綜合算法03—FrankWolfe_BPR配流算法

%% 算法符號及程序說明
%說明:本程序爲採用美國聯邦公路阻抗函數BPR時的frankwolfe算法,考慮了換乘(已經將等待時
%間考慮在內並在K短路的確定過程中計算)及擁擠附加時間,在路網情況已知時配流並求出費用值。
%計算條件:根據K短路算法計算出考慮換乘的路徑-路段關係矩陣和邊權。
%缺點:BPR函數或許不能準確的描述軌道交通系統的路段阻抗,列車的能力也不能用程序中那麼簡單
%代替(但是,這無關緊要,暫時可以認爲是正確的,後續可以用已知的路段函元胞和能力矩陣替換)
%下一步研究方向:網絡配流--所有OD對之間的配流。
%==============================================================================
%符號體系:
%   Q-OD需求量
%  Cs-路段額定能力(列車座位數)
%Cmax-路段極限能力(列車座位數+人均面積達標的時的站立人數)
%   t-路段阻抗函數(值)
%numf-起點到終點的路徑數量(自己按照K短路算法進行定義)
%numx-網絡中的路段數量(直接連接兩節點的邊數,包含所有路段)
%   W-邊權(0流量時的阻抗),在該程序中,通過調用K短路換乘算法自動標號索引得出。
%Transfer_time-某路徑的路段換乘時間
%   G-路段擁擠附加時間
%   A-一般擁擠放大係數(介於0到等車時間之間),可以看作一個綜合係數,指部分人選擇擠車,部分人選擇下趟列車。
%   B-特別擁擠放大係數(等車時間,與發車頻率對應),如果過度擁擠,則無法乘車的人必須等待後車到來,等1趟時間加B,等2趟,時間加2B,等幾趟由無法乘車人數與極限能力決定。
%   L-路網路線矩陣(0-1矩陣,表示路線與路段的關係,1爲包含,0爲不包含)
% Mxf-路徑與路段的關係矩陣(每一行表示一個路徑,矩陣值爲1表示經過該路段,否則不經過該路段)
%cont-當前配流次數
%Ckrs-路徑配流結果(更新後的阻抗值)
%  X1-當前配流結果
%  Y1-輔助流量
%   S-搜索方向
%lmbda-搜索步長
%  X2-新的迭代點
%   Z-目標函數(通用配流目標函數,可認爲是費用)
%==============================================================================
clear all
format
clc
warning off
disp('========================================================================');
disp('                           《FrankWolfe_BPR配流算法》');
disp('運行環境:MATLAB 8.3.0.532 ');
disp('制 作 人:蘭州交通大學   劉志祥');
disp('完成時間:2015-12-30');
disp('Q      Q:531548824');
disp('請提出寶貴的意見!');
disp('=========================================================================');

disp('----------------------------------------------------------------------')
fprintf('問題描述:已知路網數據(Road_Net)和線路數據(Line_Station)及OD需求(Q),\n求指定OD對的配流結果.\n\n');
disp('----------------------------------------------------------------------')

%% 定義變量及常數
syms lambda real
for i=1:100
    syms x(i) real;
end
cont=0;
e=inf;
A=2;
B=5;
cs=1460;
cmax=2070;
Q=7500; 

%% 輸入路網數據
%例1
% Road_Net=[0 15 5 inf;15 0 inf 20;5 inf 0 25;inf 20 25 0];             %路網關聯矩陣,表示點到點的距離(或時間、費用)
%例2
Road_Net =[
     0     2   Inf     1   Inf   Inf   Inf   Inf   Inf
     2     0     3   Inf     3   Inf   Inf   Inf   Inf
   Inf     3     0   Inf   Inf     2   Inf   Inf   Inf
     1   Inf   Inf     0     3   Inf     5   Inf   Inf
   Inf     3   Inf     3     0     1   Inf     2   Inf
   Inf   Inf     2   Inf     1     0   Inf   Inf     3
   Inf   Inf   Inf     5   Inf   Inf     0     2   Inf
   Inf   Inf   Inf   Inf     2   Inf     2     0     4
   Inf   Inf   Inf   Inf   Inf     3   Inf     4     0];
Line_Station={[1 2 3 6 9 8 7 4],[2 5 8 9],[1 4 5 6]};

%% 調用KSP(K shortest path)計算出W,L,Mxf
[W_Section,Line_Section_01Mat,Mxf]=KSP(Road_Net,Line_Station); 
W=cell2mat(W_Section)
L=Line_Section_01Mat
Mxf=Mxf;
if isempty(Mxf)
    Mxf=zeros(1,length(W));
    disp('警告:無路徑可達.');
