5.4图的应用

图的应用

1.最小生成树(研究问题:N个村庄修路连通,怎样花销最小让N个村庄连通)

一个连通图的生成树是该图的极小连通子图,通常为带权无向图

包含所有顶点,尽量少的边。

删除一条边则变为非连通图,增加一条边则会产生回路。

特点:

1.最小生成树不唯一,但该无向连通图中无相同权值边则最小生成树唯一;

2.最小生成树的权值之和唯一,即代价唯一;

3.该树顶点数为该连通图结点个数n,所有该生成树边为n-1。

常用生成树算法:

1.prim算法

2.Kruskal克鲁斯卡尔算法

两种算法都属于贪心算法。这也说明了生成树不唯一。

注:带权连通图的任一一个环中所包含的权值均不相同(充分不必要条件),则最小生成树唯一;

1.1prim算法

1.初始结点并加入顶点集U中;

2.遍历顶点集U中顶点,取指到向下一顶点的权值最小边且不造成回路,并将该下一顶点加入顶点集;

3.循环2直到所有顶点加入顶点集。

//V为结点集合
void Prim(G,T){
    T=null;
    U={v1};
    while(U!=V){
        edge,next_v =find_min_nextnode(U,V-U);//找到U中顶点到V-U中顶点最小边
        T+=edge;//该边加入最小生成树
        U+=next_v;//对应结点加入U集合
    }
}
//时间复杂度O(V^2),不依赖E

[外链图片转存失败(img-I4qbXAVm-1568732822107)(F:\Tim\1094201572\MobileFile\IMG_20190905_223948__01.jpg)]

1.2Kruskal算法

1.初始化所有边为堆

2.堆查找最小权值边,且不构成回路;并在堆集合删除该边;故选择最小权值边时间复杂度为O(logE)

3.循环2直至连通分量数为0,也就是T中边树为n-1;

//按权值递增的次序选择小而合适的边构造最小生成树
void Kruskal(G.V,T){
    T = V;
    numS = n;//连通分量数
    while(numS > 1){
        min_e = find_min_E(E);
        if(该边在剩余堆集合中会构成回路){
            T+=min_e;
            numS--;
        }
    }
}

[外链图片转存失败(img-aCDU36QM-1568732822109)(F:\Tim\1094201572\MobileFile\IMG_20190905_224034__01.jpg)]

1.3破圈法

2.最短路径(a村庄到b村庄所花最小开销到达的路径)

最短路径一定为简单路径,即路径中结点不重复。

对于无权图而言,两点之间边数最少的路径为最短路径;可用广度优先搜索查找最短路径;

对于有权图(可有向可无向),两点之间带权路径最短的为最短路径;

求解有权图最短路径的算法:

Dijkstra迪杰斯拉算法:求带权有向图的指定某一顶点到其他个个顶点的的最短路径,即求单源最短路径;

Floyd弗洛伊德算法:求带权有乡土所有顶点的之间的最短路径;

2.1Dijkstra算法

求某一顶点到其他个个顶点的的最短路径,即求单源最短路径;算法基于贪心策略,主体部分为一个双重循环,时间复杂度为O(V^2),

若要使用Dijkstra求解所有顶点之间的最短路径则指定V每一结点各使用一便Dijkstra算法。时间复杂度为O(V^3),故dijkstra认为可以求解每对顶点之间的最短路径问题

注:Dijkstra不适用带负权值的图

算法思想:

集合S,先后顺序存放求得最短路径的结点

1)初始化:S={0},0为V0源点结点,dist[i] =G.arcs[0]i],i=1,2,… //V0到Vi结点的当前最短距离,限制为1步;

2)从V-S中选出结点Vj,Vj=Min{dist[i]|Vi属于V-S中},选取当前限制步速到达结点中距离最短的结点加入S集合中,S=S+{j},即该轮得到最短路径的结点

3)限制步速+1,更新使V0结点限制步速到达任一结点的最短路径,dist[j]+G.arcs[j]k]<dist[k].则更新dist

4)重复2)3)操作n-1轮,直到所有结点包含在S中

注:Dijkstra求最短路径的“权值最小”和prim求最小生成树的“权值最小”的区别

Prim求最小生成树的“权值最小”是U集合中点到V-U集合中点的最小权值边;

最小生成树问题的图为带全无向图。 ·

而Dijkstra求最短路径的“权值最小”是源点到结点的的路径权值最小,即始终相对于选取的原点V0限制步速到指定结点的路径之和权值最小。

最短路径问题的图可为无向也可为有向。

最短路径例题:

[外链图片转存失败(img-gUxRCug5-1568732822110)(F:\Tim\1094201572\MobileFile\Dijkstra_example.jpg)]

Dijkstra算法过程:

[外链图片转存失败(img-hHTE9NDI-1568732822111)(F:\Tim\1094201572\MobileFile\Dijkstra_example2.jpg)]

