算法4学习笔记
有向图和无向图没有多大的差别,只是有向图addEdge()时只添加一条边而已
即边是有方向的
头->尾
概念
- 有向环:一条至少含有一条边且起点和终点相同的有向路径
有向图中的可达性和无向图中的连通性区别 - 出度: 该点指出的边的总数
- 入度: 指向该点的边的总数
算法
1. 有向图的可达性 DirectedDFS
涉及算法: DepthFirstDirectedPaths BreadthFirstDirectedPaths
深度优先搜索能解决一幅有向无环图的问题
单点连通性的问题
给定一幅图和一个起点,回答"是否存在一条从s到达给定顶点V的有向路径"
多点可达性 后面5.4会再提到
给定一幅图和顶点的集合,回答"是否存在一条从集合中任意顶点到达给定顶点V的有向路径"
有向图的应用
- JAVA的垃圾回收
- 先修课样式
(拓扑排序):给定一幅有向图,将所有的顶点排序,使得所有的有向边均从排在前面的元素指向排在后面的元素
2. 环和有向无环图
涉及算法: DirectedCycle Topological DepthFirstOrder TransitiveClosure
拓扑排序的应用:
- 任务调度 .:任务 -> 优先级限制
- 课程安排 .: 课程 -> 先导课程限制
- 继承 .: JAVA类 -> extends关系
一幅有向无环图的拓扑排序即为所有顶点的逆后序排列
有向图中基于深度优先搜索的顶点排序 DepthFirstorder
基本思想:是深度优先搜索正好只会访问每个顶点一次 若将dfs()的参数顶点保存在一个数据结构(栈,队列)中 遍历这个数据结构就能访问途中的所有顶点
3种排列顺序:
- 先序: 递归调用前
- 后序: 递归调用后
- 逆后序: 递归调用后压入栈
实现
p374
寻找有向环 DirectedEdge
private boolean[] onStack; // onStack[v] = is vertex on the stack?
private Stack<Integer> cycle; // directed cycle (or null if no such cycle)
dfs() 方法添加一个boolean类型数组onStack[] 来保存递归调用期间栈上的所有顶点 调用dfs(G,v)时将onStack[v] 设为true,结束时变为false
拓扑排序 Topological
一幅有向无环图的拓扑排序即为所有顶点的逆后续排列
证明: v->w dfs(v) 有一个成立
dfs(w)调用了且返回了
dfs(w) 没调用 v->w会直接或间接调用并返回dfs(w),且dfs(w)会在dfs(v)返回前返回
总之就是dfs(v)里面包括了dfs(w),正常返回来说w在v之前
逆后序就是在v之后
- 使用深度优先搜索对有向无环图进行拓扑排序时间和V+E成正比
实现
判断权值入度为不为0,为0就加入quue,弹出queue,判断下一个-1为不为0,0就加入queue
解决任务调用类应用:
- 指明任务和优先级条件
- 不断检测并去除有向图种的所有环,确保可行
- 使用拓扑排序解决调度问题
调用方案有变动后,都要重新检查有没有存在环
public class DirectedCycle
3. 有向图中的强连通性
涉及算法: Kosaraju算法
强连通: v<->w 中间有许多边
强连通分量
- 自反性:任意顶点v和自己都是强连通的
- 对称性:如果v和w是强连通的,那么w和v也是强连通的
- 传递性:如果v和w是强连通的且w和x是强连通的,那么v和x也是强连通的
Kosaraju算法
高效计算强连通分量
实现
- 给定一幅有向图G 中 使用DepthFirstOrder计算它的反向图G^R 的逆后续排列
- 在G中进行标准的深度优先搜索 其构造函数每一次递归调用所标记的顶点都在同一个强连通分量中
证明: 1. 反证法证明每个和s强连通的顶点v都会在构造函数调用的dfs(G,s)中访问到
2. 构造函数调用的dfs(G,s)所到达的任意顶点v都必然是和s强连通的 =》G^R中存在一条从s到v的路径
再谈可达性
给定一幅有向图,是否存在一条从一个给定的顶点v到另一个给定的顶点w的路径?
对于一对非强连通的顶点,业务存在一条从v到w的路径,业务存在w到v的,也许都不存在
G的传递闭包是由相同顶点组成的另一幅有向图,传递闭包存在一条从v到w的边当且仅当在G中w是从v可达的
一幅很稀疏的图它的传递闭包可能会很稠密
有向 一开始就只有一条边 ---->是什么
深搜能解决有向无环问题
深搜的顶点排序: ----->为什么
先序: 递归调用前
后序: 递归调用后
逆后序: 递归调用后压入栈
一幅有向无环图的拓扑排序即为所有顶点的逆后序排列
拓扑排序 -------->是什么
只能是有向无环
修课一样,低级到高级,入度下,出度高
拓扑排序时间和V+E成正比
强连通:
自反
对称
传递
kosaraju算法
计算强连通分量
求逆序
小结
问题 | 解决方案 |
---|---|
单点和多点的可达性 | DirectedDFS |
单点有向路径 | DepthFirstDirectedPaths |
单点最短有向路径 | BreadthFirstDirectedPaths |
有向环的检测 | DirectedCycle |
深度优先的顶点排序 | DepthFirstOrder |
优先级限制下的调度问题/拓扑排序 | Topological |
强连通性 | KosarajuSCC |
顶点对的可达性 | TranitiveClosure |