如何在C ++中用动态实现TSP

时间:2014-06-16 22:04:46

标签: c++ algorithm dynamic-programming traveling-salesman

最近我问question on Stack Overflow寻求帮助来解决问题。这是一个旅行商问题,我有多达40,000个城市,但我只需要访问其中的15个城市。

我被指向使用具有优先级队列的Dijkstra为我需要访问的15个城市建立连接矩阵,然后使用DP在该矩阵上执行TSP。我之前只用过Dijkstra和O(n ^ 2)。在试图弄清楚如何实现Dijkstra之后,我终于做到了(足够优化从40,000个城市的240秒到0.6)。但现在我被困在TSP部分。

以下是我用于学习TSP的材料:

我对算法有所了解(但并不完全),但我遇到了麻烦。在此之前,我已经使用dp [int]或dp [int] [int]的数组进行了动态编程。但是现在当我的dp矩阵必须是dp [subset] [int]时,我不知道该怎么做。

我的问题是:

  • 如何使用动态编程处理子集? (在C ++中的一个例子将不胜感激)
  • 我链接的算法是否允许多次访问城市,如果不是,我应该更改哪些?
  • 我应该使用其他TSP算法吗? (我注意到有几种方法可以做到这一点)。请记住,我必须得到确切的值,而不是近似值。

编辑:

经过一些研究后,我偶然发现了斯坦福大学的一些竞争性编程竞赛讲座,并设法找到了TSP here(幻灯片26-30)。关键是将子集表示为位掩码。这仍然让我的其他问题无法回答。

可以对该算法进行任何更改,以允许多次访问某个城市。如果可以做到,那些变化是什么?否则,我该怎么办?

3 个答案:

答案 0 :(得分:2)

我认为您可以使用动态解决方案,并为每对节点添加最短路径的第二条边。另请参阅此问题:Variation of TSP which visits multiple cities

答案 1 :(得分:0)

以下是TSP implementation,您可以在帖子中找到已实施问题的链接。

您关联的算法不允许多次访问城市。

对于你的第三个问题,我认为Phpdna答案很好。

答案 2 :(得分:-1)

可以不止一次访问城市吗?是的,不是。在第一步中,您将问题减少到15个相关城市。这导致完整的图形,即每个节点连接到每个其他节点的图形。两个这样的节点之间的连接可能涉及原始地图上的多个城市,包括一些相关的城市,但这在第二步中与您的算法无关。

是否使用不同的算法,我可能会在图表中进行深度优先搜索。使用最小生成树,您可以为剩余的城市提供上限和下限,并使用它来选择有前景的解决方案并丢弃无望的解决方案(也称为修剪)。还有一些关于这个主题的研究,只是搜索网络。例如,如果地图实际上是骰子(即旅行成本是飞机上两点之间的距离),您可以利用此信息来改进算法。

最后,如果您真的打算增加访问过的城市数量,您会发现计算它的时间大大增加,因此您将不得不放弃对完全解决方案的要求。