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

Kruskal’s MST Algorithm

  • 另一个用于解决MST的贪心算法
  • 以下讨论仍然保留之前的假设(全联通、所有的边代价都是不同的)
  • 割性质:既有割的最小代价交边一定在MST中
  • 算法
    1. 将所有的边按照代价升序排列
    2. 初始化: T = ∅ T = \emptyset T=
    3. 迭代:1到 m m m(遍历每一条边)
      1. 如果 T ∪ { i } T \cup \{i\} T{i} 没有环,将 i i i加入到 T T T
    4. T T T即为最终结果
  • 直接实现
    • 搜索: O ( m log ⁡ n ) O(m \log n) O(mlogn)——因为边的数量最多为点的平方
    • 迭代: O ( m ) O(m) O(m)次迭代, O ( n ) O(n) O(n)次检查是否存在环(BFS)
    • 总时间复杂度: O ( m n ) O(mn) O(mn)
  • 并查集实现
    • 可以实现在常数时间内检查是否有环存在—— O ( m log ⁡ n ) O(m \log n) O(mlogn)
    • 并查集:维护一组实例的划分
      • find(x):返回输入所在组的名字
      • union(i, j):将两个组合并到一起
    • 对Kruskal算法
      • 添加一条边,要连结两个不同的组
  • 并查集
    • 每一个联通分量维护一个链式结构
    • 每一个连通分量可以将任一个节点作为leader
    • 不变量:每个连通分量内的顶点指向其leader
    • 常数时间检查一条边上的两个点是否在同一个联通分量——是否具有相同的leader
    • 不变量维护
      • 当一条边 ( u , v ) (u,v) (u,v)加入 T T T,两个端点所在分量将会合并
      • 保留较大分量的标签,将其领导者信息连接到较小的分量的节点上
        • 增加一个分量大小计算量,尽在合并时更新,易于维护
    • Kruskal算法:查询环只需要常数时间 O ( 1 ) O(1) O(1),并查集更新 O ( n log ⁡ n ) O(n \log n) O(nlogn)—— O ( m log ⁡ n ) O(m \log n) O(mlogn)

Clustering

  • 聚类:给定 n n n个点,将其归类为合理的若干组
  • 假设
    • 给定一个相似度度量标准 d ( p , q ) d(p, q) d(p,q)
    • 指标满足对称性 d ( p , q ) = d ( q , p ) d(p, q) = d(q, p) d(p,q)=d(q,p)
  • 目标:同一聚簇内的点具有“靠近”的性质
  • 最大区分K聚类
    • 假设聚簇个数 k k k已知
    • 区分距离:两个聚簇内最近点对距离
    • 目标:给定距离度量和聚簇个数,形成的聚簇具有最大区分距离
    • 算法:初始化每个点作为一个聚簇,每次选择所有聚簇的区分距离最小的,合并之,直到只剩 k k k个聚簇
    • 其实思路接近Kruskal,但是更早地结束(MST实际是一个聚簇)

Advanced Union Find

  • 查找过程,每个节点直接指向其组内领导者
    • O ( 1 ) O(1) O(1)的查找时间
    • O ( n log ⁡ n ) O(n \log n) O(nlogn)的合并时间
  • Lazy Unions
    • 初始化:每个节点各自为政
    • 查找:从查询节点遍历父节点,直到根节点(自己指向自己)
    • 合并:首先找到欲合并点的根节点,更新其中一个根节点的指针,指向另外一个根节点
    • 旧领导者连接到新领导者
    • Pro:合并操作简化到2次find和1次union(修改一个连接, O ( 1 ) O(1) O(1)
    • Con:由于不是所有节点都指向其领导者,因此需要遍历一个路径以寻找领导者——时间复杂度不能保证 O ( 1 ) O(1) O(1)
  • Union by Rank
    • 对Lazy Union,不对合并过程限制的话,可能产生一颗非常高的树
      • 最糟糕情形下,查找和合并的时间复杂度都能达到 O ( n ) O(n) O(n)
      • 我们需要树尽可能地浅
    • 排序量rank[x]:对x所在子树,其中节点查询到达x本身的最大跳转次数
      • 初始化,所有的节点的排序值为0
      • 实际上就是树的深度
    • Union By Rank:选择根节点排序量较大的作为合并后的根节点
      • 如果两个根节点的排序量相等,合并后的根节点排序量+1
      • 否则,排序量不做修改
      • 最大的排序量不会超过 log ⁡ 2 ( n ) \log_2 (n) log2(n)
    • 不变量
      • rank[x]只会随时间增长
      • 只有根节点的rank[x]才会增长
      • 某一结点到根节点,rank[x]严格增长
    • 引理:对于任意的并查集操作,最多有 n 2 r \frac {n} {2^r} 2rn个节点的排序量为 r r r
    • 结论:最大排序量必然不超过 log ⁡ 2 n \log_2 n log2n
    • 结论:使用union by rank 的并查集,查找时间复杂度不会超过 O ( log ⁡ n ) O(\log n) O(logn)
  • Path Compression
    • 在完成find(x)操作之后,建立一条直接到达根节点的捷径
    • Pro:加速查找速度
    • Con:增加一个常数时间开销(回标)
    • 和Rank搭配:所有的排序量按照不使用路径压缩的情形处理
      • 至此,排序量已经失去了之前的定义表述,只是最大跳转次数的上界
      • 但是,由于处理流程不变,只是树变得更“扁”了,所以引理仍然成立
      • 同时,父节点的排序量会严格大于当前节点
    • Hopcroft-Ulman理论:union by rank + path compression,会让时间复杂度达到 O ( m log ⁡ ∗ n ) O(m \log^\ast n) O(mlogn),其中 log ⁡ ∗ n \log^\ast n logn表示对 n n n不断取2对数, 直到结果不大于1前的取对数次数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值