【问题标题】:find an algorithm that calculates the transitive closure of a directed graph using O(n 4 ) time找到一种算法,使用 O(n 4 ) 时间计算有向图的传递闭包
【发布时间】:2012-11-26 23:39:16
【问题描述】:

对于一个作业,我被要求找到一种算法,该算法使用 O(n 4 ) 时间计算有向图的传递闭包。我们已经了解了 floyd warshall 算法,它要好得多,所以有人可以帮我创建一个在 O(n4) 时间内运行的算法吗?有这样的算法吗?

我知道这似乎是一个愚蠢的问题。我真的不明白为什么我们被要求找到更慢的方法来做到这一点。

【问题讨论】:

  • 为图定义传递闭包。你是说Q = { (u,v) | (u,v) is an edge OR there is w such that (u,w),(w,v) is in Q } 吗?
  • T^(k)=t^(k)_ij 是一个 n × n 位矩阵,其中 t^(k)_ij = 1 如果存在从 i 到 j 的路径,其中中间顶点来自 {1, 2, . . . , k};否则,t^(k)_ij = 0. 是我使用的。
  • 等一下,你是否试图真正实现一组三元组(i,j,k),其中(i,j,k)T 中当且仅当从 i 到 j 存在任何路径(可能不是最短的)长度为 k?这是一个与我最初想的不同的问题,你不关心路径的长度 - 只关心它的存在。如果是这样 - 问题可以从哈密顿路径问题中减少,并且没有已知的多项式解决方案。你能澄清一下吗?
  • 我正在寻找以下解决方案。不寻找一组三元组
  • 我只是想我会注意到您缺少大写和标点符号是一种关闭。您是一个解决难题的聪明人,请帮自己一个忙,不要让自己暴露在语言选择所带来的刻板印象中。

标签: algorithm time-complexity floyd-warshall


【解决方案1】:

Floyd Warshall 是O(n^3),因为O(n^3)O(n^4) 的子集,所以它也是O(n^4)
因此,通过设置一个新图 G'=(V,E',w') 其中 E' = V x V (集团,完整图)和 w'(u,v) = 1 if (u,v) is in E, otherwise INFINITY - 通过使用 Floyd-Warshall 算法,每对 (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),我们只需要证明它确实找到了传递闭包。

通过归纳:

  1. 对于长度为 1 的从 u 到 v 的最短路径,它是基本子句, 因为 (u,v) 在 E 中。
  2. 对于每个k
    每对 (u,v) 的最短路径长度为 k&gt;1 - 有 w ,因此有一条路径 u -&gt; ... -&gt; w 和一条边 (w,v)。根据归纳假设,在之前的迭代中,我们将(u,w) 添加到Q,因此条件将产生真,我们会将(u,v) 添加到结果集Q

类似地表明,如果将某些对 (u,v) 添加到 Q 中,则存在路径 u-&gt;..-&gt;w-&gt;v,因此它被正确添加。


第二个Theta(n^4) 解决方案:

如上所述设置G',并为V 中的每个顶点vv 运行Bellman Ford。
BF的每次运行是Theta(n^3)1,运行它n次是Theta(n^4)


(1) 技术上它是O(VE),但对于非稀疏图ETheta(V^2)

【讨论】:

    【解决方案2】:

    传递闭包的 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)中。

    不幸的是,可能无法(轻松地)证明外循环具有该属性,因为它是特定于数据的。

    【讨论】:

      猜你喜欢
      • 2014-04-30
      • 1970-01-01
      • 2015-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-29
      相关资源
      最近更新 更多