《算法导论》笔记(13) 单源最短路径,所有结点对的最短路径

  单源最短路径,单目的地最短路径,单结点对最短路径,所有结点对最短路径。最短路径的子路径也是最短路径。最短路径不包含环路。松弛操作,三角不等式。前驱子图,最短路径树。

  Bellman-Ford算法。边总数-1次循环,每次循环将所有边进行松弛操作,最终得到最短路径,或者报错存在w为负数的环路。

relax(u, v){
  if(u.d+w(u, v)<v.d) {v.d=u.d+w(u,v); v.p=u;}
}
Bellman_Ford(G, w, s){
  for i = 1 to |G.V|-1 {
    for each edge(u, v) in G.E
      relax(u, v);
  }
  for each edge(u, v) in G.E
    if(v.d> u.d+w(u, v) ) throw error 
}

B-F适用于边有环路、有负值w的情形。总运行时间为O(EV)。若是不包括环路,则可用基于拓扑排序的简化版。运行时间为O(E+V)。

DAG_shortest_paths(G, w, s){
  topologically sort the G.V as P[]
  for each vertex u in P[]
    for each (u, v) in Adj[u]
      relax(u, v);
}

因为每条边只松弛一次,所以节省了运行时间。

  Dijkstra算法适用于所有w无负值的情况。类似于Prim最小生成树算法,维持一个子集,然后每次加入一个新元素。加入新元素的选择标准是u.d最小,然后松弛所有边(u, v)中的v。总运行时间为O(|V|^2)。

Dijkstra(G, w, s){
  Q=G.V;
  while(Q not empty){
    u=Q.extract_min;
    for each (u, v) in Adj[u]{
      relax(u, v);
    }
  }
}
  差分约束与最短路径。Ax<=b 约束条件下,寻找c'x的最大值。A是矩阵,x、b、c是向量。若A每行只有两个元素,分别取值+/-1,则称差分约束系统。约束图。一个可行解是x=(δ(x0, x1), δ(x0, x2).. .δ(x0, xn) ),约束图不能有负值的环路。x0是约束图中虚拟结点,以0权重直接连接所有结点。 

  所有结点对的最短路径问题。构造一个n*n的矩阵,L[i, j]是i结点到j结点的最短路径。下一次迭代时,L(n)[i, j]=min{L(n-1)[i, k ]+w[k, j ] }。在n-1次迭代后,得到所有结点对之间的最小路径。

extend_shortest_paths(L, w){
  for i = 1 to n 
    for j =1 to n
      New_L[i, j]=min{L[i, k] + w[k, j] } for all k= 1 to n
  return New_L[i, j]
}
slow_all_pairs_shortest_paths(w){
  L[1]=w
  for m=2 to n-1
    L[m]=extend_shortest_paths(L[m-1], w)
}
  Floyd-Warshall算法。寻找结点i到结点j的最短路径,可以考虑有某结点k,先从1到k-1的点集里找i到k的最短路径P1,再从1到k-1的点集里找到k到j的最短路径P2,则有两种可能性。从1到k-1的点集中寻找i到j的最短路径,要么不包含k,要么包含k且等于P1+P2. 那么从k=1到n迭代,计算可以得到所有点对间的最短路径。运行时间O(n^3)。

Floyd_Warshall(w){
L[0][i, j]=w;
  for k = 1 to n
    for i = 1 to n
      for j = 1 to n
        L[k][i, j]=min(L[k-1][i, j], L[k-1][i, k] + L[k-1][k, j] )
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值