图论基础知识汇总(适合建模) 联系客服

发布时间 : 星期二 文章图论基础知识汇总(适合建模)更新完毕开始阅读c182da290066f5335a812165

用矩阵an?n(n为顶点个数)存放各边权的邻接矩阵,行向量pb、indexindex2、1、

d分别用来存放P标号信息、标号顶点顺序、标号顶点索引、最短通路的值。其中分

?1当第i顶点已标号; pb(i)??0当第i顶点未标号?index2(i) 存放始点到第i点最短通路中第i顶点前一顶点的序号; d(i) 存放由始点到第i点最短通路的值。

求第一个城市到其它城市的最短路径的Matlab程序如下: clear; clc;

M=10000;

a(1,:)=[0,50,M,40,25,10];

a(2,:)=[zeros(1,2),15,20,M,25]; a(3,:)=[zeros(1,3),10,20,M]; a(4,:)=[zeros(1,4),10,25]; a(5,:)=[zeros(1,5),55]; a(6,:)=zeros(1,6); a=a+a';

pb(1:length(a))=0;pb(1)=1;index1=1;index2=ones(1,length(a)); d(1:length(a))=M;d(1)=0;temp=1; while sum(pb)

d(tb)=min(d(tb),d(temp)+a(temp,tb)); tmpb=find(d(tb)==min(d(tb))); temp=tb(tmpb(1)); pb(temp)=1;

index1=[index1,temp];

index=index1(find(d(index1)==d(temp)-a(temp,index1))); if length(index)>=2 index=index(1); end

index2(temp)=index; end

d, index1, index2

例、用迪克斯特拉算法求出权图中u0 到un 的距离d(u0 ,~S2)及最短路l

-9-

n

解:(1)S0 ={ u0},~S0 ={ u1 ,u2 ,u3,u4 ,u5 ,u6 ,u7}, ∵min{1,2,∞,∞,4,8,7}=1,

∴d(u0 ,u1 )=1,l1 =(u0 ,u1 ),| l1|=1. (2)S1 ={u0 , u1},~S1 ={u2 ,u3 ,u4 ,u5 ,u6 ,u7},

∵min{2,∞,∞,4,8,7,1+2,1+3,1+∞,1+∞,1+7,1+∞}=2, ∴d(u0 ,u2 )=2,l2=(u0 ,u2 ),| l2|=2. (3)S2 ={ u0 ,u1 ,u2},~ S2 ={ u3 ,u4 ,u5 ,u6 ,u7},

∵min{∞, ∞,4,8,7,1+3,1+∞,1+∞,1+7,1+∞,2+1,2+∞,2+∞,2+∞,2+5}=3,

∴d(u0 ,u3)=3, l3 =(u0 ,u2 , u3),| l3|=3.

(4) S3 ={ u0 ,u1 ,u2 , u3}, ~S3 ={ u4 ,u5 ,u6 ,u7},

∵min{∞, 4,8,7,1+∞,1+∞,1+∞,1+5,2+∞,2+∞,2+∞,2+5,3+6,3+∞,3+

∞,3+3}=4,

∴d(u0 ,u5)=4, l4=(u0 ,u5 ),| l4|=4.

(5) S4 ={ u0 ,u1 ,u2 , u3 , u5}, ~S5 ={ u4 , u6 , u7},

∵min{∞,8,7,1+∞,1+7,1+∞,2+∞,2+∞,2+5,3+6,3+

∞,3+3,4+6,4+2,4+3}=6,

∴d(u0 ,u7)=6, l5=(u0 ,u2 ,u3 ,u7),| l5|=6.

(6) S5 ={ u0 ,u1 ,u2 , u3 , u5, u7}, ~S5 ={ u4 , u6 },

∵min{∞,8,1+∞,1+7, 2+∞,2+∞, 3+6,3+∞, 4+6,4+2,6+4,6+∞}=6, ∴d(u0 ,u6)=6, l6=(u0 ,u5, u6),| l6|=6.

(7) S6?{u0,u1,u2,u3,u5,u7,u6},~S6?{u4},

