【问题标题】:Finding shortest circuit in a graph that visits X nodes at least once在至少访问一次 X 节点的图中找到最短电路
【发布时间】:2014-06-10 15:06:49
【问题描述】:

尽管我还是个初学者,但我喜欢解决与图相关的问题(最短路径、搜索等)。最近遇到这样一个问题:

给定一个具有 N 个节点和 E 条边的无向加权(无负值)图(两个节点之间最多有 1 条边,一条边只能放在两个不同的节点之间)和一个 X 节点列表你必须访问,找到从节点0开始的最短路径,访问所有X节点并返回节点0。总是至少有一条路径连接任意两个节点。

限制为 1

这是一个例子:

红色节点 ( 0 ) 应该是路径的起点和终点。您必须访问所有蓝色节点 (1,2,3,4) 并返回。这里的最短路径是:

0 -> 3 -> 4 -> 3 -> 2 -> 1 -> 0 总成本为 30

我曾想过使用 Dijkstra 找到所有 X(蓝色)节点之间的最短路径,然后贪婪地选择最近的未访问 X(蓝色)节点,但它不起作用(在纸上提出 32 而不是 30 )。另外我后来注意到,仅找到所有 X 节点对之间的最短路径将花费 O(X*N^2) 时间,这对于这么多节点来说太大了。

我唯一能找到的电路是欧拉电路,它只允许访问每个节点一次(我不需要那个)。这可以用 Dijkstra 解决还是有其他算法可以解决这个问题?

【问题讨论】:

  • 您需要一个准确的答案,还是一个近似的答案适合您?
  • @templatetypedef 我需要最短电路的确切成本。
  • 这肯定是 NP-hard 因为 TSP 可以减少到它,所以你的图最好小
  • 您需要计算蓝色节点之间的最短路径,然后您将得到完全是 NP 完全的旅行推销员问题。 Wiki 应该会帮助您为此选择最佳解决方案。

标签: c++ algorithm graph shortest-path


【解决方案1】:

这是一个可能足够快的解决方案:
1)从每个蓝色节点运行最短路径搜索算法(这可以在 O(X * (E log N)) 中完成)以计算成对距离。
2)构建一个只有零顶点和蓝色顶点(X + 1 个顶点)的新图。使用第一步计算的成对距离添加边。
3)新图足够小,可以使用TSP的动态规划解决方案(它具有O(X^2 * 2^X)时间复杂度)。

【讨论】:

  • 如何在 O(X * (E log N))) 中执行第一步?使用 Dijkstra,我的代码在大约 240 秒内完成,N = 36786 / X = 15 / E = 40493
  • 您可以将 Djikstra 与优先队列一起使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多