依次求出1到5,4,2,3的最短路径

1-5:5;

1-5-4:7;

1-5-2:8;

1-5-2-3:9;

2.2Floyd算法

算法描述:

定义个n阶方阵序列A(-1),A(0),…,A(n-1),其中A(-1)为初始图 的邻接矩阵arcs[i]-[j];

A(k)[i]-[j] = Min{A(k-1)[i]-[j],A(k-1)[i]-[k]+A(k-1)[k]-[j] }

时间复杂度为O(V^3).

Floyd允许图中带负权值的边,但不允许负权值边构成回路。而Dijkstra不适用带负权值的图。

[外链图片转存失败(img-VTf7jDAX-1568732822124)(F:\Tim\1094201572\MobileFile\floyd.jpg)]

3.拓扑排序(

求解AOV网问题,有向无环图DAG图,顶点表示活动,边表示活动与活动之间存在联系;

金典研究问题:学生专业选课,顶点为课程,边为课程之间的关系,先修什么再修什么,拓扑排序给出结果,

即需要先完成什么才能继续干什么;

算法思想:

1.从有向无环图中选择一个没有前驱的顶点-即该顶点入度为0的顶点-输出;

2.从图中删除该顶点和所有以它为起点的有向边;

3.重复1,2直到该有向无环图为空或当前不存在无前驱的顶点为止,后者情况说明该有向图存在环,拓扑排序失败。

bool TopoSort(Graph G){

​ InitStatck(S); //使用存放入度为0的顶点,也可使用队列,不一定要使用栈;

​ V v = find_indegree_equ_zero(G);

​ Push(S,v);

​ while(!IsEmpty(S)){ //O(V+E) ,V为遍历的顶点,E为每个顶点所需删除的边即需修改下一顶点的入度次数

​ Pop(S,temp_v);

​ print(temp_v);count++; //输出该结点并计数;

​ reduce_nextv_indegree(temp_v,1);//下一节点

​ V v = find_indegree_equ_zero(G);

​ Push(S,v);

​ }

​ if(count < sum(G.V)) return false; //拓扑排序失败,图中存在回路;

​ else return true;//拓扑排序成功,该图为AOV网;

}

算法时间复杂度度为O(V+E);

工程问题中:

1)入度为0的顶点为,这个工程开始活动或继续活动,即该活动没有前驱活动或该活动的前驱活动已完成;

2)若活动线性有向排列,则拓扑排序唯一;例 1->2->3,拓扑排序123 注:活动线性有向排列 是 拓扑排序唯一 的充分不必要条件

3)若一个有向图具有有序拓扑排序序列,则它的邻接矩阵必定为三角矩阵;(按照拓扑排序的结果重新安排顶点的序号,生成的新的邻接矩阵为三角矩阵;)

一般的图,其邻接矩阵为三角矩阵**(充分不必要条件)**,则存在拓扑排序;反之不然;

4.关键路径(

求解AOE网问题,带权有向图,顶点表示事件,边表示活动;

解决问题:

1)完成整个项目工程至少需要多少时间(关键路径)?

2)为缩短完成工程的时间,应加快哪些活动(AOE中的边)? 或者说哪些活动是影响工程的关键?

完成整个工程所需的时间取决于从源点到汇点的最长路径长度,即在这条路径上所有活动的花费之和。这条路径长度最长的路径就叫做关键路径(Critical Path)。

关键路径上的花费即完成该工程项目至少需要的时间,即整个项目的完成时间(时间最长),即最早完成时间(书上说法);

1.事件的最早发生时间(到达该事件至少需要多少时间,即到达该事件最久时间)

V源=0;

Ve(k)=Max{Ve(j)+w(Vj,Vk)} 注:计算Ve(k)按从顺序计算

2.事件的最迟发生时间(最迟发生+与下一事件活动时间为下一事件的最早发生时间)

Vl(汇点)=Ve(汇点);

Vl(j)=Min{Vl(k)-w(Vj,Vk)} 注:计算Vl(j)按从顺序计算

3.活动的最早开始时间

活动的起点表示的事件的最早发生时间e(i)=Ve(k);

4.活动的最迟开始时间

活动终点所表示的事件的最迟发生时间与该活动之差l(i)=Vl(j)-w(Vk,Vj),<Vk,Vj>表示活动ai;

5.活动完成的时间余量

d(i)=l(i)-e(i); 若一个活动的时间余量为0,则说明该活动ai为关键活动,不如期完成会影响整个工程的进度;

注:

1)构造关键路径需要拓扑排序

2)关键活动的最早开始时间与最晚开始时间相等

具体实例:

[外链图片转存失败(img-3v1S9xpY-1568732822125)(F:\Tim\1094201572\MobileFile\关键路径.jpg)]

关键路径(v1,v3,v4,v6) 关键路径上的活动有a2,a5,a7

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章