?min{?,1??,2??,3?6,4?6,6?4,6?4}?9

?d(u0,u4)?9,l7?(u0,u2,u3,u4},|l7|?9

故从

-10-

u0 到其余各点的最短距离分别为:

l1?(u0,u1),l2?(u0,u2),l3?(u0,u2,u3),

l4?(u0,u5),l5?(u0,u2,u3,u7),l6?(u0,u5,u6),l7?(u0,u2,u3,u4)

MATLAB函数

function [l,z]=Dijkstra(W) n = size (W,1); for i = 1 :n l(i)=W(1,i); z(i)=1; end i=1;

while i<=n for j =1 :n

if l(i)>l(j)+W(j,i) l(i)=l(j)+W(j,i); z(i)=j; if j

W =[ 0 2 1 8 Inf Inf Inf Inf 2 0 Inf 6 1 Inf Inf Inf

1 Inf 0 7 Inf Inf 9 Inf

8 6 7 0 5 1 2 Inf Inf 1 Inf 5 0 3 Inf 9 Inf Inf Inf 1 3 0 4 6 Inf Inf 9 2 Inf 4 0 3

Inf Inf Inf Inf 9 6 3 0 ];

Dijkstra(G,D,s){

//用Dijkstra算法求有向网G的源点s到各顶点的最短路径长度 //以下是初始化操作

S={s};D[s]=0; //设置初始的红点集及最短距离 for( all i∈ V-S )do //对蓝点集中每个顶点i

D[i]=G[s][i]; //设置i初始的估计距离为w //以下是扩充红点集

for(i=0;i

D[k]=min{D[i]:all i V-S}; //在当前蓝点集中选估计距离最小的顶点k

if(D[k]等于∞)

return; //蓝点集中所有蓝点的估计距离均为∞时, //表示这些顶点的最短路径不存在。 S=S∪{k}; //将蓝点k涂红后扩充到红点集

-11-

for( all j∈V-S )do //调整剩余蓝点的估计距离 if(D[j]>D[k]+G[k][j])

//新红点k使原D[j]值变小时,用新路径的长度修改D[j], //使j离s更近。

D[j]=D[k]+G[k][j]; } }

3.2 每对顶点之间的最短路径

计算赋权图中各对顶点之间最短路径,显然可以调用Dijkstra算法。具体方法是:每次以不同的顶点作为起点,用Dijkstra算法求出从该起点到其余顶点的最短路径,反复执行n次这样的操作,就可得到从每一个顶点到其它顶点的最短路径。这种算法的时间复杂度为O(n3)。第二种解决这一问题的方法是由Floyd. R.W提出的算法,称之为Floyd算法。

假设图G权的邻接矩阵为A0,

?a11?aA0??21????an1a12a22?an2?a1n??a2n??

?????ann?来存放各边长度,其中:

aii?0 i?1,2,?,n;

aij?? i,j之间没有边,在程序中以各边都不可能达到的充分大的数代替; aij?wij wij是i,j之间边的长度,i,j?1,2,?,n。

对于无向图,A0是对称矩阵,aij?aji。

Floyd算法的基本思想是:递推产生一个矩阵序列A0,A1,?,Ak,?,An,其中

Ak(i,j)表示从顶点vi到顶点vj的路径上所经过的顶点序号不大于k的最短路径长

度。

计算时用迭代公式:

Ak(i,j)?min(Ak?1(i,j),Ak?1(i,k)?Ak?1(k,j))

k是迭代次数,i,j,k?1,2,?,n。

最后,当k?n时,An即是各顶点之间的最短通路值。

例10 用Floyd算法求解例1。

矩阵path用来存放每对顶点之间最短路径上所经过的顶点的序号。Floyd算法的Matlab程序如下: clear; clc;

M=10000;

a(1,:)=[0,50,M,40,25,10];

a(2,:)=[zeros(1,2),15,20,M,25]; a(3,:)=[zeros(1,3),10,20,M]; a(4,:)=[zeros(1,4),10,25];

-12-