目录
1.回路的判断:
用深度优先遍历,在有向图中如果遍历过程中重复访问到已经访问过的点,那么这个有向图就是就是有回路;如果是无向图,重复访问到了祖先结点那么这个无向图就存在回路。
2.普利姆-最小生成树
需要输入一个开始结点,新建一个对象数组arr [ size ] (nodeIndex,lowcost) ,其中nodeIndex指的是结点在邻接矩阵或者邻接表的数组下标,其中arr[ i ] 表示 nodeIndex 到 i 的 是最短路径,消耗是lowcost。
对新加入的结点进行遍历边,比对 arr[i] ,如果新的边比arr[i]更小那么就重新覆盖 arr[i]的值,然后再旋转lowcost最小的点,再进行进行加入。反复执行次操作。
1.假设刚开始输入是A ,那么遍历 A 的边 ,初始化最小值 ,得到最小的边是(A,C),.然后把C 加入到集合
2 遍历新结点C的所有边,其中(C,B)要比原来的(A,B)要小 ;(C,E),(C,F)要比原先的(A,E) (A,F)要小,覆盖值,不断重复步骤2,直到遍历n次(结点总数)
次数\结点 | A | B | C | D | E | F | 已加入的点 | 最小结点 | 备注 |
1 | (null) | (A,6) | (A,1) | (A,5) | (A,∞) | (A,∞) | (A) | C | 把C加入到集合 |
2 | (null) | (C,5) | (null) | (A,5) | (C,6) | (C,4) | (A,C) | F | (C,B)比原来的(A,B)小,覆盖 |
3 | (null) | (C,5) | (null) | (F,2) | (C,6) | (null) | (A,C,F) | D | (F,D)比(A,D)小 |
4 | (null) | (C,5) | (null) | (null) | (C,6) | (null) | (A,C,F,D) | B | D的边没有原来的小 |
5 | (null) | (null) | (null) | (null) | (B,3) | (null) | (A,C,F,D,B) | E | (B,E)比(C,E)小 |
6 | (null) | (null) | (null) | (null) | (null) | (null) | (A,C,F,D,B,E) | 结束 | 总共6个结点,共遍历6次 |
3.克鲁斯特卡尔-最小生成树
刚开始,每个结点为各立为一组连通分量。连通分量之间选出最短的边,同通过最短的边,来合并连通分量,反复直到所有结点在同一个连通分量中,结束,或者无可以连接的边结束。当添加最短边时出现回路则选下一条边
对边进行从小到大排序:
(A,C,1)(D,F,2)(B,E,3)(C,F,4)(A,D,5)(B,C,5)(C,D,5)(A,B,6)(C,E,6)(E,F,6)
初始连通分量组 | A | B | C | D | E | F |
第1小边(A,C) | (A,C) | B | D | E | F | |
第2小边(D,F) | (A,C) | B | (D,F) | E | ||
第3小边(B,E) | (A,C) | (B,E) | (D,F) | |||
第4小边(C,F) | (A,C,D,F) | (B,E) | ||||
第5小边(A,D),已在同一集合中,形成回路 | (A,C,D,F) | (B,E) | ||||
第6小边(B,C) | (A,C,D,F,B,E) | |||||
全部结点在同一集合中,结束 |
4.迪杰斯特拉-最短路径
目标:输入一个起始结点,求起始结点到其他结点的最短路径和代价。需要提前初始化好邻接矩阵 adjacencyMatrix_。
假设输入起始点A,当前路径 A (也是已访问的点),
对象数组的对象元素 时 (最小代价 lowcost_,和 最短路径 pathIndex_)
1.求到所有点的代价(A,C,10) (A,E,30) ,(A,F,100) ,选取最小代价的直接目标结点currentPathIndex(C)。加入到当前路径currentPath (A,C) 代价lowestCost为10.
2.即
currentPath= lowestPaths[currentPathIndex].pathIndex_ + currentPathIndex ;
lowestCost=lowestPaths[currentPathIndex].lowcost_
3.遍历LowestPaths[0....j...n] (排除在CurrentPath的点)
if (lowestCost+ adjacencyMatrix_[currentPathIndex][j] <lowestPaths[j].lowcost_) { lowestPaths[j].lowcost_= lowestCost+ adjacencyMatrix_[currentPathIndex][j] ; lowestPaths[j].pathIndex_=currentPath; }
重复 2,3
求解步骤:
5.图的最长路径(不走重复路)
不管是有向图或者无向图都适用的递归方法,建议使用邻接矩阵的数据结构,当图是有向无环图的时候,求的是关键路径。主要思想是:当已知源节点到目标结点的前继结点的最长路径时, 就可求得 源节点到目标结点的最长路径..
加入求 结点V0 到 Vn 的最长路径。那么首先要列出Vn的前驱结点集(Vxi,Vxi....)
有递归函数fun(V0,Vn) 表示V0到Vn的最长路径 。其值 =Max(fun(V0,Vxi)+arc[Vxi][Vn]).通过次方法找到最长路径。找最短路径也可以参考此方法
函数格式 double fun( src , target , vector<int> & hasVisits)
提前初始化邻接矩阵 arc[][]。
0.如果源结点和目标结点相同则返回0。
1.已访问的结点集 hasVisits为引用形参,把目标结点target 加入进该集合。
2.寻找还未访问的目标结点的前继结点。
3.判断邻接矩阵arc[源结点][目标结点] 的是否是∞,如果为真初始化最大路径maxValue为最小浮点值,如果为假 maxValue为设置为arc[源结点][目标结点]。
4..拷贝hasVisits出一个副本,遍历前继结点集合,
value = fun(源结点,某个前继结点,hasVisits的副本引用) + arc[某个前继结点][目标结点]
,如果value大于maxvalue时,maxvalue赋值成value且 hasVisit赋值成hasVisits的副本引用。最后递归结束时hasVisits就是最大路径,返回值就是最大代价。
6.有向无环图的关键路径
主要思想就是 找出 最早开始时间和最晚结束时间相等的结点
起始结点的最早开始时间是 0 ,把代价当作时间。
每个结点最早开始时间 = max(前继结点的最早开始时间+ arc[前继结点][当前结点])
终点结点的最晚结束时间=终点结点的最早开始时间。
每个结点最晚结束时间 = min((后继结点的最晚结束时间 - arc[当前结点][后继结点])
最早开始时间和最晚结束时间相等的结点就是关键结点,通路就是关键路径