配流02—DIAL算法(改进)

欢迎使用Markdown编辑器写博客

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
配流结果如图所示:

这里写图片描述

======================================================================================
<程序运行完毕>

说明:显然改进的算法更符合实际情况,因为人们通常不会因为需要绕一点点路而长时间等待。

猜你喜欢

转载自blog.csdn.net/LZX19901012/article/details/80928072
今日推荐