%% 算法符號及程序說明
%說明:本程序爲採用美國聯邦公路阻抗函數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查看。