四階段法-出行分佈計算 底特律法

底特律法計算未來出行分佈

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