Python 通过有序圆形航路点的最短路径

Python 通过有序圆形航路点的最短路径,python,optimization,geometry,shortest-path,Python,Optimization,Geometry,Shortest Path,我试图实现一种算法,该算法通过二维平面上的路径点有序列表计算从当前位置到目标的最短路径及其相关距离。航路点由其中心坐标(x,y)及其半径r定义。最短路径必须至少与每个航路点周长相交一次。这与其他路径优化问题不同,因为我已经知道必须跨越路径点的顺序 在这种情况下,连续的航路点是不同的,并且没有对齐,这可以使用连续的角度平分来解决。棘手的情况是: 这是我的Python实现的一个精简版本,它不处理对齐的航路点,并且处理非常同心的连续航路点。我修改它是因为它通常使用纬度和经度,而不是欧几里得空间

我试图实现一种算法,该算法通过二维平面上的路径点有序列表计算从当前位置到目标的最短路径及其相关距离。航路点由其中心坐标(x,y)及其半径r定义。最短路径必须至少与每个航路点周长相交一次。这与其他路径优化问题不同,因为我已经知道必须跨越路径点的顺序

在这种情况下,连续的航路点是不同的,并且没有对齐,这可以使用连续的角度平分来解决。棘手的情况是:

这是我的Python实现的一个精简版本,它不处理对齐的航路点,并且处理非常同心的连续航路点。我修改它是因为它通常使用纬度和经度,而不是欧几里得空间中的点

def优化(位置、航路点):
#当前位置在最短路径上,累积距离从零开始
最短路径=[position.center]
优化距离=0
#如果只剩下一个航路点,沿直线前进
如果len(航路点)==1:
最短路径。追加(航路点[-1]。中心)
优化的_距离+=距离(位置。中心,航路点[-1]。中心)
其他:
考虑最后一个优化点(一个)和下两个路径点(两个,三个)
两个,三个压缩(航路点[:],航路点[1:]):
一个=快速航路点[-1]
in_heading=获取_heading(2.center,1.center)
in_距离=距离(一个中心,两个中心)
向外距离=距离(2.中心,3.中心)
#接下来的两个航路点是同心的
如果out_距离==0:
下一个目标,nb\U同心=查找下一个非同心(两个,航路点)
out\u heading=get\u heading(两个中心,下一个目标,中心)
角度=向外航向-向内航向
支腿距离=两个半径
航向=内航向+(0.5/nb\U同心)*角度
其他:
外航向=外航向(2.center,3.center)
角度=向外航向-向内航向
航向=内航向+0.5*角
支腿距离=(2*英寸距离*英寸距离*英寸距离*数学弧度(角度*0.5))/(英寸距离+英寸距离)
最佳支腿距离=最小(支腿距离,2.半径)
下一个最佳=获取偏移(两个中心,航向,最小航程)
最短路径追加(次最佳中心)
优化的距离+=距离(一个中心,下一个最佳中心)
返回优化的\u距离、最短的\u路径
我可以看到如何测试不同的角落案例,但我认为这种方法不好,因为可能还有其他我没有想到的角落案例。另一种方法是离散航路点周长,并应用最短路径算法,如a*,但这将是非常低效的


所以我的问题是:有没有更简洁的方法来解决这个问题?我会这样做:

  • 对于按顺序排列的每个圆,拾取圆周上的任意点,并通过这些点布置路径
  • 对于每个圆,沿圆周沿使总路径长度变小的方向移动点
  • 重复2。直到无法进一步改进为止

  • 为了记录在案,我使用拟牛顿方法实现了一个解决方案,并对其进行了描述。主要工作总结如下

    import numpy as np
    from scipy.optimize import minimize
    
    # objective function definition
    def tasklen(θ, x, y, r):
        x_proj = x + r*np.sin(θ)
        y_proj = y + r*np.cos(θ)
    
        dists = np.sqrt(np.power(np.diff(x_proj), 2) + np.power(np.diff(y_proj), 2))
    
        return dists.sum()
    
    # center coordinates and radii of turnpoints
    X = np.array([0, 5, 0, 7, 12, 12]).astype(float)
    Y = np.array([0, 0, 4, 7, 0, 5]).astype(float)
    R = np.array([0, 2, 1, 2, 1, 0]).astype(float)
    
    # first initialization vector is an array of zeros
    init_vector = np.zeros(R.shape).astype(float)
    
    # using scipy's solvers to minimize the objective function
    result = minimize(tasklen, init_vector, args=(X, Y, R), tol=10e-5)