此模型用到的程序。
M=inf;
a=矩阵(方阵);zusan=D(fenzu3,fenzu3);
model:
sets:
city / 1.. 17/: u;
link( city, city):
dist, ! 距离矩阵;
x;
endsets
n = @size( city);
data: !距离矩阵,它并不需要是对称的;
dist =@ole('E:\完全图.xls','dist4');//dist是floyd算法产生的方阵;例如:zuyi ,zuer,zusan;
!随机产生,这里可改为你要解决的问题的数据;
enddata
!目标函数;
min = @sum( link: dist * x);
@FOR( city( K):
!进入城市K;
@sum( city( I)| I #ne# K: x( I, K)) = 1;
!离开城市K;
@sum( city( J)| J #ne# K: x( K, J)) = 1;
);
!保证不出现子圈;
@for(city(I)|I #gt# 1:
@for( city( J)| J#gt#1 #and# I #ne# J:
u(I)-u(J)+n*x(I,J)<=n-1);
);
!限制u的范围以加速模型的求解,保证所加限制并不排除掉TSP问题的最优解;
@for(city(I) | I #gt# 1: u(I)<=n-2 );
!定义X为0\1变量;
@for( link: @bin( x));
end
//用此程序需改两处,第一: city / 1.. 17/: u;中的17改成所算矩阵的维数;
第二:data.dist =@ole('E:\完全图.xls','dist4');//dist是floyd算法产生的方阵即可。
%floyd算法通用程序,输入a为赋权邻接矩阵
%输出为距离矩阵D,和最短路径矩阵path
function [D,path]=floyd(a)
n=size(a,1);
D=a;
path=zeros(n,n);
for i=1:n
for j=1:n
if D(i,j)~=inf
path(i,j)=j;
end
end
end
for k=1:n
for i=1:n
for j=1:n
if D(i,k)+D(k,j)
path(i,j)=path(i,k);
end
end
end
end
%配合floyd算法的后续程序,s为源点,t为宿点
%L为长度,R为路由
function [L,R]=router(D,path,s,t)
L=zeros(0,0);
R=s;
while 1
if s==t
L=fliplr(L);
L=[0,L];
return
end
L=[L,D(s,t)];
R=[R,path(s,t)];
s=path(s,t);
end
//如何用:
首先对path的说明:这里的D是用floyd算出的距离矩阵,path是最短路径矩阵。
path是这样的,他的结果是任意两点最短距离所经过的最后一个中间节点。比如
说是path[2,10]=7;这就说明2号节点到10号节点距离时,当添加7号节点能够缩
短他们之间的距离,当然7号节点是最后一个能缩短他们之间距离的中间节点。
//router何时用:比如说对于灾难巡视模型,一个人走完所有村庄,经过的路程最短,(类似TSP问题)
这个问题你可以用hamilton圈解决,先把一般图转化为完全图,因为完全图一定可以找到hamiltom圈,找到之后形成一条回路,比如
1-2-3-4-5-6;但在原图(一般图)中2-3没有边相连,这时你需要,找出2-3最短路程的的路径,这时可以用调用 [L,R]=router(D,path,2,3),
R就是路径(走法)