Coursera - Algorithm (Stanford) - 课程笔记 - Week 6

Dijkstra’s Shortest Path Algorithm

  • 单源最短路
    • 输入:有向图 G = ( V , E ) G=(V, E) G=(V,E),要求所有边权非负,给定源点 s s s
    • 输出:计算从 s s s到所有 v ∈ V v \in V vV的最短路径长度
    • 两个假设:
      • (方便起见)所有点 v v v都存在从 s s s到达之的路径
      • 所有边权值非负
  • BFS求解最短路?
    • 只能处理边权均为1(或者所有的边权均一致)的情形
    • 将非单元权值边处理成多条单元权值边?无法控制展开规模
  • 算法
    • 初始化
      • 将源点 s s s加入到以遍历点集 X X X
      • 结果数组 A [ s ] = 0 A[s]=0 A[s]=0
      • 路径数据 B [ S ] B[S] B[S]为空路径(实际实现中用不到)
    • 主循环
      • 终止条件: X = V X = V X=V
      • 考察跨域(从 X X X V − X V-X VX)边中最短的一条( min ⁡ v ∈ X , w ∈ V − X { A [ v ] + l v w } \min_{v \in X, w \in V-X} \{A[v] + l_{vw}\} minvX,wVX{A[v]+lvw} ( v ∗ , w ∗ ) (v^\ast, w^\ast) (v,w)
      • w ∗ w^\ast w加入 X X X
      • 赋值 A [ w ∗ ] = A [ v ] + l v ∗ w ∗ A[w^\ast] = A[v] + l_{v^\ast w^\ast} A[w]=A[v]+lvw
      • 赋值 B [ w ∗ ] = B [ v ∗ ] ∪ ( v ∗ , w ∗ ) B[w^\ast] = B[v^\ast] \cup (v^\ast, w^\ast) B[w]=B[v](v,w)
  • 不允许负权值边?无法保证最短路,且会出现错误
  • 时间复杂度 O ( m n ) O(mn) O(mn)
  • 使用数据结构来加快运行速度?及时维护“最短边”——堆
    • 堆能够保证在 O ( log ⁡ n ) O(\log n) O(logn)时间内得到最小值
    • 不变量1:用堆维护 V − X V-X VX中的顶点
    • 不变量2:用对维护 k e y [ v ] , v ∉ X key[v], v \notin X key[v],v/X,其为以该点为边的头的最小“分值”(不存在满足要求的边的顶点,则赋值正无穷)
      • 第一轮,每个 V − X V-X VX中的顶点更新 k e y key key值(实际就是 A A A值)
      • 第二轮,得到堆中的最小值
    • 维护不变量:第一个显然,第二个只需要考察与被包含顶点存在边的顶点(边要求从被包含点到该点)的 k e y key key值,为了方便实现:
      • 删除顶点
      • 重新计算 k e y key key
      • 以更新后的 k e y key key值重新插入该顶点
    • 时间复杂度
      • 堆操作 O ( log ⁡ n ) O(\log n) O(logn)
      • 每一个顶点需要取一次最小值 O ( n log ⁡ n ) O(n \log n) O(nlogn)
      • 针对每一个边,至多出发一次更新 O ( m log ⁡ n ) O(m \log n) O(mlogn)
      • 考虑弱连通图, n n n m m m相当,整体时间复杂度 O ( m log ⁡ n ) O(m \log n) O(mlogn)
      • 最短路时间接近排序算法
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值