day图论算法与模型构建(精品) .ppt
《day图论算法与模型构建(精品) .ppt》由会员分享,可在线阅读,更多相关《day图论算法与模型构建(精品) .ppt(111页珍藏版)》请在三一办公上搜索。
1、图论算法与模型构建,总览,图的基本概念与存储结构图的遍历和染色性图的连通性问题路径问题 拓扑排序流量问题匹配问题,图论中的“图”并不是通常意义下的几何图形或物体的形状图,而是以一种抽象的形式来表达一些确定的事物之间的联系的一个数学系统.,定义1 一个有序二元组(V,E)称为一个图,记为G=(V,E),其中,V称为G的顶点集,V,其元素称为顶点或结点,简称点;E称为G的边集,其元素称为边,它联结V 中的两个点,如果这两个点是无序的,则称该边为无向边,否则,称为有向边.如果V=v1,v2,vn是有限非空点集,则称G为有限图或n阶图.,Sec.1 图的基本概念与存储结构,如果E的每一条边都是无向边,
2、则称G为无向图(如图1);如果E的每一条边都是有向边,则称G为有向图(如图2);否则,称G为混合图.,图1,图2,并且常记,V=v1,v2,vn,|V|=n;E=e1,e2,em(ek=vivj),|E|=m.,称点vi,vj为边vivj的端点.在有向图中,称点vi,vj分别为边vivj的始点和终点.,有边联结的两个点称为相邻的点,有一个公共端点的边称为相邻边.边和它的端点称为互相关联.常用d(v)表示图G中与顶点v关联的边的数目,d(v)称为顶点v的度数.用N(v)表示图G中所有与顶点v相邻的顶点的集合.,d(v1)=d(v3)=d(v4)=4,d(v2)=2.,我们今后只讨论有限简单图:,
3、(1)顶点个数是有限的;(2)任意一条边有且只有两个不同的点与它相互关联;(3)若是无向图,则任意两个顶点最多只有一条边与之相联结;(4)若是有向图,则任意两个顶点最多只有两条边与之相联结.当两个顶点有两条边与之相联结时,这两条边的方向相反.如果某个有限图不满足(2)(3)(4),可在某条边上增设顶点使之满足.,定义2 若将图G的每一条边e都对应一个实数F(e),则称F(e)为该边的权,并称图G为赋权图(网络),记为G=(V,E,F).,定义3 设G=(V,E)是一个图,v0,v1,vkV,且1ik,vi-1viE,则称v0 v1 vk是G的一条通路.如果通路中没有相同的边,则称此通路为道路.
4、始点和终点相同的道路称为圈或回路.如果通路中既没有相同的边,又没有相同的顶点,则称此通路为路径,简称路.定义4 任意两点均有通路的图称为连通图.定义5 连通而无圈的图称为树,常用T表示树.,图的储存结构,矩阵邻接表邻接多重表十字链表,无向图邻接表,1,5,2,4,3,12345,1|,5|,4|,3|/,2|,2|,2|,3|,1|,2|,4|/,5|/,4|/,5|/,邻接链表每一个顶点有一个所有与之相邻的链表每一条边2 个(对无向图)要在两个顶点的链表中都加入空间复杂度O(|E|)对稀疏图这种方式比较好,邻接表,Pascal语言 const maxv=10000;type Tnode=re
5、cord/定义顶点类型 c:integer;/顶点编号 next:Tnode;/此点的邻接链表end;Var/数组g表示每个顶点的邻接链表/的链表头-哨兵 g:array1.maxv of Tnode;n,m,i,a,b:integer;t:Tnode;,C+语言#include using namespace std;const int maxv=10000;struct Tnode/定义顶点类型 int c;/顶点编号 Tnode*next;/此点的邻接链表;/数组g表示每个顶点的邻接链表/的链表头-哨兵 Tnode gmaxv;int n,m,i,a,b;Tnode*t;,图G有n个顶点
6、,编号从1到n。有m条有向边,输入时每行两个整数a b,表示边为从顶点a连接到顶点b。下面程序用指针实现图的邻接链表。,Pascal语言 procedure ins(x:integer;var p:Tnode);Begin/插入链表子过程 new(t);t.c:=x;t.next:=p.next;p.next:=t;end;begin readln(n,m);/初始化邻接链表“哨兵”for i:=1 to n do gi.next:=nil;/读入边,插入邻接链表 for i:=1 to m do begin readln(a,b);ins(b,ga);ins(a,gb);/无向边时再加入 e
7、nd;/.,C+语言 void ins(int x,Tnode/无向边时/,邻接表的实现A(指针),Pascal语言 const maxV=1000;/最多顶点数 maxE=10000;/最多边数type Tnode=record/定义顶点类型 c:integer;/节点编号 next:integer;/此节点的邻接链表end;var e:array1.maxE of Tnode;g:array1.maxV of Tnode;n,m,efree,i,a,b,t:integer;procedure ins(x:integer;var p:Tnode);begin/取一个空元素插入链表p后 eef
8、ree.c:=x;eefree.next:=p.next;p.next:=efree;efree:=efree+1;/新空元素下标end;,C+语言 const int maxV=1000,/最多顶点数 maxE=10000;/最多边数struct Tnode/定义顶点类型 int c;/顶点编号 int next;/此点的邻接链表;/数组g表示每个顶点的邻接链表/的链表头-哨兵 Tnode gmaxV,emaxE;int n,m,i,a,b,efree,t;void ins(int x,Tnode/新空元素下标,邻接表的实现B(数组),Pascal语言 begin readln(n,m);/
9、初始化邻接链表“哨兵”for i:=1 to n do gi.next:=-1;efree:=1;/读入边,插入邻接链表 for i:=1 to m do begin readln(a,b);ins(b,ga);ins(a,gb);/无向边时 end;.,C+语言 int main()cin n m;efree=0;/初始化邻接链表“哨兵”for(i=1;iab;ins(b,ga);/ins(a,gb);/无向边时,邻接表的实现B(数组),带权图的邻接表存储方法,Type Link=Node;Node=Record v,w:Longint;顶点和费用 Next:Link;End;Map:Arr
10、ay1.Maxnof Link;用邻接表记录的图,Read(n,m);For i:=1 to m do Begin Read(a,b,c);New(p);p.v:=b;p.w:=c;p.Next:=Mapa;Mapa:=p;End;,Sec.2 图的遍历和染色性,图的遍历和染色性是解决一切图论问题的根基,例如判断图的联通性,判断图是否有环,判断图是否为二分图,等等一些基本问题都要通过图的遍历和染色来进行。这一步骤虽然很不起眼,但是在编程解题过程中往往都是一些最基本的步骤,整个问题的求解往往都是由它开始的。,图的遍历,从图中某一顶点出发,按某种搜索方法访遍其余顶点,且使每一顶点仅被访问一次。这一
11、过程称为图的遍历。遍历图的基本搜索方法有两种:深度优先搜索DFS和广度优先搜索BFS。这两种方法都适用于有向图和无向图。,图的深度优先搜索遍历,图的深度优先遍历DFS算法是每次在访问完当前顶点后,首先访问当前顶点的一个未被访问过的邻接顶点,然后去访问这个邻接点的一个未被访问过的邻接点,这样的算法是一个递归算法。连通图的深度优先遍历算法思想。(1)访问初始顶点v并标记顶点v已访问。(2)查找顶点v的第一个邻接顶点w。(3)若顶点v的邻接顶点w存在,则继续执行;否则回溯到v,再找v的另外一个未访问过的邻接点。(4)若顶点w尚未被访问,则访问顶点w并标记顶点w为已访问。(5)继续查找顶点w的下一个邻
12、接顶点wi,如果v取值wi转到步骤(3)。直到连通图中所有顶点全部访问过为止。,深度优先遍历的程序实现:(邻接表、Pascal),/图的一般结构 type graph_node=record end;type AdjList=record id:integer;next:AdjList;end;var n_nodes,S_i:integer;nodes:array1.maxN of graph_node;visited:array1.maxNof integer;adj:array1.maxN of AdjList;,标识项点有没有访问过,每个顶点都有邻接链表,邻接链表的节点数据结构,深度优先
13、遍历的程序实现:(邻接表、Pascal),置每个点标识为“未访问”,从所有未被访问的点k出发,调用DFS(k),procedure search();begin k:integer;for k:=1 to n_nodes do visitedk:=0;for k:=1 to n_nodes do if visitedk0 then DFS(k);end;,置被访问节点的“时间”-次序,访问k的所有相邻的节点,procedure DFS(k:integer);begin/从k出发搜索 var j:AdjList;begin inc(S_i);visitedk:=S_i;j:=adjk;while
14、(jNULL)do begin if visitedj.id0 then DFS(j.id);j:=j.next;end;end;,图的广度优先搜索遍历,图的广度优先遍历BFS算法是一个分层搜索的过程,和树的层序遍历算法类同,它也需要一个队列以保持遍历过的顶点顺序,以便按出队的顺序再去访问这些顶点的邻接顶点。连通图的广度优先遍历算法思想。(1)顶点v入队列。(2)当队列非空时则继续执行,否则算法结束。(3)出队列取得队头顶点v;访问顶点v并标记顶点v已被访问。(4)查找顶点v的第一个邻接顶点col。(5)若v的邻接顶点col未被访问过的,则col入队列。(6)继续查找顶点v的另一个新的邻接顶点
15、col,转到步骤(5)。直到顶点v的所有未被访问过的邻接点处理完。转到步骤(2)。,广度优先遍历的程序实现:(邻接表、C+),/图的一般结构 struct graph_node;struct AdjList int id;AdjList*next;int n_nodes,S_index=0;graph_node nodes maxN;int visited maxN;AdjList*adj maxN;,标识项点有没有访问过,每个顶点都有邻接链表,邻接链表的节点数据结构,广度优先遍历的程序实现:(邻接表、C+),置每个点标识为“未访问”,从所有未被访问的点k出发,调用BFS(k),void se
16、arch()int k;for(k=0;kn_nodes;k+)visitedk=0;for(k=0;kn_nodes;k+)if(!visitedk)BFS(k);,宽度优先遍历的程序实现:(邻接表、C+),int q maxN;void BFS(int k)int front,back;q0=k;front=back=0;for(;fronnext)if(!visitedj-id)q+back=j-id;visitedj-id=+S_index;,BFS用的队列,一般全局,Front=back,队列不空,访问k的所有相邻的节点,例1、双栈排序(NOIP2008 提高组),给出N(1=n=1
17、000)个未排序的数,要求用两个栈将它排好序。有4种操作:1、入栈12、出栈13、入栈24、出栈2必须满足栈的先进后出的性质。不能排序则输出-1可以排序则输出字典序最小的操作序列。,这道题的关键还是在于构图和染色。,首先是构图:将所有数都看成点,两个点ai和aj之间连一条边的条件为ai和aj不能进入同一个栈。而不能进入同一个栈又如何判断呢?,如果存在k使得ijk且akaiaj则ai和aj不能进入同一个栈。,构图完毕,问题就渐渐明朗了,如果图中存在奇环则问题必然无解。,然后按照输入的顺序对图进行二染色,染到1的入1栈,染到2的入2栈。,这样每个数字进哪个栈都知道,剩下的就是模拟了。,图的连通分量
18、最小生成树问题(MST)桥和割顶,Sec3.图的连通性问题,生成树问题,无向图的最小生成树(贪心思想)Prim算法,适用于点少的图Kruskal算法,适用于边少的图有向图的最小树形图,局域网(net)某局域网内有n(n=100)台计算机,由于建网时工作人员的疏忽,现在网内存在回路,造成网络卡的现象。我们用f(i,j)表示i,j之间连接的畅通程度(f(i,j)=1000),f(i,j)值越小表示i,j之间连接越通畅,f(i,j)为0表示i,j之间无网线连接。现在我们需要除去一些连线,使得网络中没有回路,并且被除去网线的f(i,j)最大,请求出这个最大值。,实际问题,生成树:一个|V|个点的图,取
19、其中|V|-1条边,并连接所有的顶点,则组成原图的一个生成树。属性:|v|-1条边、连通、无环。最小生成树:加权图的最小生成树是一棵生成树,其所有边的权值之和不会大于其它任何生成树。简单讲:找出连接所有点的最低成本路线,最小生成树(MST),红边连接了所有顶点,所以构成一棵生成树权和=1+2+4+4+7+8+9,环属性:一棵生成树上,增加一条边e,再删除e所在环上的最大边,会得到另一棵“更好”的生成树(如果e不是最大边),最小生成树(MST)-算法原理,9,4,剪切属性:在图中,剪切将顶点划分成两个不相交集合。交叉边为这些顶点在两个不同集合的边。对于任何一个剪切,各条最小的交叉边都属于某个MS
20、T,且每个MST中都包含一条最小交叉边。,最小生成树(MST)-算法原理,7,4,9,最小边原则:图中权值最小的边(如果唯一的话)一定在最小生成树上。唯一性:一棵生成树上,如果各边的权都不相同,则最小生成树是唯一的。反之不然。,最小生成树(MST)-算法原理,Prim算法构建MST的过程,将1号节点置入集合S中。找到所有连接S中的节点和非S中的节点的边中的权值最小的那一条,并标记这条边,同时将连接的非S中的节点加入S集合。重复2步骤,直到所有节点都在S中了。,1,2,4,3,5,6,1,2,3,1,2,3,1,2,1,2,算法描述1:(1)将G剪切成两个集合A、B,A中只有一个点r(2)取最小
21、权的交叉边(x,y),xA,yB(3)将y加入A(4)如果已经加了n-1条边,结束。否则,转(3),最小生成树(MST)-Prim算法,算法描述2:MST_Prim(G,r)/从任意点r出发,生长成一MST for i=1 to n do disi/初始化每点到A集合的最小值 inAi false/设顶点不在A中disr 0/将r设为0(或-),准备取出for i=1 to n do v get-min()/取dis?中最小的值c和顶点v,inA v true/v放入A中 sum sum+c/c加入MST的总和中 updata(v)/枚举交叉边(v,B),改进dis,最小生成树(MST)-Pr
22、im算法,算法要点:每次求最小权交叉边时,如果都重新计算,则显然要枚举(x,y)-xA,yB。O(n2)时间复杂度。其实每次A中只是增加一个新顶点v,最多有交叉边(v,y),修改量只有与v有边的顶点,为O(n)。只需记录下B中的每个元素y与A所有元素中最小权边,则求最小值最多为O(n)-有时可以用“堆”优化。,最小生成树(MST)-Prim算法,Kruskal算法同样是常用的求最小生成树的算法之一,其算法思想如下:K r u s k a l算法每次选择n-1条边,所使用的贪婪准则是:从剩下的边中选择一条不会产生环路的具有最小耗费的边加入已选择的边的集合中。注意到所选取的边若产生环路则不可能形成
23、一棵生成树。K r u s k a l算法分e 步,其中e 是网络中边的数目。按耗费递增的顺序来考虑这e 条边,每次考虑一条边。当考虑某条边时,若将其加入到已选边的集合中会出现环路,则将其抛弃,否则,将它选入。这个算法可以用并叉集优化到o(e*(e)的时间复杂度。(表示阿克曼反函数),最小生成树(MST)-Kruskal算法,找到连接两个不同连通分量(由已标记的边构成的)的边中,权值最小的那一条,标记这条边。重复1步骤,直到所有节点都在同一连通分量中。,1,2,4,3,5,6,1,2,3,1,2,3,1,2,1,2,最小生成树(MST)-Prim算法,MST_Kruskal(G)(1)将G所有
24、条边按权从小到大排序;图mst开始为空(2)从小到大次序取边(x,y)(3)若加入边(x,y),mst就有环,则放弃此边,转(2)(4)将边(x,y)加入mst,如果已经加了n-1条边,结束。否则,转(2),最小生成树(MST)-Kruskal算法,算法要点:Kruskal算法的最难点在于怎样判断加入边(x,y)后是否形成了环。问题可化为:判断边(x,y)的两个顶点x,y在图(实际是森林)mst中是否已经连通。如果已经连通,加入边将形成环;否则,不形成环。并查集:连通点集之类问题,有高效算法-并查集。,最小生成树(MST)-Kruskal算法,算法描述:MST_Kruskal(G)for i=
25、1 to n do fi i;/初始化并查集 sort(e,e+m);/边按大小排序c 0;/取边的计数器for i=1 to m do/从小到大取边 v find_set(ei.v);/左端点所在连通块“根”u find_set(ei.u);/右端点所在连通块“根 if(u,v 不在同一连通块上)/如果不在同一连通块 union(v,u);/合并两连通块 sum=sum+gvu;/加入这条边的权 if(+c=n-1)break;/if 取了n-1条边,结束,最小生成树(MST)-Kruskal算法,时间复杂度分析Prim算法普通的方法 O(|V|2)Prim算法中用“堆”方法 O(|E|+|
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- day图论算法与模型构建精品 day 算法 模型 构建 精品

链接地址:https://www.31ppt.com/p-2226130.html