【问题标题】:Can you help explain this Held-Karp TSP Pseudocode?你能帮忙解释一下这个 Held-Karp TSP 伪代码吗?
【发布时间】:2021-12-22 09:48:30
【问题描述】:

我正在尝试按照以下伪代码实现旅行商问题的 Held-Karp 算法:

(我在这里找到:https://en.wikipedia.org/wiki/Held%E2%80%93Karp_algorithm#Example.5B4.5D

我可以手动完成算法,但在代码中实际实现它时遇到了麻烦。如果有人能提供一个易于理解的解释,那就太好了。


这个我也不明白:

我以为这部分是为了设置从起始城市到连接城市的距离。如果是这样,那不是C({1}, k) := d1,k而不是C({k}, k) := d1,k吗?我只是完全误解了这一点吗?

我还听说这个算法在大约 15-20 个城市之后表现不佳,所以对于大约 40 个城市,有什么好的替代方案?

【问题讨论】:

  • 40 个城市在宏伟计划中并不多,但您必须决定如何在运行时间的可预测性与解决方案质量之间进行权衡。
  • @DavidEisenstat 嗯好的,很高兴知道。你会说 Held-Karp 是否适用于 40 个城市?
  • 不,这不是一个好选择。我可能会达到那个规模的混合整数程序,但如果你需要保证运行时间,2-opt 或其他本地搜索算法。

标签: algorithm pseudocode traveling-salesman


【解决方案1】:

Held-Karp 是一种dynamic programming 方法。

在动态编程中,您将任务分解为子任务,并使用“动态函数”使用较小子任务的已计算结果来解决较大的子任务,直到最终解决您的任务。

要了解 DP 算法,必须了解它如何定义子任务和动态函数。

在 Held-Karp 的情况下,子任务如下:

对于给定的一组顶点S 和一个顶点k1 ∉ S, k ∈ S

C(S,k) 是从顶点1 开始,遍历S 中的所有顶点并以顶点k 结束的路径的最小长度。

鉴于这个子任务定义,很清楚为什么初始化是:

C({k}, k) := d(1,k)

1k 的路径的最小长度,穿过{k},只是从1k 的边。


接下来是“动态函数”。

附带说明,DP 算法可以写成top-down or bottom-up。此伪代码是自下而上的,这意味着它首先计算较小的任务,然后将其结果用于较大的任务。更具体地说,它以集合S 的大小递增的顺序计算任务,从|S|=1 开始直到|S| = n-1(即S 包含除1 之外的所有顶点)。

现在,考虑一个由S, k 定义的任务。请记住,它对应于从1,到S,以k 结尾的路径。

我们把它分解成:

  • 1 开始的路径,通过S 中的所有顶点,除了k (S\k),它以顶点m 结束 (m ∈ S, m ≠ k):C(S\k, m)
  • mk 的边

很容易看出,如果我们像这样查看所有可能的方法来破坏C(S,k),并找到它们之间的最小路径,我们将得到C(S, k)的答案。


最后,在计算出所有C(S, k)|S| = n-1 之后,我们检查所有这些,完成从k1 的缺少边的循环:d(1,k)。最小循环就是最终结果。


关于:

我还听说这个算法在大约 15-20 个城市之后表现不佳,所以对于大约 40 个城市,有什么好的替代方案?

Held-Karp 的算法复杂度为 θ(n²2n)。 40² * 240 ≈ 1.75 * 1015 我想说,在合理的时间内在单台机器上计算是不可行的。

正如 David Eisenstat 所建议的那样,有一些使用 mixed integer programming 的方法可以在 N=40 时足够快地解决这个问题。

例如,请参阅this blog post 和基于它的this project

【讨论】:

  • 求解一个混合整数程序将为您提供最佳解决方案,对于 40 个城市来说可能相当快,除非发生了一些奇怪的事情。但不能保证。
  • @DavidEisenstat,您能否提供一个链接来支持该声明?我知道可以将 TSP 描述为整数规划问题,但我不确定解决此类问题是否会比基于 DP 的专用算法更快。
  • @DavidEisenstat,谢谢。我发现this project 使用您的链接作为来源。对于 N=48 和 N=50 的精确和近似解决方案有基准,所以我认为这证明了这些方法在实践中可以更快。
  • @Aivean 只是为了澄清一下,我认为它应该是 C({1}, k) := d(1,k) 而不是 C({k}, k) 是否正确:= d1,k 在伪代码中?但是感谢您对 Held-Karp 的精彩解释,这将有很大帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 2021-04-22
  • 1970-01-01
  • 2018-11-03
相关资源
最近更新 更多