对于一项任务我被要求找到一个算法,该算法使用O(n 4)时间计算有向图的传递闭包。我们已经了解了floyd warshall算法,这个算法好多了,所以有人可以帮我创建一个在O(n4)时间内运行的算法吗?有这样的算法吗?
我知道这个问题似乎很愚蠢。我真的不明白为什么我们被要求找到更慢的方法来做到这一点。
答案 0 :(得分:4)
Floyd Warshall为O(n^3)
,由于O(n^3)
是O(n^4)
的子集,因此它也是O(n^4)
。
因此,通过使用Floyd-Warshall算法设置新图G'=(V,E',w')
其中E' = V x V
(clique,完整图)和w'(u,v) = 1 if (u,v) is in E, otherwise INFINITY
,每对(u,v)
最终得到一个小于无穷大的值就在闭合中。
Theta(n ^ 4)解决方案:
Q <- E (init) #(Q is a set)
for i from 1 to n:
for each v in V:
for each w in V:
for each u in V:
if (v,w) is in Q and (w,u) is in E:
Q <- Q U {(v,u)} #add (v,u) to Q
复杂性很简单Theta(n^4)
,我们只需要证明它确实找到了传递闭包。
通过归纳:
k
:
(u,v)
的最短路径为k>1
- w
有一条路径u -> ... -> w
和一条边(w,v)
。从归纳假设开始,在之前的迭代中我们将(u,w)
添加到Q
,因此条件将生成true,我们会将(u,v)
添加到结果集Q
。类似地显示,如果某个对(u,v)
被添加到Q中,则会有一条路径u->..->w->v
,因此它被合理地添加。
第二个Theta(n^4)
解决方案:
如上所述设置G'
,并v
中的每个顶点V
从v
运行Bellman Ford。
每次运行BF都是Theta(n^3)
1 ,运行n
次Theta(n^4)
(1)从技术上讲,它是O(VE)
,但是没有稀疏图E
位于Theta(V^2)
答案 1 :(得分:1)
用于传递闭包的Floyd-Warshall算法如下:
int dist[N][N]; // For some N
int i, j, k;
// Input data into dist, where dist[i][j] is the distance from i to j.
// If the nodes are unconnected, dist[i][j] should be infinity
for ( k = 0; k < N; k++ )
for ( i = 0; i < N; i++ )
for ( j = 0; j < N; j++ )
if(dist[i][k] && dist[k][j])
dist[i][j] = 1;
请注意所使用的索引的顺序:它们以这种方式排序以保留最佳子结构属性。如果我们改为对它们进行重新排序,则会违反该属性:
for ( i = 0; i < N; i++ )
for ( j = 0; j < N; j++ )
for ( k = 0; k < N; k++ )
if(dist[i][j] && dist[j][k])
dist[i][k]=1;
违反该属性的结果是传递闭包路径(在最坏的情况下)仅在上面的O(n ^ 3)次迭代中增长一个链路。为了确保它们的传递闭包路径一直在增长,我们需要不断迭代直到它们停止增长:
do{
something_done=false;
for ( i = 0; i < N; i++ )
for ( j = 0; j < N; j++ )
for ( k = 0; k < N; k++ )
if(dist[i][j] && dist[j][k]){
dist[i][k]=1;
something_done=true;
}
} while (something_done);
如果外环在O(N)中,则算法本身在O(N ^ 4)中。
不幸的是,可能无法(轻松地)显示外部循环具有该属性,因为它特定于数据。