松弛:原来用一根橡皮筋连接p和w两点,现在有一点v到w的路径更短,现在把橡皮筋w点的另一端p换成v点,这样缓解橡皮筋紧绷的压力,让其变得松弛。
1)松弛边: v -> w 意味着先检查从s到w的最短路径是否是先从s 到 v,再由v -> w, 如果是,则更新distTo[w]和EdgeTo[w]的数据。
private void relax(DirectedEdge e)
{
int v = e.from(), w = e.to();
if (distTo[w] > distTo[v] + e.Weight()) // 当distTo[v] !=double.PositiveInfinity 才可能为TRUE,这时v是目前到到w最短的边
{
distTo[w] = distTo[v] + e.Weight();
edgeTo[w] = e;
if (pq.contains(w)) pq.decreaseKey(w, distTo[w]);
else pq.insert(w, distTo[w]);
}
}
1)如果distTo[w] > distTo[v] + e.Weight() 意味着最短路径是先从s 到 v,再由v -> w, 所以更新distTo[w]和EdgeTo[w]的数据。
2)如果distTo[w] < distTo[v] + e.Weight() 则边v -> w失效,忽略这条边
注意:以下情况a和b不能比较,虽然感觉a<b,但计算机可不这么认为
double a = double.PositiveInfinity;
double b = (double.PositiveInfinity+10);
print(a>b); //false
print(a<b); //false
print(a==b); //true
2)顶点的松弛
private void relax(EdgeWeightedDigraph G,int v)
{
foreach (DirectedEdge e in G.Adj(v))
{
int w = e.to();
if (distTo[w] > distTo[v] + e.Weight())
{
distTo[w] = distTo[v] + e.Weight();
edgeTo[w] = e;
}
}
}