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

时间:2010-10-12 04:10:49

标签: algorithm graph dijkstra

我在接受采访时被问到这个问题,但我无法提出任何体面的解决方案。所以,我告诉他们找到所有周期然后选择长度最短的周期的天真方法。

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

6 个答案:

答案 0 :(得分:27)

您可以轻松修改Floyd-Warshall algorithm。 (如果您根本不熟悉图论,我建议您查看它,例如获取Introduction to Algorithms的副本。

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

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

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

答案 1 :(得分:6)

伪代码是对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)

答案 2 :(得分:0)

  • 执行DFS
  • 在DFS期间保持边缘类型的跟踪
  • 边缘类型为Tree EdgeBack EdgeDown EdgeParent Edge
  • 在获得Back Edge时跟踪并有另一个获取长度的计数器。

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

下面是对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

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div> <div class="side-bar"> <ul> <li id="home">Home</li> <li id="services">Services</li> <li id="portfolio">Portfolio</li> <li id="clients">Clients</li> <li id="contact">Contacts</li> </ul> </div> <div class="img-sec"> <div class="change-img"></div> </div> </div>