function dialsuanfaxishujuzhen(T)
%程序说明
clc
disp(‘======================================================================================‘);
disp(‘ 《基于LOGIT的STOCH配流法——改进的dial算法》‘);
disp(‘运行环境:MATLAB 8.3.0.532 ‘);
disp(‘制 作 人:兰州交通大学 刘志祥‘);
disp(‘Q Q:531548824‘);
fprintf(‘说 明:本程序用于进行静态配流,在经典Dial算法的基础上进行修改,重新定义了有效路径,使得在用\n户的容忍绕路范围内比原来多走h倍路(一般情况下0<h<1,针对论断T(i,j)),即最多不超过2倍的路程,若\nh=0则等同经典算法.dial算法分四大步骤:一是求最短路,二是求边权似然数,三是求路权,四是配流\n‘);
disp(‘======================================================================================‘);
disp(‘按任意键继续...‘);
pause;
%数据获取,人机交互
disp(‘ ***请按照提示输入以下参数***‘);
Q=input(‘总 需 求 量:‘);
thita=input(‘参 数 thita:‘);
h=input(‘容忍绕路倍数:‘);
r=input(‘起 点:‘);
s=input(‘终 点:‘);
n=size(T,1);
%初始化
L=zeros(n,n);
W=zeros(n,n);
X=zeros(n,n);
%求最短距离矩阵及最短路径
disp(‘step1->:求最短距离,其中‘);
disp(‘---------------------------------------------------------------------------------------‘);
disp(‘ R—起点r到其他点的最短距离‘);
disp(‘ S—其他点到终点s的最短距离‘);
disp(‘按任意键继续...‘);
pause;
for i=1:n
for j=1:n
if T(i,j)==inf
T(i,j)=0;
end
end
end
T=sparse(T);
Tmin=graphallshortestpaths(T);
[dist,path]=graphshortestpath(T,r,s);
disp(‘________________________________________________________________‘);
R=Tmin(r,:)
S=Tmin(:,s)‘%注意因为方向性,这里作转置处理
disp(‘________________________________________________________________‘);
%画出初始图及最短路,边权为阻抗值t
disp(‘初始图及最短路径(红色)如图所示:‘);
chushitu=view(biograph(T,[],‘showW‘,‘ON‘));
set(chushitu.Nodes(path),‘Color‘,[1 0 0]);
edges=getedgesbynodeid(chushitu,get(chushitu.Nodes(path),‘ID‘));
set(edges,‘Linecolor‘,[1 0 0]);
disp(‘最短路径:‘);
path
disp(‘最短路距离:‘);
dist
%找上游节点和下游节点(显然up和down互为转置——对称,因为若j是i的下游节点,则i必是j的上游节点)
for i=1:n
for j=1:n
if T(i,j)>0
down(i,j)=1;
up(j,i)=1;
else
down(i,j)=0;
up(j,i)=0;
end
end
end
down=sparse(down);
up=sparse(up);
%计算边权
disp(‘step2->:计算边权似然值(任意键继续)‘);
disp(‘---------------------------------------------------------------------------------------‘);
pause;
for i=1:n
for j=1:n
if down(i,j)
if R(i)+T(i,j)-R(j)<(1+h)*T(i,j)&&S(j)+T(i,j)-S(i)<(1+h)*T(i,j)
P=1;
else
P=0;
end
L(i,j)=P*exp(thita*(R(j)-R(i)-T(i,j)));
end
end
end
L=sparse(L)
disp(‘边权如图所示:‘);
bianquantu=view(biograph(L,[],‘showW‘,‘ON‘));
%计算路权
disp(‘step3->:计算路权(任意键继续)‘);
disp(‘---------------------------------------------------------------------------------------‘);
pause;
for i=1:n
for j=1:n
if down(i,j)~=0
if R(i)+T(i,j)-R(j)<(1+h)*T(i,j)&&S(j)+T(i,j)-S(i)<(1+h)*T(i,j)
if i==r
W(i,j)=L(i,j);
else
W(i,j)=L(i,j)*(up(i,:)*W(:,i));
%这是核心句,先找到上游节点,再写出上游节点到i的W值(若还没有,则递归直到能够算出),请仔细查阅路权的算法好好理解。
end
end
end
end
end
W=sparse(W)
disp(‘路权如图所示:‘);
luquantu=view(biograph(W,[],‘showW‘,‘ON‘));
%配流
disp(‘step4->:配流(任意键继续)‘);
disp(‘------------------------------------------------------------------------------------------‘);
pause;
for i=n:-1:1
for j=n:-1:1
if down(i,j)==1
if R(i)+T(i,j)-R(j)<(1+h)*T(i,j)&&S(j)+T(i,j)-S(i)<(1+h)*T(i,j)
if j==s
X(i,j)=Q*W(i,j)/((up(j,:)*W(:,j)));
else
X(i,j)=X(j,:)*down(j,:)‘*W(i,j)/(up(j,:)*W(:,j));
%注意X(j,:)是1*n行向量,down(j,:)是1*n行向量,因此要将down向量转置为1*n的列向量才能相乘。
end
end
end
end
end
X=sparse(X)
disp(‘配流结果如图所示:‘);
peiliutu=view(biograph(X,[],‘showW‘,‘ON‘));
disp(‘======================================================================================‘);
disp(‘<程序运行完毕>‘);
例:某路网如图所示,阻抗已标注于边上(这里阻抗用距离值表示),需求为1000,起点为v1,终点为v9,θ=1,用户可容忍的绕路倍数为0.5.请用改进的ial算法进行配流。
解:(1)写权值矩阵
quanzhijuzhen=[
0 2 Inf 2 Inf Inf Inf Inf Inf
Inf 0 2 Inf 2 Inf Inf Inf Inf
Inf Inf 0 Inf Inf 2 Inf Inf Inf
Inf Inf Inf 0 1 Inf 2 Inf Inf
Inf Inf Inf Inf 0 1 Inf 2 Inf
Inf Inf Inf Inf Inf 0 Inf Inf 2
Inf Inf Inf Inf Inf Inf 0 2 Inf
Inf Inf Inf Inf Inf Inf Inf 0 2
Inf Inf Inf Inf Inf Inf Inf Inf 0];
(2)带入程序(格式整理后输出如下)
>> dialsuanfaxishujuzhen(quanzhijuzhen)
======================================================================================
《基于LOGIT的STOCH配流法——改进的dial算法》
运行环境:MATLAB 8.3.0.532
制 作 人:兰州交通大学 刘志祥
Q Q:531548824
说 明:本程序用于进行静态配流,在经典Dial算法的基础上进行修改,重新定义了有效路径,使得在用
户的容忍绕路范围内比原来多走h倍路(一般情况下0<h<1,针对论断T(i,j)),即最多不超过2倍的路程,若
h=0则等同经典算法.dial算法分四大步骤:一是求最短路,二是求边权似然数,三是求路权,四是配流
======================================================================================
按任意键继续...
***请按照提示输入以下参数***
总 需 求 量:1000
参 数 thita:1
容忍绕路倍数:0.5
起 点:1
终 点:9
step1->:求最短距离,其中
---------------------------------------------------------------------------------------
R—起点r到其他点的最短距离
S—其他点到终点s的最短距离
按任意键继续...
________________________________________________________________
R =
0 2 4 2 3 4 4 5 6
S =
6 5 4 4 3 2 4 2 0
________________________________________________________________
初始图及最短路径(红色)如图所示:
最短路径:
path =
1 4 5 6 9
最短路距离:
dist =
6
step2->:计算边权似然值(任意键继续)
---------------------------------------------------------------------------------------
L =
(1,2) 1.0000
(2,3) 1.0000
(1,4) 1.0000
(2,5) 0.3679
(4,5) 1.0000
(3,6) 0.1353
(5,6) 1.0000
(4,7) 1.0000
(5,8) 1.0000
(7,8) 0.3679
(6,9) 1.0000
(8,9) 0.3679
边权如图所示:
step3->:计算路权(任意键继续)
---------------------------------------------------------------------------------------
W =
(1,2) 1.0000
(2,3) 1.0000
(1,4) 1.0000
(2,5) 0.3679
(4,5) 1.0000
(3,6) 0.1353
(5,6) 1.3679
(4,7) 1.0000
(5,8) 1.3679
(7,8) 0.3679
(6,9) 1.5032
(8,9) 0.6386
路权如图所示:
step4->:配流(任意键继续)
------------------------------------------------------------------------------------------
X =
(1,2) 298.1420
(2,3) 63.1887
(1,4) 701.8580
(2,5) 234.9533
(4,5) 638.6693
(3,6) 63.1887
(5,6) 638.6693
(4,7) 63.1887
(5,8) 234.9533
(7,8) 63.1887
(6,9) 701.8580
(8,9) 298.1420
配流结果如图所示:
======================================================================================
<程序运行完毕>
说明:显然改进的算法更符合实际情况,因为人们通常不会因为需要绕一点点路而长时间等待。
版权声明:博主文章可以被非商用转载,但请务必注明出处,因水平有限,难免出错,在此免责。