图表 - 如何查找最小定向循环(最小总重量)?

时间:2012-05-04 22:29:44

标签: algorithm data-structures graph shortest-path

这是一个消费税:

  

设G是具有n个顶点和m个边的加权有向图,其中所有边都具有正权重。有向循环是一个有向路径,它在同一个顶点开始和结束,并包含至少一个边。给出O(n ^ 3)算法以找到G最小总重量的有向循环。将给出O((n ^ 2)* m)算法的部分信用。


这是我的算法。

我做DFS。每次当我找到back edge时,我知道我有一个定向循环。

然后我会暂时沿parent array向后移动(直到我遍历周期中的所有顶点)并计算total weights

然后我将此周期的total weightmin进行比较。 min始终采用最小总权重。在DFS完成后,我们也找到了最小的定向循环。


好的,然后是关于时间的复杂性。

老实说,我不知道算法的时间复杂度。

对于DFS,遍历取O(m + n)(如果m是边数,则n是顶点数)。对于每个顶点,它可能指向其祖先之一,从而形成一个循环。当找到一个循环时,需要O(n)来总结总重量。

所以我认为总时间是O(m + n * n)。但显然这是错误的,如消费中所述,最佳时间为O(n ^ 3),正常时间为O(m * n ^ 2)。


任何人都可以帮助我:

  1. 我的算法是否正确?
  2. 如果算法正确,时间复杂度是多少?
  3. 这个问题有更好的算法吗?

4 个答案:

答案 0 :(得分:20)

您可以在此处使用Floyd-Warshall算法。

Floyd-Warshall算法找到所有对顶点之间的最短路径。

该算法非常简单,遍历所有对(u,v)找到最小化dist(u,v)+dist(v,u) 的对,因为该对指示来自{{1}的循环重量为u的{​​{1}}。如果图形也允许自循环(边u),您还需要单独检查它们,因为算法不会检查这些循环(并且只有它们)。

伪代码:

dist(u,v)+dist(v,u)

(u,u)实际上是从u到v然后从v到u的路径,这是一个循环。

算法运行时间为run Floyd Warshall on the graph min <- infinity vertex <- None for each pair of vertices u,v if (dist(u,v) + dist(v,u) < min): min <- dist(u,v) + dist(v,u) pair <- (u,v) return path(u,v) + path(v,u) ,因为floyd-warshall是瓶颈,因为循环需要path(u,v) + path(v,u)时间。

我认为这里的正确性是微不足道的,但如果你不同意我,请告诉我,我会尝试更好地解释它。

答案 1 :(得分:2)

“对于每个顶点,它可能会指向其中一个祖先,从而形成一个循环”

我认为它可能会指向它的任何祖先,这意味着N

另外,当你从dfs中出来时,你将如何标记顶点,你可能会从其他顶点再次到达那里,它将成为另一个循环。所以这不再是(n + m)dfs了。

  1. 所以你的算法不完整
  2. 同样在这里
  3. 3。 在一个dfs期间,我认为顶点应该是看不见的,或者是检查,并且对于检查,你可以存储到起始顶点的路径的最小权重。因此,如果在某个其他阶段,您找到该顶点的边缘,则不必再搜索此路径。 此dfs将找到包含第一个顶点的最小定向循环。并且它是O(n ^ 2)(如果你将图形存储为列表,则为O(n + m))

    所以如果要从任何其他顶点做到它将是O(n ^ 3)(O(n *(n + m))

    抱歉,我的英语和我不擅长术语

答案 2 :(得分:2)

  

我的算法是否正确?

没有。让我举一个反例。想象一下,您从u开始DFS,从p1p2有两条路径uv以及{{1}路径p3 }}返回vup1短。

假设您首先将p2路径转到p2,然后按路径v返回u。发现了一个周期,但显然它不是最小的。然后,您可以通过p3路径继续探索u,但是自p1完全探索以来,DFS结束时没有找到最小周期。

答案 3 :(得分:0)

我做了类似的事情,但是我没有为dfs使用任何访问数组(这是我的算法正常工作所必需的),因此我意识到我的算法具有指数复杂性。

由于您正在查找所有周期,因此不可能在不到指数时间内找到所有周期,因为可能会有2 ^(e-v + 1)个周期。