Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 贝尔曼福特的负周期_Algorithm_Graph Theory_Shortest Path_Bellman Ford - Fatal编程技术网

Algorithm 贝尔曼福特的负周期

Algorithm 贝尔曼福特的负周期,algorithm,graph-theory,shortest-path,bellman-ford,Algorithm,Graph Theory,Shortest Path,Bellman Ford,在具有V节点和E边的有向图中,Bellman-Ford算法将每个顶点(或者更确切地说,每个顶点的边)松弛(V-1)次。这是因为从源到任何其他节点的最短路径最多包含(V-1)条边。在第V次迭代中,如果边可以松弛,则表示存在负循环 现在,我需要找到被这个负循环“摧毁”的其他节点。也就是说,由于从源到位于负循环中的节点的路径上有一个或多个节点,因此一些不在负循环中的节点现在与源的距离为负无穷远 实现这一点的一种方法是运行Bellman Ford并注意负循环上的节点。然后,从这些节点运行DFS/BFS以

在具有V节点和E边的有向图中,Bellman-Ford算法将每个顶点(或者更确切地说,每个顶点的边)松弛(V-1)次。这是因为从源到任何其他节点的最短路径最多包含(V-1)条边。在第V次迭代中,如果边可以松弛,则表示存在负循环

现在,我需要找到被这个负循环“摧毁”的其他节点。也就是说,由于从源到位于负循环中的节点的路径上有一个或多个节点,因此一些不在负循环中的节点现在与源的距离为负无穷远

实现这一点的一种方法是运行Bellman Ford并注意负循环上的节点。然后,从这些节点运行DFS/BFS以标记其他节点

然而,为什么我们不能运行Bellman Ford 2*(V-1)次来检测这样的节点,而不用DFS/BFS呢?如果我的理解是正确的,放松所有顶点2*(V-1)次应该允许负循环将其值“传播”到所有其他连接的节点

其他详细信息:我在解决此在线问题时遇到这种情况:

我使用的Java代码(以及此处未显示的BFS/DFS)如下所示:

  // Relax all vertices n - 1 times.
  // And relax one more time to find negative cycles
  for (int vv = 1; vv <= n; vv++) {
    // Relax each vertex
    for (int v = 0; v < n; v++) {
      // For each edge
      if (distTo[v] != (int) 1e9) {
        for (int i = 0; i < adjList[v].size(); i++) {
          int dest = adjList[v].get(i).fst;
          int wt = adjList[v].get(i).snd;

          if (distTo[v] + wt < distTo[dest]) {
            distTo[dest] = distTo[v] + wt;

            if (vv == n) {
              isInfinite[v] = true;
              isInfinite[dest] = true;
            }
          }
        }
      }
    }
  }
//将所有顶点松弛n-1次。
//再放松一次,寻找负面循环

对于(int vv=1;vv,在经典情况下,“在”负长度循环上的所有节点到源都有任意小的距离。 因此,在第v-1次迭代之后的每次迭代中,从源到这些节点的路径都会变小。 该任务要求您为所有此类节点返回无穷大


您可以使用Bellman Ford算法的修改版本来标记所有此类节点的距离,例如-infinity,并运行它v-1次,以将-infinity传播到连接到该循环的所有其他节点。但是,与仅从循环上的节点运行DFS或BFS相比,这需要大量额外的时间。

在经典情况下,所有节点“开启”负长度循环与源之间有任意小距离。 因此,在第v-1次迭代之后的每次迭代中,从源到这些节点的路径都会变小。 该任务要求您为所有此类节点返回无穷大


您可以使用Bellman Ford算法的修改版本来标记所有此类节点的距离,例如-infinity,并运行它v-1次,以将-infinity传播到连接到该循环的所有其他节点。但是与仅从循环上的节点运行DFS或BFS相比,这需要大量额外的时间。

考虑一个
N=4,M=5的图

A -> B weight 1000
A -> C weight 1000
C -> D weight -1
D -> C weight -1
D -> B weight 1000
让A作为我们的来源,B作为目的地

现在显然存在一个负循环
(cd)
。但是,无论我们运行算法N次、2N次甚至3N次,从a到B的最短路径仍然是1000。因为每次使用负循环时,它只会减少一小部分距离,所以它不会像我们期望的那样传播到其他节点

一种解决方案是,一旦识别出影响节点的循环,就将距离标记为负无穷大。这样,负循环在通过其他节点的其他最短路径上“优先”

您诚挚的,

一位在这个问题上花费了大量时间的程序员。

考虑一个
N=4,M=5的图:

A -> B weight 1000
A -> C weight 1000
C -> D weight -1
D -> C weight -1
D -> B weight 1000
让A作为我们的来源,B作为目的地

现在显然存在一个负循环
(cd)
。但是,无论我们运行算法N次、2N次甚至3N次,从a到B的最短路径仍然是1000。因为每次使用负循环时,它只会减少一小部分距离,所以它不会像我们期望的那样传播到其他节点

一种解决方案是,一旦识别出影响节点的循环,就将距离标记为负无穷大。这样,负循环在通过其他节点的其他最短路径上“优先”

您诚挚的,
一位在这个问题上花了很多时间的程序员