在Dijkstra算法中放松边缘

时间:2012-10-08 13:08:40

标签: algorithm graph-theory graph-algorithm

relaxation of an edge 在图论的背景下意味着什么?我在研究Dijkstra的单源最短路径算法时遇到了这个问题。

6 个答案:

答案 0 :(得分:41)

Here's对算法的一个很好的描述也解释了放松的概念。

  

"放松"的概念来自估计之间的类比   最短路径和螺旋拉伸弹簧的长度   不是为压缩而设计的。最初,成本最短   路径是一种高估,就像一个伸展的春天。越短越好   找到路径,估计成本降低,弹簧是   轻松。最终,找到最短路径(如果存在)   春天已经放松到它的休息长度。

答案 1 :(得分:22)

Dijkstra算法中的松弛过程是指更新连接到顶点v的所有顶点的成本,如果通过在v中包含路径来提高这些成本。

答案 2 :(得分:8)

放宽边缘(你可以在其他最短路径算法中找到的概念)试图通过使用另一个顶点来降低到达顶点的成本。

您正在计算从起始顶点(比如 S )到所有其他顶点的距离。在某些时候,您有中间结果 - 当前估计。放松是您检查的过程,对于某些顶点 u v

if directly_connected(v, u)
    if est(S, v) > est(S, u) + dist(u,v)
       est(S, v) = est(S, u) + dist(u, v)

其中est(S,a)是距离的当前估计值,dist(a,b)是图中邻居的两个顶点之间的距离。

您在放松过程中基本上要检查的是天气,从 a b 的当前估计可以通过“转移”路径 c <来改善/ em>(此“转移”将是从 a c 以及从 c b的路径的长度)。

答案 3 :(得分:1)

边缘松弛过程

初始化

在最短路径算法中,您首先将零路径成本分配给起始节点(例如 S),并为每个其他节点分配无穷大路径成本(例如 A ,<强>电子)。

shortest_path_01

S := new Node()
A := new Node()
E := new Node()

// To go from S to S is zero
S.path_cost = 0

// high cost
A.path_cost = 1000 // "infinity"
E.path_cost = 1000 // "infinity"

边缘松弛

Infinity 是我们所能拥有的最高成本,因此我们希望尽可能将“放松”降低到更低的成本。为此,我们计算起始节点和另一个节点之间的路径成本(例如 aab),并更新节点的路径成本,如果路径成本更低。

shortest_path_02

a := 3
b := 5

SS := S.path_cost + 0
if (S.path_cost > SS) {
  // 0 !> 0 + 0
  S.path_cost = SS
}

Sa := S.path_cost + a
if (A.path_cost > Sa) {
  // 1000 > 0 + 3
  A.path_cost = Sa
  // A = 0 + 3
}

ab := A.path_cost + b
if (E.path_cost > ab) {
  // 1000 > 3 + 5
  E.path_cost = ab
  // E = 3 + 5
}

边缘松弛重复

shortest_path_03

c := 1

Sc := S.path_cost + c
if (E.path_cost > Sc) {
  // 8 > 0 + 1
  E.path_cost = Sc
  // E = 0 + 1
}

答案 4 :(得分:0)

让我们在图中假设我们有(u,v)∈E其中w(u,v)= 10 然后,如果通过在它们之间添加第三个顶点,如w(u,y)= 1和w(y,v)= 3,现在我们找到u和v之间的路径,其中权重1 + 3 = 4 <10。现在我们将第二条路径视为最短路径(u,y,v),并忽略第一条路径,这就是放松。

答案 5 :(得分:0)

边缘松弛。

  

放松边缘v-> w表示测试是否最著名的方法是   s到w是从s到v,然后从v到w占据边,如果是这样,   更新我们的数据结构。

Java代码:

private void relax(DirectedEdge e) {
    int v = e.from(), w = e.to;
    if (distTo[w] > distTo[v] + e.weight()) {
        distTo[w] = distTo[v] + e.weight();
        edgeTo[w] = e;
    }
}

还有顶点松弛。这意味着放宽从给定顶点指向的所有边。

private void relax(EdgeWeightedGraph G, int v) {
    for (DirectedEdge e : G.adj(v)) {
        relax(e);
    }
}

来自https://algs4.cs.princeton.edu/44sp/