end
disp('路徑:(矩陣Mxf的行表示路徑號,列表示路段號)');Mxf

%% 計算路網基礎數據及路網表達
numf=size(Mxf,1);
numx=length(W);
Cs=cs.*ones(1,numx);
Cmax=cmax.*ones(1,numx);
x=x(1:numx);
disp('路網介紹')
disp(['總需求:',num2str(Q)]);
disp(['路徑數:',num2str(numf)]);
disp(['路段數:',num2str(numx)]);
disp(['初始路段阻抗:',num2str(W)]);
disp(['路段額定能力:',num2str(Cs)]);
disp(['路段極限能力:',num2str(Cmax)]);
delete('E:\MATLAB\自己的算法\FW_BPR算法計算過程.txt');
fid=fopen('E:\MATLAB\自己的算法\FW_BPR算法計算過程.txt','a');

%% step1_初始化
X0=zeros(1,numx);
t=zeros(1,numx);
t=W.*(1+0.15*(x./Cmax).^4);                                             %路段走行時間函數
tt=t;
disp('路段阻抗函數t=');
disp(vpa(t.',2));
t=W.*(1+0.15*(X0./Cmax).^4);                                            %路段的初始阻抗函數
Ckrs=(Mxf*t')';                                                         %路徑的走行時間初值
disp(['初始路徑阻抗:',num2str(Ckrs)]);
%% step2_更新流量和阻抗
[Min,index]=min(Ckrs);
X1=Mxf(index,:).*Q;                                                     %全有全無法爲最短路徑上的路段分配流量

fprintf(fid,'\r\n==============================================================\r\n');
while e>1e-3
    cont=cont+1;
    
    %% 計算路段附加擁擠時間G
    G=zeros(1,length(W));
    a1=(X1<=Cs);                                                        %a1-指向流量不大於額定能力的下標
    a2=(X1>Cs&X1<=Cmax);                                                %a2-指向流量介於額定能力和極限能力的下標
    a3=(X1>Cmax);                                                       %a3-指向流量大於極限能力的下標
    G(a1)=0;
    G(a2)=(X1(a2)-Cs(a2))./Cs(a2).*A;
    G(a3)=(Cmax(a3)-Cs(a3))./Cs(a3).*A+(X1(a3)-Cmax(a3))./Cs(a3).*B;
    
    %% 計算路段阻抗函數並求出路徑阻抗輸出至指定文件
    t=(W+G).*(1+0.15*(X1./Cmax).^4);                                    %路段時間
    fprintf(fid,'                   <第%d次的計算結果>\r\n',cont);
    Ckrs=(Mxf*t')';                                                     %路徑時間
    fprintf(fid,'阻 抗 值:');
    fprintf(fid,'%9.2f  ',Ckrs);
    fprintf(fid,'\r\n');
    
    %% 輸出當前流量至指定文件
    fprintf(fid,'當前流量:');
    fprintf(fid,'%9.2f  ',X1);
    fprintf(fid,'\r\n');
    
    %% 輸出輸出擁擠附加時間至指定文件
    fprintf(fid,'擁擠附加:');
    fprintf(fid,'%9.2f  ',G);
    fprintf(fid,'\r\n');
    
    %% step3_計算輔助流量並輸出至指定文件
    [Min,index]=min(Ckrs);
    Y1=Mxf(index,:).*Q;                                                 %全有全無法求輔助流量
    fprintf(fid,'輔助流量:');
    fprintf(fid,'%9.2f  ',Y1);
    fprintf(fid,'\r\n');
    
    %% step4_求搜索方向和步長並輸出至指定文件
    S=Y1-X1;                                                            %搜索方向
    fprintf(fid,'搜索方向:');
    fprintf(fid,'%9.2f  ',S);
    fprintf(fid,'\r\n');     
    X2=X1+lambda*S;                                                     %先將X2用X1和lambda進行表達
    t=(W+G).*(1+0.15*(X2./Cmax).^4);                                    %含lambda的阻抗表達
    f=sum(S.*t,2);                                                      %2表示按行求和    
    if S==0
        lambda2=0;
    else        
        lambda1=double(solve(f));                                       %求解方程,確定步長。
        k=length(lambda1);                                              %如步長lambda1的解不唯一,取實數,且大於0小於1;
        for m=1:k
            if lambda1(m,1)>=0&&lambda1(m,1)<=1
                lambda2=lambda1(m,1);
            end
        end
    end
    fprintf(fid,'迭代步長:');
    fprintf(fid,'  lambda=%9.2f  ',lambda2);
    fprintf(fid,'\r\n');
    
    %% step5_確定新的迭代點並輸出至指定文件
    X2=X1+lambda2*S;                                                    %得到下一步的流量值,且進行下一次迭代
    fprintf(fid,'新迭代點:');
    fprintf(fid,'%9.2f  ',X2);
    fprintf(fid,'\r\n');    
    
    %% step6_收斂性判斷
    e=sqrt(sum((X2-X1).^2))/sum(X1);
    X1=X2;
    fprintf(fid,'\r\n==============================================================\r\n');
end

%% 求目標函數值
Xx=zeros(numx,1);                                                       %積分下界
Xn=X1;                                                                  %積分上界
Z=zeros(numx,1);
for i=1:numx
    Z(i)=int(tt(i),Xx(i),Xn(i));                                        %對每一個路徑積分
end
Z=sum(Z);

%% step7_輸出結果
disp(['     迭代次數:',num2str(cont)]);
disp(['     誤 差 值:',num2str(e)]);
disp(['     配流結果:',num2str(Xn)]);
disp(['     路徑阻抗:',num2str(Ckrs)]);
disp(['     目 標 值:',num2str(Z)]);
toc
disp('**************************************************************************************')
disp('提示:詳細計算過程請打開 “E:\MATLAB\自己的算法\FW_BPR算法計算過程.txt” 查看。');
open('E:\MATLAB\自己的算法\FW_BPR算法計算過程.txt')
status=fclose('all');


算例分析:

路網如圖,節點1到節點9的OD需求爲7500,其他數據及說明見程序。求配流結果。

運行結果:

========================================================================
                           《FrankWolfe_BPR配流算法》
運行環境:MATLAB 8.3.0.532 
制 作 人:蘭州交通大學   劉志祥
完成時間:2015-12-30
Q      Q:531548824
請提出寶貴的意見!
=========================================================================
----------------------------------------------------------------------
問題描述:已知路網數據(Road_Net)和線路數據(Line_Station)及OD需求(Q),
求指定OD對的配流結果.

----------------------------------------------------------------------
Original=1
Destination=9
起點和終點間有直達線路:1
提示:若選擇換乘,可能的換乘站有:2  4  5  6  8
提示:滿足距離要求的路徑最多隻有10條,其中直達線路2條,1次換乘可達的3條,2次換乘可達的2條,3次及以上換乘可達的3條(已捨去)。

KSP = 

                               Road_Net: {[9x9 double]}
                           Line_Station: {[1 2 3 6 9 8 7 4]  [2 5 8 9]  [1 4 5 6]}
                        Section_Station: {1x24 cell}
                              W_Section: {[2]  [1]  [2]  [3]  [3]  [3]  [2]  [1]  [3]  [5]  [3]  [3]  [1]  [2]  [2]  [1]  [3]  [5]  [2]  [2]  [2]  [4]  [3]  [4]}
                           Line_Section: {[1 4 7 17 24 21 18]  [5 14 22]  [2 9 13]}
                     Line_Section_01Mat: [3x24 double]
                         W_Line_Section: {{1x7 cell}  {1x3 cell}  {1x3 cell}}
                               Original: {[1]}
                            Destination: {[9]}
                                   Kmax: {[100]}
                       Cost_of_Transfer: {[2.5000]}
                                      H: {[1.5000]}
                       Transfer_Station: {[2 4 5 6 8]}
    Irrespective_of_the_Transfer_KPaths: {1x10 cell}
    Irrespective_of_the_Transfer_KCosts: {[8]  [9]  [10]  [10]  [11]  [12]  [14]  [14]  [15]  [19]}
               Transfer_Station_of_Path: {[6]  [2 5 6]  [5]  []  [2]  []  [6 5]  [5 6 8]  [5 2]  [2 4 5]}
                      Times_of_Transfer: {[1]  [3]  [1]  [0]  [1]  [0]  [2]  [3]  [2]  [3]}
                     KCosts_of_Transfer: {[2.5000]  [Inf]  [2.5000]  [0]  [2.5000]  [0]  [5]  [Inf]  [5]  [Inf]}
           Consider_the_Transfer_KCosts: {[10.5000]  [Inf]  [12.5000]  [10]  [13.5000]  [12]  [19]  [Inf]  [20]  [Inf]}
    Consider_not_consider_KPaths_number: {[4 1 6 3 5]}
     Consider_not_consider_KPaths_Costs: {[10 10.5000 12 12.5000 13.5000]}
           Consider_the_Transfer_KPaths: {[1 2 3 6 9]  [1 4 5 6 9]  [1 4 7 8 9]  [1 4 5 8 9]  [1 2 5 8 9]}
                                    Mxf: {[5x24 double]}

計算耗時:
時間已過 0.379715 秒。

W =

     2     1     2     3     3     3     2     1     3     5     3     3     1     2     2     1     3     5     2     2     2     4     3     4


L =

     1     0     0     1     0     0     1     0     0     0     0     0     0     0     0     0     1     1     0     0     1     0     0     1
     0     0     0     0     1     0     0     0     0     0     0     0     0     1     0     0     0     0     0     0     0     1     0     0
     0     1     0     0     0     0     0     0     1     0     0     0     1     0     0     0     0     0     0     0     0     0     0     0

路徑:(矩陣Mxf的行表示路徑號,列表示路段號)

Mxf =

     1     0     0     1     0     0     1     0     0     0     0     0     0     0     0     0     1     0     0     0     0     0     0     0
     0     1     0     0     0     0     0     0     1     0     0     0     1     0     0     0     1     0     0     0     0     0     0     0
     0     1     0     0     0     0     0     0     0     1     0     0     0     0     0     0     0     0     1     0     0     1     0     0
     0     1     0     0     0     0     0     0     1     0     0     0     0     1     0     0     0     0     0     0     0     1     0     0
     1     0     0     0     1     0     0     0     0     0     0     0     0     1     0     0     0     0     0     0     0     1     0     0

路網介紹
總需求:7500
路徑數:5
路段數:24
初始路段阻抗:2  1  2  3  3  3  2  1  3  5  3  3  1  2  2  1  3  5  2  2  2  4  3  4
路段額定能力:1460  1460  1460  1460  1460  1460  1460  1460  1460  1460  1460  1460  1460  1460  1460  1460  1460  1460  1460  1460  1460  1460  1460  1460
路段極限能力:2070  2070  2070  2070  2070  2070  2070  2070  2070  2070  2070  2070  2070  2070  2070  2070  2070  2070  2070  2070  2070  2070  2070  2070
路段阻抗函數t=
  1.6e-14*x(1)^4 + 2.0
  8.2e-15*x(2)^4 + 1.0
  1.6e-14*x(3)^4 + 2.0
  2.5e-14*x(4)^4 + 3.0
  2.5e-14*x(5)^4 + 3.0
  2.5e-14*x(6)^4 + 3.0
  1.6e-14*x(7)^4 + 2.0
  8.2e-15*x(8)^4 + 1.0
  2.5e-14*x(9)^4 + 3.0
 4.1e-14*x(10)^4 + 5.0
 2.5e-14*x(11)^4 + 3.0
 2.5e-14*x(12)^4 + 3.0
 8.2e-15*x(13)^4 + 1.0
 1.6e-14*x(14)^4 + 2.0
 1.6e-14*x(15)^4 + 2.0
 8.2e-15*x(16)^4 + 1.0
 2.5e-14*x(17)^4 + 3.0
 4.1e-14*x(18)^4 + 5.0
 1.6e-14*x(19)^4 + 2.0
 1.6e-14*x(20)^4 + 2.0
 1.6e-14*x(21)^4 + 2.0
 3.3e-14*x(22)^4 + 4.0
 2.5e-14*x(23)^4 + 3.0
 3.3e-14*x(24)^4 + 4.0
 
 初始路徑阻抗:10   8  12  10  11
     迭代次數:117
     誤 差 值:0.00092332
     配流結果:3699.3642      3800.6358              0      1901.3204      1798.0438              0      1901.3204              0      2226.3406      1574.2952              0              0      1914.7689      2109.6155              0              0      3816.0893              0      1574.2952              0              0      3683.9107              0              0
     路徑阻抗:54.494      54.8772      55.0724      56.1326      54.5126
     目 標 值:88930.865
時間已過 111.671728 秒。
**************************************************************************************
提示:詳細計算過程請打開 “E:\MATLAB\自己的算法\FW_BPR算法計算過程.txt” 查看。
>> 


詳細計算過程可去http://download.csdn.net/detail/lzx19901012/9383749查看。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章