【问题标题】:Traveling Salesman - 2-Opt improvement旅行推销员 - 2-Opt 改进
【发布时间】:2013-09-10 21:56:21
【问题描述】:

所以我一直在寻找关于旅行商问题的 2-opt 改进的解释,我明白了它的要点,但我不明白一件事。

我知道如果生成路径的两条边相互交叉,我可以只切换两个点,它们将不再交叉。但是 - 我不明白如何确定两条边是否交叉。

为了让我的问题更清楚,这是我到目前为止所做的:(我在 java 中做了)

  1. 我有一个名为 Point 的对象,它代表一个城市,具有 x 和 y 坐标。
  2. 我有一个PointSet,它有一组Points,包含在List 中。
  3. 我有一个 PointSet 的方法,称为 computeByNN(),它通过最近邻算法以相当短的方式排列 PointSet。

所以现在我有一个排序的 PointSet(不是最优的,但仍然很短),我想对其进行 2-opt。但是,我不知道从哪里开始。我是否应该检查每个线段以查看它们是否相交,如果相交,则切换两个点?我觉得这违背了启发式的目的,它变成了一种蛮力解决方案。有没有一种有效的方法来确定游览的两个部分是否交叉?

如果我的问题不清楚,我很抱歉。如果有人需要,我会尝试对其进行编辑以使其更清晰。

【问题讨论】:

  • 检查每条边的每一条只有O(n²)。逼近 NP 完全问题时的完全合理的运行时间(显然没有已知的多项式时间精确解)。

标签: java algorithm optimization nearest-neighbor traveling-salesman


【解决方案1】:

如果您愿意,可以创建一个查找表来检测交叉边缘。对于 n = 1000,订购 10^12 个条目显然过于奢侈。但是,您可能最担心较短的边缘?假设您的目标是为每个节点包含大约 √n 个最近邻居的边。那么你只处于兆字节空间的领域,并且无论如何都是 O(n^2) 预处理。从那里它是一个启发式,祝你好运!

还将提到这可以即时完成。

【讨论】:

  • 理想情况下,我想修复所有交叉的边缘(甚至是长边缘)。如果您看过 Concorde TSP 求解器,它能够找到所有交叉的边并替换它们。不过我不明白它是怎么做到的这么快。但是,我将通过仅检查 root(n) 邻居来尝试您的方式,看看它是如何进行的。另外,当您说可以即时完成时,您是什么意思? (我是一名高中生,对这一切真的很陌生,所以请原谅我的愚蠢问题)。
  • 即时我的意思是从一个入口表开始,如果你的图中确实出现了一对边,那么只存储它们是否交叉。抱歉,我不太了解 TSP。仅当您希望一遍又一遍地测试相同的配对时,才值得这样做。由于没有明显的快速方法来实现我的想法的 √n 部分,我建议您专注于如何检查交叉边缘。例如,如果边缘 A 的最高 y 值小于边缘 B 的最低值,则不需要执行任何其他检查。
  • 可以通过计算每个边缘在 x 和 y 维度上覆盖的阴影线段来降低时间复杂度。然后可能有一种算法可以找到在 O(n^2) 下相交的那些。然后你只测试那些可能相交的边。
  • 好的,我明白你现在在说什么,我会将你的答案设置为已接受,尽管我会尝试找到更好的方法来做到这一点。如果我发现了什么,我会发布我的问题的答案。谢谢您的帮助!这是一些令人困惑的东西......
  • 这有意义吗?对端点进行排序需要 O(n log n)。然后,您从左到右 (O(n)) 逐步遍历端点,并维护一个列表 (O(n log n)) 的边缘,您到目前为止已经看到了一个端点。当需要从这个列表中删除一条边时,它可能只能穿过列表中的那些边。并重复这是每个坐标 x, y...
猜你喜欢
  • 1970-01-01
  • 2017-06-03
  • 2013-06-09
  • 1970-01-01
  • 2011-09-08
  • 2015-04-28
  • 2017-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多