底特律法計算未來出行分佈
% trans_planning 計算未來出行量分佈
function main()
clc;clear;
confirm = 0;
while confirm == 0
inner = 0; % 是否使用算例標識
e = input('確定本次計算使用誤差精度(推薦0.03):');
OD = input('請輸入當前交通量方陣(輸入1使用算例1,輸入2使用算例2):');
if OD == 1
inner = 1;confirm = 1;
Gi1 = [2 1 4 3];% 產生量增長係數
Gj1 = Gi1; % 吸引量增長係數
OD1 = [ 0 25 10 5;
0 0 15 10;
0 0 0 5;
0 0 0 0];
OD1 = OD1 + OD1'; % 初始出行分佈
OD = OD1;
Gi = Gi1;Gj = Gj1;
elseif OD ==2
inner = 1;confirm = 1;
OD2 = [17 7 4;
7 38 6;
4 5 17];
P_0 = sum(OD2,1);
A_0 = sum(OD2,2)';
P_f = [38.6 91.9 36];
A_f = [39.3 90.3 36.9];
Gi2 = P_f./P_0;
Gj2 = A_f./A_0;
OD = OD2;Gi = Gi2;Gj = Gj2;
else
choice = input('以預測交通量輸入選1,以增長係數輸入選2:');
if choice == 1
P_f = input('請輸入發生量向量,格式爲行向量:');
A_f = input('請輸入吸引量向量,格式爲行向量:');
P_0 = sum(OD,1);
A_0 = sum(OD,2)';
Gi = P_f./P_0;
Gj = A_f./A_0;
elseif choice == 2
Gi = input('請輸入發生量增長係數向量,格式爲行向量:');
Gj = input('請輸入吸引量增長係數向量,格式爲行向量:');
else
disp('選擇發生錯誤');
return;
end
end
if inner == 0
disp('確認輸入:');
disp('當前交通量分佈矩陣:');disp(OD);
if choice == 1
disp('預測各區發生量分佈');disp(P_f);
disp('預測各區吸引量分佈');disp(A_f);
else
disp('預測各區發生量增長係數');disp(Gi);
disp('預測各區吸引量增長係數');disp(Gj);
end
confirm = input('確認數據輸入1,重新錄入數據輸入0:');
end
end
[OD_f alpha m] = MyDetroit(OD,Gi,Gj,e);
disp('未來交通量分佈:');
disp(OD_f);
for i = 1:size(OD_f,2)
OD_f{i}
end
disp(['當前精度:',num2str(e),' 迭代次數:',num2str(m)]);
printfile = input('是否打印結果報告(1是,2否):');
if printfile == 1
OD_f = cell2mat(OD_f);
file = fopen('report.txt','w+');
fprintf(file,'%s\n','未來交通量分佈:');
[row col] = size(OD_f);
for i = 1:row
for j = 1:col
if j == col
fprintf(file,'%g\n',OD_f(i,j));
else
fprintf(file,'%g\t',OD_f(i,j));
end
end
end
fprintf(file,'當前精度:%d\t迭代次數:%d',e,m);
fclose(file);
else
return;
end
end
function [OD_f alpha m] = MyDetroit(OD,Gi,Gj,e)
%% 參數計算
if size(OD,1) ~= length(Gi) || size(OD,2) ~= length(Gj)
disp("增長係數維度與出行量矩陣維度不符");
return;
end
Gavg = sum(OD,1)*Gi'/sum(sum(OD,1)); % 計算出行分佈的平均增長係數
P_0 = sum(OD,1); %計算各區當前發生量
A_0 = sum(OD,2)'; %計算各區當前吸引量
P_f0 = P_0.*Gi; % 計算未來各區發生量
A_f0 = A_0.*Gj; % 計算未來各區吸引量
flag = 0;
m = 0;
while(flag == 0 && m < 100)
%計算分區之間未來分佈量
for i = 1:size(OD,1)
for j = 1:size(OD,2)
OD(i,j) = OD(i,j)*Gi(i)*Gj(j)/Gavg;
end
end
%計算調整係數
P_f = sum(OD,1);
A_f = sum(OD,2)';
%alpha1 = Gi.*P_0./P_f;
%alpha2 = Gj.*A_0./A_f;
alpha1 = P_f0./P_f;
alpha2 = A_f0./A_f;
Gi = alpha1;Gj = alpha2;
Gavg = sum(P_f0)/sum(P_f);
%檢驗alpha是否符合要求
for k = 1:length(alpha1)
if alpha1(k)<=1+e && alpha1(k) >= 1-e
flag = 1;
else
flag =0;
break;
end
end
for k = 1:length(alpha2)
if alpha2(k)<=1+e && alpha2(k) >= 1-e
flag = 1;
else
flag =0;
break;
end
end
m = m+1;
alpha(m,:) = alpha1;
pf(m) = sum(P_f);
OD_f{m} = OD;
end
if m >= 100 && flag == 0
disp("算法發散,計算失敗");
return;
end
end