数学建模程序必用.docx
- 文档编号:6493906
- 上传时间:2023-01-07
- 格式:DOCX
- 页数:17
- 大小:53.89KB
数学建模程序必用.docx
《数学建模程序必用.docx》由会员分享,可在线阅读,更多相关《数学建模程序必用.docx(17页珍藏版)》请在冰豆网上搜索。
数学建模程序必用
图论算法及其MATLAB程序代码
求赋权图G=(V,E,F)中任意两点间的最短路的Warshall-Floyd算法:
设A=(aij)n×n为赋权图G=(V,E,F)的矩阵,当vivj∈E时aij=F(vivj),否则取aii=0,aij
=+∞(i≠j),dij表示从vi到vj点的距离,rij表示从vi到vj点的最短路中一个点的编号.
①赋初值.对所有i,j,dij=aij,rij=j.k=1.转向②
②更新dij,rij.对所有i,j,若dik+dkj<dij,则令dij=dik+dkj,rij=k,转向③.
③终止判断.若dii<0,则存在一条含有顶点vi的负回路,终止;或者k=n终止;否则
令k=k+1,转向②.
最短路线可由rij得到.
例1求图6-4中任意两点间的最短路.
解:
用Warshall-Floyd算法,MATLAB程序代码如下:
n=8;A=[0281InfInfInfInf
206Inf1InfInfInf
8607512Inf
1Inf70InfInf9Inf
Inf15Inf03Inf8
InfInf1Inf3046
InfInf29Inf403
InfInfInfInf8630];%MATLAB中,Inf表示∞
D=A;%赋初值
for(i=1:
n)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) R(i,j)=k;end;end;end%更新rij k%显示迭代步数 D%显示每步迭代后的路长 R%显示每步迭代后的路径 pd=0;fori=1: n%含有负权时 if(D(i,i)<0)pd=1;break;end;end%存在一条含有顶点vi的负回路 if(pd)break;end%存在一条负回路,终止程序 end%程序结束 图6-4 Kruskal避圈法: 将图G中的边按权数从小到大逐条考察,按不构成圈的原则加入到T 中(若有选择时,不同的选择可能会导致最后生成树的权数不同),直到q(T)=p(G)-1为 止,即T的边数=G的顶点数-1为止. Kruskal避圈法的MATLAB程序代码如下: n=8;A=[02810000 20601000 86075120 10700090 01500308 00103046 00290403 00008630]; 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;%临时变量 for(s=1: k-1)if(x(k)==x(s))kk=0;break;end;end%排除相同的正数 k=k+kk;end;end;end k=k-1%显示A中所有不同正数的个数 for(i=1: k-1)for(j=i+1: k)%将x中不同的正数从小到大排序 if(x(j) T(n,n)=0;%将矩阵T中所有的元素赋值为0 q=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)==x(s))T(i,j)=x(s);T(j,i)=x(s);%加入边到树T中 TT=T;%临时记录T while (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;end if(pd)T(i,j)=0;T(j,i)=0;%假如TT中有圈 elseq=q+1;end;end;end;end;end T%显示近似最小生成树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(如任取e∈E,则M={e}是一个匹配). ①令S=f,T=f,转向②. ②若M饱和X\S的所有点,则M是二部图G的最大匹配.否则,任取M的非饱和点 u∈X\S,令S=S∪{u},转向③. ③记N(S)={v|u∈S,uv∈E}.若N(S)=T,转向②.否则取y∈N(S)\T.若y是M 的饱和点,转向④,否则转向⑤. ④设xy∈M,则令S=S∪{x},T=T∪{y},转向③. ⑤u-y路是M-增广路,设为P,并令M=M⊕P,转向①.这里M⊕P=M∪P\M∩ P,是对称差. 由于计算M-增广路P比较麻烦,因此将迭代步骤改为: ①将X中M的所有非饱和点(不是M中某条边的端点)都给以标号0和标记*,转向②. ②若X中所有有标号的点都已去掉了标记*,则M是G的最大匹配.否则任取X中一 个既有标号又有标记*的点xi,去掉xi的标记*,转向③. ③找出在G中所有与xi邻接的点yj(即xiyj∈E),若所有这样的yj都已有标号,则转向 ②,否则转向④. ④对与xi邻接且尚未给标号的yj都给定标号i.若所有的yj都是M的饱和点,则转向⑤, 否则逆向返回.即由其中M的任一个非饱和点yj的标号i找到xi,再由xi的标号k找到yk,⋯, 最后由yt的标号s找到标号为0的xs时结束,获得M-增广路xsyt⋯xiyj,记P={xsyt,⋯, xiyj},重新记M为M⊕P,转向①. ⑤将yj在M中与之邻接的点xk(即xkyj∈M),给以标号j和标记*,转向②. 例1求图6-9中所示的二部图G的最大匹配. 匈牙利算法的MATLAB程序代码如下: m=5;n=5;A=[01100 11011 01100 01100 00011]; M(m,n)=0; for(i=1: m)for(j=1: n)if(A(i,j))M(i,j)=1;break;end;end%求初始匹配M if(M(i,j))break;end;end%获得仅含一条边的初始匹配M while (1) for(i=1: m)x(i)=0;end%将记录X中点的标号和标记* for(i=1: n)y(i)=0;end%将记录Y中点的标号和标记* for(i=1: m)pd=1;%寻找X中M的所有非饱和点 for(j=1: n)if(M(i,j))pd=0;end;end if(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中一个既有标号又有标记*的点xi if(xi==0)pd=1;break;end%假如X中所有有标号的点都已去掉了标记*,算法终止 x(xi)=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都 给以标号i if(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(即xkyj∈M),给以标号j和标记* if(pdd)break;end;end if(pdd)k=1;j=yy(j);%yj不是M的饱和点 while (1)P(k,2)=j;P(k,1)=y(j);j=abs(x(y(j)));%任取M的一个非饱和点yj,逆向返回 if(j==n+1)break;end%找到X中标号为0的点时结束,获得M-增广路P k=k+1;end for(i=1: k)if(M(P(i,1),P(i,2)))M(P(i,1),P(i,2))=0;%将匹配M在增广路P中出现的边 去掉 elseM(P(i,1),P(i,2))=1;end;end%将增广路P中没有在匹配M中出现的边加入 到匹配M中 break;end;end;end if(pd)break;end;end%假如X中所有有标号的点都已去掉了标记*,算法终止 M%显示最大匹配M,程序结束 图6-9 利用可行点标记求最佳匹配的算法步骤如下: 设G=(X,Y,E,F)为完备的二部赋权图,L是其一个初始可行点标记,通常取 . ()0, ()max{()|}, yY xX Ly LxFxyyY ∈ ∈ ⎩⎨⎧ = =∈ M是GL的一个匹配. ①若X的每个点都是M的饱和点,则M是最佳匹配.否则取M的非饱和点u∈X,令S ={u},T=f,转向②. ②记NL(S)={v|u∈S,uv∈EL}.若NL(S)=T,则GL没有完美匹配,转向③.否则转 向④. ③调整可行点标记,计算 aL=min{L(x)+L(y)-F(xy)|x∈S,y∈Y\T}. 由此得新的可行顶点标记 H(v)=, (), (), (), vT vS Lv Lva Lva L L ∈ ∈ ⎪⎩ ⎪⎨ ⎧ + - 令L=H,GL=GH,重新给出GL的一个匹配M,转向①. ④取y∈NL(S)\T,若y是M的饱和点,转向⑤.否则,转向⑥. ⑤设xy∈M,则令S=S∪{x},T=T∪{y},转向②. ⑥在GL中的u-y路是M-增广路,记为P,并令M=M⊕P,转向①. 利用可行点标记求最佳匹配算法的MATLAB程序代码如下: n=4;A=[4551 2246 4233 5021]; for(i=1: n)L(i,1)=0;L(i,2)=0;end for(i=1: n)for(j=1:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数学 建模 程序