Home Articles

求解具有最小误差的非线性方程组

Asked
Viewed 1403 times
1

我有一些非线性优化问题(最好在python中解决):

给定在2D平面中的3个圆(中心x1..3,y1..3,半径d1..3) .

(x-x1)^2 + (y-y1)^2 - r1^2 = 0
(x-x2)^2 + (y-y2)^2 - r2^2 = 0
(x-x3)^2 + (y-y3)^2 - r3^2 = 0

公共点(x / y)是期望的,并且在这种情况下可以通过fsolve(scipy.optimize)来计算 . But how does one solve the problem if the radii r1..3 are with an uncertainness of u1..3 ,分别?即圆的真实半径在区间r-u ... r u .

如何找到包含半径不确定性的最佳点(x / y)?

2 Answers

  • 1

    我试试这种方式 . 对于给定点p,我计算从该点到三个圆中的每一个的距离 . 这可以通过获取(1)圆与圆的原点之间的距离和(2)圆的半径之间的差的绝对值来完成 . 然后你的目标函数是最小化三个距离的总和(p到circleA,p到圆圈B,p到圆圈C) . 我会尝试算术和,但可能有一些很好的理由进行不同的聚合(ensamble平均数学类型) . 然后,您使用非线性包来最小化目标函数(即三个距离的总和) .

    现在你有每个圆圈的重量 . 因此,您修改目标函数以通过每个圆的不确定性来折扣距离 . 同样,你需要一些逻辑来完成这个权重...天真的方法是使用“加权平均”,即每个距离的权重为1 / sigma ^ 2 . 所以你的目标功能变成了

    (weighted average distance) 
    = ( distA * sigmaA^-2 + distB * sigmaB^-2 + distC * sigmaC^-2 ) 
       / ( sigmaA^-2 + sigmaB^-2 + sigmaC^-2)
    

    其中distX是从点到圆的距离,sigmaA是圆的位置的标准偏差(由于cicle位置和大小的不确定性), ^-2 表示正方形然后除 .

    使用nonlin包来最小化上述obj . 通过改变点的x和y来起作用 .

  • 0

    考虑到这里的解密,这实际上并不那么难:http://mathworld.wolfram.com/Circle-CircleIntersection.html

    提出的算法:

    • 查找x - 如链接中所述 .

    • 计算y .

    两者都应该使用任何2个圆圈完成 .

    • 将点(x,y)和(x,-y)插入3圈 .

    • 解决方案是所有三个圆相交:x,y x,-y或根本不相交 .

    另一个建议......我再次读到你的问题,并意识到你并不是想找到自己的观点......

    但是,如果您在纸张上绘制所有9个圆圈(3个相交,加上2个越来越大的r e和r-e,其中e是错误),您会注意到以下情况 . 您的交叉点位于多边形内 . 您可以轻松计算此多边形的顶点 . 然后你的问题就变成了:在多边形中找到一个点 . 或者您编写一个找到这些顶点的异议函数,然后最小化该区域 .

    要了解我对圈子的意思,请运行:

    # excuse me for the ugly code ...
    import pylab
    pylab.axes()
    
    cir = pylab.Circle((1,0), radius=1, alpha =.2, fc='b')
    cir1 = pylab.Circle((1,0), radius=0.9, alpha =.2, fc='b')
    cir2 = pylab.Circle((1,0), radius=1.1, alpha =.2, fc='b')
    cir3 = pylab.Circle((-1,0), radius=1, alpha =.2, fc='b')
    cir4 = pylab.Circle((-1,0), radius=0.9, alpha =.2, fc='b')
    cir5 = pylab.Circle((-1,0), radius=1.1, alpha =.2, fc='b')
    cir6 = pylab.Circle((0,-1), radius=0.9, alpha =.2, fc='b')
    cir7 = pylab.Circle((0,-1), radius=1.1, alpha =.2, fc='b')
    cir8 = pylab.Circle((0,-1), radius=1, alpha =.2, fc='b')
    pylab.gca().add_patch(cir)
    pylab.gca().add_patch(cir1)
    pylab.gca().add_patch(cir2)
    pylab.gca().add_patch(cir3)
    pylab.gca().add_patch(cir4)
    pylab.gca().add_patch(cir5)
    pylab.gca().add_patch(cir6)
    pylab.gca().add_patch(cir7)
    pylab.gca().add_patch(cir8)
    
    pylab.axis('scaled')
    pylab.show()
    

Related