繁体   English   中英

在具有正权重的有向图中找到最短长度的环

[英]Find cycle of shortest length in a directed graph with positive weights

我在一次采访中被问到这个问题,但我想不出任何像样的解决方案。 所以,我告诉他们找到所有循环然后选择长度最短的循环的天真方法。

我很想知道什么是解决这个问题的有效方法。

您可以轻松修改Floyd-Warshall 算法 (如果您根本不熟悉图论,我建议您查看一下,例如获取《算法导论》的副本)。

传统上,您为每个i开始path[i][i] = 0 但是您可以改为从path[i][i] = INFINITY 它不会影响算法本身,因为无论如何这些零都没有用于计算(因为路径path[i][j]永远不会改变k == ik == j )。

最后, path[i][i]是经过i的最短循环的长度。 因此,您需要为所有i找到min(path[i][i]) 如果你想要循环本身(不仅是它的长度),你可以像通常使用普通路径一样完成它:通过在算法执行期间记住k

此外,您还可以使用Dijkstra 算法找到经过任何给定节点的最短周期。 如果您为每个节点运行此修改后的 Dijkstra,您将获得与 Floyd-Warshall 相同的结果。 由于每个 Dijkstra 都是O(n^2) ,因此您将获得相同的O(n^3)整体复杂度。

伪代码是对 Dijkstra 算法的简单修改。

for all u in V:
   for all v in V:
      path[u][v] = infinity

for all s in V:
   path[s][s] = 0
   H = makequeue (V) .. using pathvalues in path[s] array as keys
   while H is not empty:
      u = deletemin(H)
      for all edges (u,v) in E:
         if path[s][v] > path[s][u] + l(u, v) or path[s][s] == 0:
            path[s][v] = path[s][u] + l(u,v)
         decreaseKey(H, v)

lengthMinCycle = INT_MAX

for all v in V:
   if path[v][v] < lengthMinCycle & path[v][v] != 0 :
      lengthMinCycle = path[v][v]

if lengthMinCycle == INT_MAX:
   print(“The graph is acyclic.”)

else:
   print(“Length of minimum cycle is ”, lengthMinCycle)

时间复杂度:O(|V|^3)

  • 执行 DFS
  • 在 DFS 期间跟踪边缘的类型
  • 边的类型是Tree Edge , Back Edge , Down EdgeParent Edge
  • 当你得到一个Back Edge并有另一个计数器来获取长度时,请跟踪。

有关更多详细信息,请参阅Algorithms in C++ Part5 - Robert Sedgwick

您需要做的是为每个节点分配另一个权重,该权重始终为 1。现在使用这些权重运行从一个节点到同一节点的任何最短路径算法。 但是在考虑中间路径时,您将不得不忽略实际权重为负的路径。

当您的问题与TSP匹配时,我们还可以使用分支定界算法来解决旅行商问题。 http://lcm.csa.iisc.ernet.in/dsa/node187.html

下面是对 Floyd - Warshell 算法的简单修改。

V = 4
INF = 999999

def minimumCycleLength(graph): dist = [[0]*V for i in range(V)] for i in range(V): for j in range(V): dist[i][j] = graph[i][j]; for k in range(V): for i in range(V): for j in range(V): dist[i][j] = min(dist[i][j] ,dist[i][k]+ dist[k][j]) length = INF for i in range(V): for j in range(V): length = min(length,dist[i][j]) return length

graph = [ [INF, 1, 1,INF], [INF, INF, 1,INF], [1, INF, INF, 1], [INF, INF, INF, 1] ] length = minimumCycleLength(graph) print length

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM