旅行售货员问题中的方向限制

27

我正在尝试按照路径顺序对一组三维坐标进行排序。一个示例:

points = np.array([[ 0.81127451,  0.22794118,  0.52009804],
                   [ 0.62986425,  0.4546003 ,  0.12971342],
                   [ 0.50666667,  0.41137255,  0.65215686],
                   [ 0.79526144,  0.58186275,  0.04738562],
                   [ 0.55163399,  0.49803922,  0.24117647],
                   [ 0.47385621,  0.64084967,  0.10653595]])

这些点是随机排列的,但总会有一条路径穿过它们。我正在使用LKH求解器(Helsgaun 2009)寻找适应性旅行商问题(TSP)的路线。它包括两个修改:

  • 在原点附近添加一个点。这在我处理的每个实例中都能找到最佳起点。这是我的想法,我没有其他依据。
  • 在每个点上添加一个距离为零的点。这使得求解器能够找到路径的另一端。这个想法来自于这个 SO 问题

请注意,TSP不涉及位置,只涉及节点之间的距离。因此,求解器并不知道(或在意)我正在使用三维空间。我只需像这样制作距离矩阵:

import numpy as np
from scipy.spatial.distance import pdist, squareform

# Add a point near the origin.
points = np.vstack([[[0.25, 0, 0.5]], points])
dists = squareform(pdist(points, 'euclidean'))

# Normalize to int16s because the solver likes it.
d = 32767 * dists / np.sqrt(3)
d = d.astype(np.int16)

# Add a point that is zero units from every other point.
row, col = d.shape
d = np.insert(d, row, 0, axis=0)
d = np.insert(d, col, 0, axis=1)

我将这个问题提交给我的pytsp分支,然后将其传递给LKH求解器。一切都很好......除了路径交叉的情况。TSP解决方案不能有闭合环,所以我总是得到右边显示的开放环路:

旅行商路径

请注意,这是我情况的类似2D版本。还要注意,这些点没有完全对齐,即使沿着“直线”部分也是如此。

因此,我的问题是:如何帮助求解器尽可能地保留路径的方向?我有两个不成熟的想法,但迄今为止未能实现任何东西:

  • 使用另一种度量而不是L2。但我认为这行不通,因为在给定的交点处,'错误'点本质上并没有什么不同。它的错误取决于前一个点。而我们还不知道哪个是前一个点(这就是我们试图弄清楚的)。所以我认为这不好。
  • 评估每组三个点的局部共线性(例如使用每个三元组的行列式)。通过此共线性系数调节本地“三维坡度”(不确定我的意思是什么)。为每个点提供另一个表示此本地对齐的维度。现在,范数将反映局部对齐,(希望)大致共线的事物将连接起来。

我已经将这些文件放在Dropbox上:

谢谢您的阅读;任何想法都会受到赞赏。

参考文献

K. Helsgaun, Lin-Kernighan TSP启发式算法的通用k-opt子移动。Mathematical Programming Computation, 2009, doi: 10.1007/s12532-009-0004-6.


3
如果您有一个特定的问题需要解决,并且可以负担一些迭代式的定制“干预”,那么您可以运行代码一次,确定路径中应该是相邻的点,在“dists”数组中手动重置它们之间的距离以使它们看起来更接近,重新运行算法,确定任何其他应该是相邻的点等等。当然,如果您将反复解决不同实例的问题,并且需要一个“只需工作”而无需额外干预的求解器,那么这个想法对您没有帮助。 - Warren Weckesser
感谢 @WarrenWeckesser 的建议。我尝试使用 BallTree 来获取局部密度,它确实突出了这些问题区域。理论上,我可以尝试在密集区域重新调整连接关系。但是,是的 - 我仍然希望能找到一种技巧来避免这种事后临时解决的情况。暂时而言,这是我的备选方案。干杯! - Matt Hall
3
这似乎不是一个旅行商问题。你有一个隐含的目标函数,与路径长度不同。也许你可以先将你的目标函数明确化。例如,总长度+所有方向变化幅度之和。计算一个方向变化需要使用连续的三个点(这就是我说它不像TSP的原因)。一旦你澄清了你的目标函数,你可以使用一种通用的启发式算法,如进化算法。 - John Coleman
@JohnColeman 感谢您的建议。我同意这似乎距离TSP太远,继续沿着那条路走下去。我以前从未像您描述的那样解决过问题;如果您能给我指出一个简单的例子,我将不胜感激。同时,我会开始使用Google。向前迈进! - Matt Hall
没时间给出完整的答案,但是搜索“点云曲线重建”这个主题会发现丰富的文献资料。我甚至找到了一个基于TSP的文献 - ojdo
显示剩余2条评论
2个回答

1
根据pytsp的文档,距离矩阵不必对称。这意味着您可以修改L2范数以将有关首选方向的信息合并到该矩阵中。假设您有一些点对(i,j)的首选方向,则对于每个这些点,您可以将除以<(1+a)>,并将乘以<(1+a)>,以使该方向更有利。这意味着,如果您的算法肯定会找到全局最优解,则可以通过取足够大的来强制满足您的首选方向。
此外,我不确定在从3D数据获取距离矩阵的解决方案中是否不可能存在闭环。我认为“无闭环”是特定于2D的(三角不等式)结果。

谢谢你的答案。我认为你对于三维空间中三角不等式的观察非常准确 - 实际上,路径并没有完全交叉。至于不对称距离矩阵...我也没有想过。我需要尝试一下,看看它是否有帮助���棘手的问题是我无法预先知道我想要遍历图形的哪个部分。干杯! - Matt Hall

0
也许,如果您包含一个机制来控制方向动量,偏好于沿着现有轨迹的节点,那么这可能会使成本函数优化您想要实现的目标。我认为这可以很好地表述为一个局部搜索问题,并使用模拟退火等元启发式算法来解决。
以这种方式解决问题的优点是,在计算两个节点之间的距离时,可以考虑整个解决方案的状态。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接