我正在尝试一系列不同的算法来寻找Traveling Salesman Problem的近似最优解,其中一种方法就是蛮力方法 - 检查每条之间的可能路径n个城市,只需返回最好的城市。这是一个O(n!)算法,因此很自然地需要很长时间来执行大量城市。
我想提高我的暴力实施的效率,我注意到的一件事是你不必检查城市的每个单个排列。例如,如果您有城市1,2,3和4,则路径(1-2-3-4)与路径(2-3-4-1)的长度相同。路径(3-4-1-2)和(4-1-2-3)也是如此。通过利用这一事实,我们应该能够将蛮力算法的复杂性从O(n!)降低到O((n-1)!),甚至O((n-1)!/ 2)如果我们意识到所有路径都可以反转,而不会影响它们的长度。
基本上,我正在寻找一种能够从一组不同的整数生成circular permutations的算法。如果算法将“镜像”排列视为等效(例如1-2-3和3-2-1是相同的,因此只需要其中一个),这也是很好的。有谁知道这样做的方法? Java实现会很精彩,但我会采取任何措施!
答案 0 :(得分:4)
如果您始终使用相同的节点(例如' 1'),则不应遇到此问题。然后你也可以轻松添加镜像检查,因为它只是从节点0运行到N-1 N-2,直到你再次为零。
例如,1,2,3,4具有以下排列:
1234 1243 1324 1342 1423 1432 2134 2143 2314 2341 2413 2431
3124 3142 3214 3241 3412 3421 4123 4132 4213 4231 4312 4321
现在,如果我们强制将1作为第一个节点,那么您最终会得到这些独特的解决方案:
1234 1243 1324 1342 1423 1432
接下来我们可以消除镜像'解决方案:
normal => reverse => rotated by 1
1234 => 4321 => 1432
1243 => 3421 => 1342
1324 => 4231 => 1423
您只需要查看:
1234 1243 1324
<强>更新强>
生成此序列的最简单方法是枚举1 ... N-1的所有可能性,其中1在2之前(强制方向)并附加N.
例如,对于N = 4,我们首先生成所有排列1 ... N-1:
123 132 213 231 312 321
现在我们在2之前过滤1:
123 132 312
追加N(4):
1234 1324 3124
这可能更容易,也更有效。这也证明了暴力TSP所需的上限是:(N - 1)! / 2
答案 1 :(得分:0)