图论算法及其MATLAB程序代码_第1页
图论算法及其MATLAB程序代码_第2页
图论算法及其MATLAB程序代码_第3页
图论算法及其MATLAB程序代码_第4页
图论算法及其MATLAB程序代码_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、图论算法及其MATLAB程序代码求赋权图G = (V, E , F )中任意两点间的最短路的Warshall-Floyd算法:设A = (aij )n×n为赋权图G = (V, E , F )的矩阵, 当vivjE时aij = F (vivj), 否则取aii =0, aij = +(ij ), dij表示从vi到vj点的距离, rij表示从vi到vj点的最短路中一个点的编号. 赋初值. 对所有i, j, dij = aij, rij = j. k = 1. 转向 更新dij, rij . 对所有i, j, 若dik + dk jdij, 则令dij = dik + dk j, ri

2、j = k, 转向. 终止判断. 若dii0, 则存在一条含有顶点vi的负回路, 终止; 或者k = n终止; 否则令k = k + 1, 转向.最短路线可由rij得到.例1 求图6-4中任意两点间的最短路.图6-4解:用Warshall-Floyd算法, MATLAB程序代码如下:n=8;A=0281InfInfInfInf206Inf1InfInfInf8607512Inf1Inf70InfInf9InfInf15Inf03Inf8InfInf1Inf3046InfInf29Inf403InfInfInfInf8630; % MATLAB中, Inf表示D=A; %赋初值for(i=1:n

3、)for(j=1:n)R(i,j)=j;end;end%赋路径初值for(k=1:n)for(i=1:n)for(j=1:n)if(D(i,k)+D(k,j)<D(i,j)D(i,j)=D(i,k)+D(k,j); %更新dijR(i,j)=R(k,j);end;end;end%更新rijk%显示迭代步数D%显示每步迭代后的路长R%显示每步迭代后的路径pd=0;for i=1:n%含有负权时if(D(i,i)<0)pd=1;break;end;end%存在一条含有顶点vi的负回路if(pd)break;end%存在一条负回路, 终止程序end%程序结束Kruskal避圈法:将图G中

4、的边按权数从小到大逐条考察, 按不构成圈的原则加入到T中(若有选择时, 不同的选择可能会导致最后生成树的权数不同), 直到q (T ) = p (G ) - 1为止, 即T 的边数= G的顶点数- 1为止.Kruskal避圈法的MATLAB程序代码如下:n=8;A=0281000020601000860751201070009001500308001030460029040300008630; k=1;%记录A中不同正数的个数for(i=1:n-1)for(j=i+1:n) %此循环是查找A中所有不同的正数if(A(i,j)>0)x(k)=A(i,j);%数组x记录A中不同的正数kk=1

5、;%临时变量for(s=1:k-1)if(x(k)=x(s)kk=0;break;end;end%排除相同的正数k=k+kk;end;end;endk=k-1%显示A中所有不同正数的个数for(i=1:k-1)for(j=i+1:k) %将x中不同的正数从小到大排序if(x(j)<x(i)xx=x(j);x(j)=x(i);x(i)=xx;end;end;endT(n,n)=0;%将矩阵T中所有的元素赋值为0q=0;%记录加入到树T中的边数for(s=1:k)if(q=n)break;end%获得最小生成树T, 算法终止for(i=1:n-1)for(j=i+1:n)if (A(i,j)

6、=x(s)T(i,j)=x(s);T(j,i)=x(s);%加入边到树T中TT=T;%临时记录Twhile(1)pd=1;%砍掉TT中所有的树枝for(y=1:n)kk=0;for(z=1:n)if(TT(y,z)>0)kk=kk+1;zz=z;end;end%寻找TT中的树枝if(kk=1)TT(y,zz)=0;TT(zz,y)=0;pd=0;end;end%砍掉TT中的树枝if(pd)break;end;end%已砍掉了TT中所有的树枝pd=0;%判断TT中是否有圈for(y=1:n-1)for(z=y+1:n)if(TT(y,z)>0)pd=1;break;end;end;e

7、ndif(pd)T(i,j)=0;T(j,i)=0;%假如TT中有圈else q=q+1;end;end;end;end;endT%显示近似最小生成树T, 程序结束求二部图G的最大匹配的算法(匈牙利算法), 其基本思想是:从G的任意匹配M开始, 对X中所有M的非饱和点, 寻找M -增广路. 若不存在M -增广路, 则M为最大匹配; 若存在M -增广路P, 则将P中M与非M的边互换得到比M多一边的匹配M1 , 再对M1重复上述过程.设G = ( X, Y, E )为二部图, 其中X = x1, x2, , xn , Y = y1, y2, , yn. 任取G的一初始匹配M (如任取eE, 则M

8、= e是一个匹配). 令S = f , T = f , 转向. 若M饱和X S的所有点, 则M是二部图G的最大匹配. 否则, 任取M的非饱和点uX S , 令S = S u , 转向. 记N (S ) = v | uS, uvE . 若N (S ) = T, 转向. 否则取yN (S ) T. 若y是M的饱和点, 转向, 否则转向. 设x yM, 则令S = S x , T = T y , 转向. u - y路是M-增广路, 设为P, 并令 M = MP, 转向. 这里MP = MP MP, 是对称差.由于计算M-增广路P比较麻烦, 因此将迭代步骤改为: 将X中M的所有非饱和点(不是M中某条边

9、的端点)都给以标号0和标记*, 转向. 若X中所有有标号的点都已去掉了标记*, 则M是G的最大匹配. 否则任取X中一个既有标号又有标记*的点xi , 去掉xi的标记*, 转向. 找出在G中所有与xi邻接的点yj (即xi yjE ), 若所有这样的yj都已有标号, 则转向, 否则转向. 对与xi邻接且尚未给标号的yj都给定标号i. 若所有的yj都是M的饱和点, 则转向, 否则逆向返回. 即由其中M的任一个非饱和点yj的标号i找到xi, 再由xi的标号k找到yk , , 最后由yt的标号s找到标号为0的xs时结束, 获得M -增广路xs yt xi yj, 记P = xs yt, , xi yj

10、 , 重新记M为MP, 转向. 将yj在M中与之邻接的点xk (即xk yjM), 给以标号j和标记*, 转向.例1 求图6-9中所示的二部图G的最大匹配.图6-9匈牙利算法的MATLAB程序代码如下:m=5;n=5;A=0110011011011000110000011;M(m,n)=0;for(i=1:m)for(j=1:n)if(A(i,j)M(i,j)=1;break;end;end %求初始匹配Mif(M(i,j)break;end;end%获得仅含一条边的初始匹配Mwhile(1)for(i=1:m)x(i)=0;end%将记录X中点的标号和标记*for(i=1:n)y(i)=0;

11、end%将记录Y中点的标号和标记*for(i=1:m)pd=1;%寻找X中M的所有非饱和点for(j=1:n)if(M(i,j)pd=0;end;endif(pd)x(i)=-n-1;end;end%将X中M的所有非饱和点都给以标号0和标记*, 程序中用n+1表示0标号, 标号为负数时表示标记*pd=0;while(1)xi=0;for(i=1:m)if(x(i)<0)xi=i;break;end;end%假如X中存在一个既有标号又有标记*的点, 则任取X中一个既有标号又有标记*的点xiif(xi=0)pd=1;break;end%假如X中所有有标号的点都已去掉了标记*, 算法终止x(x

12、i)=x(xi)*(-1);%去掉xi的标记*k=1;for(j=1:n)if(A(xi,j)&y(j)=0)y(j)=xi;yy(k)=j;k=k+1;end;end%对与xi邻接且尚未给标号的yj都给以标号iif(k>1)k=k-1;for(j=1:k)pdd=1;for(i=1:m)if(M(i,yy(j)x(i)=-yy(j);pdd=0;break;end;end%将yj在M中与之邻接的点xk (即xkyjM), 给以标号j和标记*if(pdd)break;end;endif(pdd)k=1;j=yy(j);%yj不是M的饱和点while(1)P(k,2)=j;P(k,

13、1)=y(j);j=abs(x(y(j);%任取M的一个非饱和点yj, 逆向返回if(j=n+1)break;end%找到X中标号为0的点时结束, 获得M-增广路Pk=k+1;endfor(i=1:k)if(M(P(i,1),P(i,2)M(P(i,1),P(i,2)=0;%将匹配M在增广路P中出现的边去掉else M(P(i,1),P(i,2)=1;end;end%将增广路P中没有在匹配M中出现的边加入到匹配M中break;end;end;endif(pd)break;end;end%假如X中所有有标号的点都已去掉了标记*, 算法终止M%显示最大匹配M, 程序结束利用可行点标记求最佳匹配的算

14、法步骤如下:设G = ( X, Y, E , F )为完备的二部赋权图, L是其一个初始可行点标记, 通常取M是GL的一个匹配. 若X的每个点都是M的饱和点, 则M是最佳匹配. 否则取M的非饱和点uX, 令S = u , T = f , 转向. 记NL (S ) = v | uS, uvEL . 若NL ( S ) = T , 则GL没有完美匹配, 转向. 否则转向. 调整可行点标记, 计算aL = min L ( x ) + L ( y ) - F (x y) | xS, yY T .由此得新的可行顶点标记否则.H (v ) =令L = H, GL = GH , 重新给出GL的一个匹配M,

15、转向. 取yNL ( S ) T , 若y是M的饱和点, 转向. 否则, 转向. 设x yM, 则令S = S x , T = T y , 转向. 在GL中的u - y路是M -增广路, 记为P, 并令 M = MP, 转向.利用可行点标记求最佳匹配算法的MATLAB程序代码如下:n=4;A=4551224642335021;for(i=1:n)L(i,1)=0;L(i,2)=0;endfor(i=1:n)for(j=1:n)if(L(i,1)<A(i,j)L(i,1)=A(i,j);end;%初始可行点标记LM(i,j)=0;end;endfor(i=1:n)for(j=1:n)%生成

16、子图Glif(L(i,1)+L(j,2)=A(i,j)Gl(i,j)=1;elseGl(i,j)=0;end;end;endii=0;jj=0;for(i=1:n)for(j=1:n)if(Gl(i,j)ii=i;jj=j;break;end;endif(ii)break;end;end%获得仅含Gl的一条边的初始匹配MM(ii,jj)=1;for(i=1:n)S(i)=0;T(i)=0;NlS(i)=0;endwhile(1)for(i=1:n)k=1;for(j=1:n)if(M(i,j)k=0;break;end;endif(k)break;end;endif(k=0)break;end

17、%获得最佳匹配M, 算法终止S(1)=i;jss=1;jst=0;%S=xi, T=fwhile(1)jsn=0;for(i=1:jss)for(j=1:n)if(Gl(S(i),j)jsn=jsn+1;NlS(jsn)=j;%NL(S)=v|uS,uvELfor(k=1:jsn-1)if(NlS(k)=j)jsn=jsn-1;end;end;end;end;endif(jsn=jst)pd=1;%判断NL(S)=T?for(j=1:jsn)if(NlS(j)=T(j)pd=0;break;end;end;endif(jsn=jst&pd)al=Inf;%如果NL(S)=T, 计算al

18、, Inf为for(i=1:jss)for(j=1:n)pd=1;for(k=1:jst)if(T(k)=j)pd=0;break;end;endif(pd&al>L(S(i),1)+L(j,2)-A(S(i),j)al=L(S(i),1)+L(j,2)-A(S(i),j);end;end;endfor(i=1:jss)L(S(i),1)=L(S(i),1)-al;end%调整可行点标记for(j=1:jst)L(T(j),2)=L(T(j),2)+al;end%调整可行点标记for(i=1:n)for(j=1:n)%生成子图GLif(L(i,1)+L(j,2)=A(i,j)Gl

19、(i,j)=1;elseGl(i,j)=0;endM(i,j)=0;k=0;end;endii=0;jj=0;for(i=1:n)for(j=1:n)if(Gl(i,j)ii=i;jj=j;break;end;endif(ii)break;end;end%获得仅含Gl的一条边的初始匹配MM(ii,jj)=1;breakelse%NL(S)Tfor(j=1:jsn)pd=1;%取yNL(S)Tfor(k=1:jst)if(T(k)=NlS(j)pd=0;break;end;endif(pd)jj=j;break;end;endpd=0;%判断y是否为M的饱和点for(i=1:n)if(M(i,N

20、lS(jj)pd=1;ii=i;break;end;endif(pd)jss=jss+1;S(jss)=ii;jst=jst+1;T(jst)=NlS(jj);%S=Sx, T=Tyelse%获得Gl的一条M-增广路, 调整匹配Mfor(k=1:jst)M(S(k),T(k)=1;M(S(k+1),T(k)=0;endif(jst=0)k=0;endM(S(k+1),NlS(jj)=1;break;end;end;end;endMaxZjpp=0;for(i=1:n)for(j=1:n)if(M(i,j)MaxZjpp=MaxZjpp+A(i,j);end;end;endM%显示最佳匹配MMa

21、xZjpp%显示最佳匹配M的权, 程序结束从一个可行流f开始, 求最大流的Ford-Fulkerson标号算法的基本步骤: 标号过程 给发点vs以标号(+, +) , d s = +. 选择一个已标号的点x, 对于x的所有未给标号的邻接点y, 按下列规则处理:当yxE, 且f yx 0时, 令d y = min f yx , d x , 并给y以标号 ( x - , d y ).当xyE, 且f xyC xy时, 令d y = min C xy - f xy , d x , 并给y以标号 ( x + , d y ). 重复直到收点vt被标号或不再有点可标号时为止. 若vt得到标号, 说明存在一

22、条可增广链, 转调整过程; 若vt未得到标号, 标号过程已无法进行时, 说明f 已经是最大流. 调整过程 决定调整量d =d vt , 令u = vt . 若u点标号为( v +, d u ), 则以f vu + d 代替f vu ; 若u点标号为( v -, d u ), 则以 f vu - d 代替f vu. 若v = vs, 则去掉所有标号转重新标号; 否则令u = v, 转.算法终止后, 令已有标号的点集为S, 则割集(S, S c )为最小割, 从而Wf = C (S, S c ).例1 求图6-19所示网络的最大流.图6-19利用Ford-Fulkerson标号法求最大流算法的MA

23、TLAB程序代码如下:n=8;C=0543000000005300000003200000002000000004000000030000000500000000;%弧容量for(i=1:n)for(j=1:n)f(i,j)=0;end;end%取初始可行流f为零流for(i=1:n)No(i)=0;d(i)=0;end%No,d记录标号while(1)No(1)=n+1;d(1)=Inf;%给发点vs标号while(1)pd=1;%标号过程for(i=1:n)if(No(i)%选择一个已标号的点vifor(j=1:n)if(No(j)=0&f(i,j)<C(i,j)%对于未给标

24、号的点vj, 当vivj为非饱和弧时No(j)=i;d(j)=C(i,j)-f(i,j);pd=0;if(d(j)>d(i)d(j)=d(i);endelseif(No(j)=0&f(j,i)>0)%对于未给标号的点vj, 当vjvi为非零流弧时No(j)=-i;d(j)=f(j,i);pd=0;if(d(j)>d(i)d(j)=d(i);end;end;end;end;endif(No(n)|pd)break;end;end%若收点vt得到标号或者无法标号, 终止标号过程if(pd)break;end%vt未得到标号, f已是最大流, 算法终止dvt=d(n);t=

25、n;%进入调整过程, dvt表示调整量while(1)if(No(t)>0)f(No(t),t)=f(No(t),t)+dvt;%前向弧调整elseif(No(t)<0)f(No(t),t)=f(No(t),t)-dvt;end%后向弧调整if(No(t)=1)for(i=1:n)No(i)=0;d(i)=0; end;break;end%当t的标号为vs时, 终止调整过程t=No(t);end;end;%继续调整前一段弧上的流fwf=0;for(j=1:n)wf=wf+f(1,j);end%计算最大流量f%显示最大流wf%显示最大流量No%显示标号, 由此可得最小割, 程序结束设

26、网络G = ( V, E, C ), 取初始可行流 f 为零流, 求解最小费用流问题的迭代步骤: 构造有向赋权图 Gf = ( V, Ef , F ), 对于任意的vivjE , Ef , F的定义如下:当f ij = 0时, vivjEf , F ( vivj ) = bij ;当f ij = Cij时, vj viEf , F ( vj vi ) = -bij ;当0 f ij Cij时, vivjEf , F ( vivj ) = bij , vj viEf , F ( vj vi ) = -bij .转向. 求出有向赋权图Gf = (V, Ef , F )中发点vs到收点vt的最短路m

27、 , 若最短路m存在转向; 否则f是所求的最小费用最大流, 停止. 增流. 同求最大流的方法一样, 重述如下:令d = min d ij | vivjm, 重新定义流f = f ij为其它.f ij =如果Wf大于或等于预定的流量值, 则适当减少d 值, 使Wf等于预定的流量值, 那么 f 是所求的最小费用流, 停止; 否则转向.求解含有负权的有向赋权图G = ( V, E, F )中某一点到其它各点最短路的Ford算法.当vivjE时记wij = F (vivj), 否则取wii =0, wij = +(ij ). v1到vi的最短路长记为p ( i ), v1到vi的最短路中vi的前一个点

28、记为q ( i ). Ford算法的迭代步骤: 赋初值p (1) = 0, p ( i ) = +, q ( i ) = i, i = 2, 3, , n . 更新p ( i ), q ( i ). 对于i = 2, 3, , n和j = 1, 2, , n, 如果p ( i )p ( j ) + wji, 则令p ( i ) = p ( j ) , q ( i ) = j. 终止判断:若所有的p ( i )都无变化, 停止; 否则转向.在算法的每一步中, p ( i )都是从v1到vi的最短路长度的上界. 若不存在负长回路, 则从v1到vi的最短路长度是p ( i )的下界, 经过n -1次

29、迭代后p ( i )将保持不变. 若在第n次迭代后p ( i )仍在变化时, 说明存在负长回路.例2 在图6-22所示运输网络上, 求s到t的最小费用最大流, 括号内为(Cij , bij ).图6-22求最小费用最大流算法的MATLAB程序代码如下:n=5;C=0151600000131401101700000800000;%弧容量b=0410000061020300000200000;%弧上单位流量的费用wf=0;wf0=Inf;%wf表示最大流量, wf0表示预定的流量值for(i=1:n)for(j=1:n)f(i,j)=0;end;end%取初始可行流f为零流while(1)for(i=1:n)for(j=1:n)if(j=i)a(i,j)=Inf;end;end;end%构造有向赋权图for(i=1:n)for(j=1:n)if(C(i,j)>0&f(i,j)=0)a(i,j)=b(i,j);elseif(C(i,j)>0&f(i,j

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论