图的有关算法

来源:互联网 发布:new balance淘宝旗舰店 编辑:程序博客网 时间:2024/05/17 17:54

涉及到图的有关算法比较多,这里只简单归纳介绍一下,具体算法希望大家参考有关资料。

一、求最小代价生成树
设G=(V,E)是一个连通的无向图,若G1是包含G中所有顶点的一个无回路的连通子图,则称G1为G的一棵生成树。其中代价最小(各条边的权值之和最小)的生成树就称为最小代价生成树(简称最小生成树)。
这里提供两种算法来求解这一问题:普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法。分别适用于求边稠密的网的最小生成树和边稀疏的网的最小生成树,其时间复杂度分别是O(n2)和O(eloge)(e为网中边的数目)。
其中prim算法基本思想:任选一个顶点v0开始,连接与v0最近的顶点v1,得子树T1,再连接与T1最近的顶点v2,得子树T2,如此进行下去,直到所有顶点都用到为止。
L(v):v 到子树T0的直接距离。E是边集合。
输入加权连通图的带权邻接矩阵C=(Cij)n*n.
(1) T0<-空集,C(T0)<-0,V1={v0}
(2) 对每一点v属于V-V1,L(v)<-C(v, v0);[如果(v, v0)不属于E,则C(v, v0)=无穷大]
(3) 若V1=V,则输出T0,C(T0),停机。否则转到下一步;
(4) 在V-V1中找一点u,使L(u)=min{L(v)|v属于(V-V1)},并记在V1中与u相邻的点为w,e=(w,u)
(5) T0 <-T0 ,C(T0)<- C(T0)+ C(e), V1 <-V1
(6) 对所有的v属于V-V1,若C(v, u)<L(v),则L(v)<- C(v, u),否则L(v)不变。
(7) 转3
克鲁斯卡尔(Kruskal)算法基本思想:最初把图的n个顶点看作n个分离的部分树,每个树具有一个顶点,算法的每一步选择可连接两分离树的边中权最小的边连接两个部分树,合二为一,部分树逐步减少,直到只有一个部分树,便得到最小生成树。
克鲁斯卡尔(Kruskal)算法步骤:
T0 :存放生成树的边的集合,初态为空;
C(T0):最小生成树的权,初值为0;
VS:部分树的顶点集合,其初值为{{v0}{ v1}......{ vn}}
输入边的端点数组A(e),边的权值w(e);
(1) T0 为空,C(T0)<-0;VS为空,将E中的边按从小到大的顺序排列成队列Q;
(2) 对所有的v属于V,VS〈-{v};
(3) 若|VS|=1,输出T0 ,C(T0) ,停止,否则转下一步;
(4) 从Q中取出排头边(u,v),并从Q中删除(u,v);
(5) 如u,v杂VS的同一个元素集 V1 中,则转4,否则分属于两个几个V1 V2 ,进行下一步;
(6) T0<- T0 ,V<- , C(T0)<- C(T0)+ C(u,v),转3

二、求最短路径
在图中求最短路径问题有两种提法,一是求从某个源点到其他顶点的最短路径,二是求每一对顶点之间的最短路径。
对于前者,一般采用迪杰斯特拉(Dijkstra)算法,按路径长度递增的次序产生最短路径。时间复杂度为O(n2)。
迪杰斯特拉(Dijkstra)算法的基本思想:生长一棵以v0为根的最短路树,在这棵树上每一顶点与根之间的路径都是最短路径。由于网络不存在负权,最短路树的生长过程中各顶点将按照距v0的远近及顶点的相邻关系,逐次长入树中,先近后远,直至所有顶点都已经在树中。
解决后面一种问题的方法是:每次以一个顶点为源点,重复执行迪杰斯特拉算法n次。另外还可以使用一种弗洛伊德(Floyd)算法,其时间复杂度也是O(n3)。
弗洛伊德(Floyd)算法基本思想:直接在图的带权邻接矩阵中用插入顶点的方法依次构造出n个矩阵,D(1)D(2)....D(n),使最后得到的矩阵.D(n)成为图的距离矩阵,同时也求出插入点矩阵以便得到两点见的最短路径。

三、拓扑排序
拓扑排序的算法原理实际很简单。
I. 在有向图中选一个没有前驱的顶点且输出之
II. 从图中删除该顶点和所有以它为尾的弧
重复执行以上两步,直至全部顶点均已输出,或者当前图中不存在无前驱的顶点为止。后一种情况则说明有向图中存在环。

四、求关键路径
在AOE网络中的某些活动可以并行的进行,因此完成工程的最少时间是从开始顶点到结束顶点的最长路径长度,称从开始顶点到结束顶点的最长路径为关键路径,关键路径上的活动即为关键活动。

原创粉丝点击