最小树最短路程序Word下载.docx
《最小树最短路程序Word下载.docx》由会员分享,可在线阅读,更多相关《最小树最短路程序Word下载.docx(15页珍藏版)》请在冰豆网上搜索。
![最小树最短路程序Word下载.docx](https://file1.bdocx.com/fileroot1/2023-2/4/1fd81562-28d5-48c1-85fb-0a0f6a4a87a5/1fd81562-28d5-48c1-85fb-0a0f6a4a87a51.gif)
v2=index(2,flag);
ifv1~=v2
result=[result,data(:
flag)];
end
index(find(index==v2))=v1;
data(:
flag)=[];
index(:
end
result
Prim算法(顶点扩充法)
%清空命令窗口,清空内存
a=zeros(7);
a(2,4)=65;
a(4,5)=50;
a(5,6)=70;
a=a+a'
a(a==0)=inf;
p=1;
tb=2:
length(a);
%边的个数比顶点数少一
whilesize(result,2)~=length(a)-1
temp=a(p,tb)
temp=temp(:
)%将temp转化成一维列数组
d=min(temp)
[jb,kb]=find(a(p,tb)==d);
j=p(jb
(1));
k=tb(kb
(1));
result=[result,[j;
k;
d]];
p=[p,k];
tb(find(tb==k))=[];
%将顶点k从选择顶点中去掉
从起点sb到终点db通用的Dijkstra标号算法程序
function[mydistance,mypath]=mydijkstra(a,sb,db);
%输入:
a—邻接矩阵,a(i,j)是指i到j之间的距离,可以是有向的
%sb—起点的标号,db—终点的标号
%输出:
mydistance—最短路的距离,mypath—最短路的路径
n=size(a,1);
visited(1:
n)=0;
distance(1:
n)=inf;
distance(sb)=0;
%起点到各顶点距离的初始化
visited(sb)=1;
u=sb;
%u为最新的P标号顶点
parent(1:
%前驱顶点的初始化
fori=1:
n-1
id=find(visited==0);
%查找未标号的顶点
forv=id
ifa(u,v)+distance(u)<
distance(v)
distance(v)=distance(u)+a(u,v);
%修改标号值
parent(v)=u;
end
temp=distance;
temp(visited==1)=inf;
%已标号点的距离换成无穷
[t,u]=min(temp);
%找标号值最小的顶点
visited(u)=1;
%标记已经标号的顶点
mypath=[];
ifparent(db)~=0%如果存在路!
t=db;
mypath=[db];
whilet~=sb%从终点db开始回溯
p=parent(t);
mypath=[pmypath];
t=p;
mydistance=distance(db);
例题某公司在六个城市
中有分公司,从
到
的直接航程票价记在下述矩阵的(i,j)位置上。
(∞表示无直接航路),请帮助该公司设计一张城市
到其它城市间的票价最便宜的路线图。
LINGO的Floyd算法程序如下
model:
sets:
nodes/c1..c6/;
link(nodes,nodes):
w,path;
!
path标志最短路径上走过的顶点;
endsets
data:
path=0;
w=0;
enddata
calc:
w(1,2)=50;
w(1,4)=40;
w(1,5)=25;
w(1,6)=10;
w(2,3)=15;
w(2,4)=20;
w(2,6)=25;
w(3,4)=10;
w(3,5)=20;
w(4,5)=10;
w(4,6)=25;
w(5,6)=55;
@for(link(i,j):
w(i,j)=w(i,j)+w(j,i));
@for(link(i,j)|i#ne#j:
w(i,j)=@if(w(i,j)#eq#0,10000,w(i,j)));
@for(nodes(k):
@for(nodes(i):
@for(nodes(j):
tm=@smin(w(i,j),w(i,k)+w(k,j));
path(i,j)=@if(w(i,j)#gt#tm,k,path(i,j));
w(i,j)=tm)));
endcalc
求解最短路问题的数学规划法
取决策变量为
,当
,说明弧
位于顶点
到顶点
的最短路上,否则
。
s.t
例在下图中,用点表示城市,现有
共7个城市。
点与点之间的连线表示城市间有道路相连。
连线旁的数字表示道路的长度。
现计划从城市
到城市
铺设一条天然气管道,请设计出最小长度管道铺设方案。
基于数学规划求解最短路的LINGO代码
cities/A,B1,B2,C1,C2,C3,D/;
roads(cities,cities)/AB1,AB2,B1C1,B1C2,B1C3,B2C1,
B2C2,B2C3,C1D,C2D,C3D/:
w,x;
w=24331231134;
n=@size(cities);
城市的个数;
min=@sum(roads:
w*x);
@for(cities(i)|i#ne#1#and#i#ne#n:
@sum(roads(i,j):
x(i,j))=@sum(roads(j,i):
x(j,i)));
@sum(roads(i,j)|i#eq#1:
x(i,j))=1;
@sum(roads(i,j)|j#eq#n:
求最大流问题的Ford-Fulkerson标号算法
function[fwfNo]=fofuf(C,f1)
%C表示弧上的容量
%f1表示弧上现有的流量函数,默认情况下为0
%f表示最大流
%wf表示最大流量
%No标号函数,由此可得最小割
%注:
待求最大流的源为第一个顶点,汇为最后一个顶点
n=length(C)
ifnargin==1;
f=zeros(n,n);
else
f=f1;
No=zeros(1,n);
d=zeros(1,n);
while
(1)
No
(1)=n+1;
d
(1)=Inf;
%给发点vs标号
while
(1)%标号过程
pd=1;
for(i=1:
n)
if(No(i))%选择一个已标号的vi
for(j=1:
if(No(j)==0&
f(i,j)<
C(i,j))%对于未给标号的点vj,当vi-vj为非饱和弧时
No(j)=i;
d(j)=C(i,j)-f(i,j);
pd=0;
if(d(j)>
d(i))
d(j)=d(i);
elseif(No(j)==0&
f(j,i)>
0)%对于未给标号的点vj,当vi-vj为非零流弧时
No(j)=-i;
d(j)=C(j,i)
if(No(n)|pd)
break;
end%若收点vt得到标号或者无法标号,则终止标号过程
if(pd)
end%vt未得到标号,f已是最大流,算法终止
dvt=d(n);
t=n;
%进入调整过程,dvt表示调整量
if(No(t)>
0)
f(No(t),t)=f(No(t),t)+dvt;
%前向弧调整
elseif(No(t)<
f(No(t),t)=f(No(t),t)-dvt;
%后向弧调整
if(No(t)==1)
No(i)=0;
d(i)=0;
End
break
end%当t的标号为vs时,终止调整过程
t=No(t);
end%继续调整前一段弧上的流f
wf=0;
n)%计算最大流量
wf=wf+f(1,j);
f;
%显示最大流
wf;
%显示最大流量
No;
%显示标号,由此可得最小割
例求下图所示网络的最大流
C=[05430000;
00005300;
00000320;
00000020;
00000004;
00000003;
00000005;
00000000];
[qwe]=fofuf(C)
最小费用最大流问题
function[fwfzwf]=BGf(C,b)
%C表示弧容量矩阵
%b表示弧上单位流量的费用
%f表示最小费用最大流矩阵
%zwf表示最小费用
n=size(C,2);
wf0=Inf;
%wf表示最大流量,wf0表示预定的流量值
%取初始可行流f为零流
a=ones(n,n)*inf;
a(i,i)=0;
end%构造有向赋权图a
if(C(i,j)>
0&
f(i,j)==0)
a(i,j)=b(i,j);
elseif(C(i,j)>
f(i,j)==C(i,j))
a(j,i)=-b(i,j);
a(j,i)=b(i,j);
for(i=2:
p(i)=Inf;
s(i)=i;
end%用Floyd算法求最短路,赋初值
for(k=1:
%求有向赋权图中vs到vt的最短路
if(p(i)>
p(j)+a(j,i))
p(i)=p(j)+a(j,i);
s(i)=j;
end%求最短路的Floyd算法结束
if(p(n)==Inf)
end%不存在vs到vt的最短路,算法终止
%注意在求最小费用最大流时构造有向赋权图中不会含
%负权回路,所以不会出现k=n
dvt=Inf;
while
(1)%通过回溯计算调整量
if(a(s(t),t)>
dvtt=C(s(t),t)-f(s(t),t);
%前向弧调整量
elseif(a(s(t),t)<
dvtt=f(t,s(t));
end%后向弧调整量
if(dvt>
dvtt)
dvt=dvtt;
if(s(t)==1)
end%当t的标号为vs时,终止计算调整量
t=s(t);
if(wf+dvt>
=wf0)
dvt=wf0-wf;
end%如果最大流量大于或等于预定的流量值
while
(1)%调整过程
if(a(s(t),t)>
f(s(t),t)=f(s(t),t)+dvt;
f(t,s(t))=f(t,s(t))-dvt;
end%后向弧调整
end%如果最大流量达到预定的流量值
end%计算最大流量
zwf=0;
zwf=zwf+b(i,j)*f(i,j);
end%计算最小费用
%最小费用最大流
例求下图所示网络的最小费用最大流,弧旁
中的
分别表示顶点i到顶点j间弧的费用和容量。
b=[0106300;
004003;
0000124;
005020;
000005;
000000];
c=[0127800;
008005;
0000107;
009070;
000008;
[fwfzwf]=BGf(c,b)