综合算法04—非排序换乘算法

来源:互联网 发布:sar 指标算法 编辑:程序博客网 时间:2024/04/30 06:41

一、算法描述

问题描述:已知站点,线路,线路-站点数据,求指定点之间的:

1、直达线路
2、一次换乘线路
3、两次换乘线路

模块1:直达线路算法
Step1:S为过起点A的线路集合,T为过终点B的线路集合;
Step2:ZDXL为直达线路,ZDXL=S∩T;ZDD为在直达线路上的点
Step3:若某条线路上起点在终点后面,则该线路不是直达线路(区分上下行)

模块2:一次换乘线路算法
Step1:与起点直达的点的集合zhan_A,与终点直达的点的集合zhan_B;
Step2:剔除在起讫点直达线路上的点ZDD_AB;
Step4:一次换乘点HCD_1ci=zhan_A∩zhan_B;
Step5:针对每一个换乘点i,再利用模块1的直达算法求得起点到每一个换乘点的直达线路;同理求得换乘点到终点的直达线路;则一次换乘线路为两段直达线路的组合。

模块3:二次换乘线路算法
Step1:找到与A直达的点的集合Z2,S2为过Z2的线路;
Step2:求与Z2直达的点集合并剔除直达点和一次换乘点记为zhan_2_A;
Step3:二次换乘点HCD_2ci=zhan_2_A∩zhan_B;
Step4:起点不变,以HCD_2ci为终点,调用一次换乘算法求得一次换乘点HCD_1,则起点、一次换乘点、二次换乘点、终点被确定;
Step5:分段,第一段:【起点,一次换乘点】;第二段:【一次换乘点,二次换乘点】,第三段:【二次换乘点,终点】;
Step6:分别对三段调用直达算法求得各段的直达线路,则二次换乘方案为三段直达线路的组合。

总算法:
Step1:数据准备,输入或调用编辑好的路网数据,输入起点和终点;
Step2:调用直达函数,输出直达方案(不排序);
Step3:调用一次换乘函数,输出一次换乘方案(不排序);
Step4:调用二次换乘函数,输出二次换乘方案(不排序)。

补充说明:
如有换乘路径,但换乘点在直达线路上,算法认为没有必要换乘,即舍去该换乘方案,然而有时候舍去的方案可能费用更省,在此不再深究。
例如:从v2到v9有很多条路径,但由于其他路径的换乘点在直达线路L1或L4上,故不管其路径费用是多少都舍弃其他方案。

二、算法程序

使用说明:将以下代码分别保存为m文件放在同一个目录下,注意名称不能写错,修改案例请打开luwangshuju.m,运行程序请打开huanchengsuanfa.m。

1. fuhaoshuoming.m

fprintf('=======================================================================\n');fprintf('                   《换乘方案算法——不对方案排序》\n');fprintf('运行环境:MATLAB 8.3.0.532 \n');fprintf('作者信息:兰州交通大学  刘志祥   QQ:531548824\n');fprintf('说明:本程序用于在已知路网数据时,通过输入起讫点求直达、一次、二次换乘方案。\n')fprintf('=======================================================================\n\n');%《路网数据符号》% luwangshuju-路网数据,包括站数据(点编号),线数据(线编号),站—线数据(线路包含的站点)% A-起点% B-终点% zhan-站集合,本程序中站点以V开头编号% xian-线集合,可理解为公交车名称,如k102等% zhan_xian-线与站的关系,表示线路上有哪些站点%《数据处理符号》% zhan_xian_01-线与站的01矩阵,行表示线,列表示站,0表示不在该线,1表示在该线上% xian_zhan_01-站与线的01矩阵,行表示站,列表示线,0表示线不经过站,1表示经过,与zhan_xian_01互为转置矩阵%《直达算法符号》% S-经过起点的所有线路集合% T-经过终点的所有线路集合% ZDXL-直达线路,是S与T的交集% ZDD-直达线路上的点%《一次换乘算法符号》% D_A-与A直达的点的集合(矩阵的行是线,列是站,表示线路是否经过该站点)% D_B-与B直达的点的集合(同上)% Z2-为与A直达的点% X2-为Z2所在的线路% S2-过与A直达的点的线路% E2-把与A直达的点zhan_A看作起点,与该点直达的点的集合,即S2上的点% zhan_A-与起点A直达的点的集合(剔除直达点后)% xian_A-表示zhan_A所在的线路集合(一一对应)% zhan_B-与终点B直达的点的集合(剔除起讫点直达线路点后的)% xian_B-表示zhan_B所在的线路集合(一一对应)% HCX_1ci_qianmian-一次换乘的前段线路% HCX_1ci_houmian-一次换乘的末段线路% HCD_1ci-一次换乘点% HCX_1ci-一次换乘线集合(第1行表示前段线路,第2行表示末段线路)%《二次换乘算法符号》% Point-二次换乘4个关键点【起点 换乘点1 换乘点2 终点】% HCD_1-换乘点1% HCD_2-换乘点2% HCX_1-前段线路【起点-换乘点1】% HCX_2-中段线路【换乘点1-换乘点2】% HCX_3-末段线路【换乘点2-终点】%《总换乘算法符号》% ZDX_AB-起讫点间的直达线% ZDD_AB-起讫点间的直达点% HCX_1ci_AB-起讫点直接的一次换乘线% HCD_1ci_AB-起讫点直接的一次换乘点% HCX_2ci_AB-起讫点直接的二次换乘线% HCD_2ci_AB-起讫点直接的一次换乘点%其他符号见程序内注释


2. luwangshuju.m

%==========================================================================% 路网数据% 运行可得基础路网数据% 主要计算结果:【输入起讫点 得到路网的站-线-权数据 】%==========================================================================%% 输入始发点和目的地qidian=2;zhongdian=9;A=qidian;B=zhongdian;%% 数据for换乘算法% %例1% %==========================================================================% zhan=[1 2 3 4 5 6 7 8 9];                                                   %站数据% xian={1 2 3 4 5 6};                                                         %线路数据% xian_zhan={[1 2 4 6],[1 3 5 7 8],[9 2 5 6],[6 4 2 1],[8 7 5 3 1],[6 5 2 9]};%线路包含哪些站% %==========================================================================%例2%==========================================================================zhan=[1 2 3 4 5 6 7 8 9 10 11 12 13];                                       %站数据xian=[1 2 3 4 5 6];                                                         %线路数据xian_zhan={[1 2 3 6 9 8 7 4],[10 4 5 6 11],[12 2 5 8 13],[4 7 8 9 6 3 2 1],...    [11 6 5 4 10],[13 8 5 2 12]};                                           %线路包含哪些站,注意要和roadnet对应起来,如果线路的始发站和终点站直接相连,即为环线。%==========================================================================


3. shujuchuli.m

% =========================================================================% 数据处理% 运算依赖于luwangshuju.m% 主要运算结果【得到普通线站关系的01矩阵】...%==========================================================================%% 线_站单元数组转换为01矩阵%==========================================================================xian_zhan_01=zeros(length(xian),length(zhan));for i=1:length(xian)    xian_zhan_01(i,xian_zhan{i})=1;endzhan_xian_01=xian_zhan_01';%==========================================================================


4. zhida.m
%==========================================================================% 直达方案% 运算依赖于luwangshuju.m shujuchuli.m% 主要计算结果:【ZDXL ZDD】%==========================================================================%% step1 起终点线路统计%==========================================================================S=find(zhan_xian_01(A,:)==1);                 %经过起点的所有线路集合T=find(zhan_xian_01(B,:)==1);                 %经过终点的所有线路集合%==========================================================================%% step2 求直达路线%==========================================================================ZDXL=intersect(S,T);                          %直达线路就是S和T的交集ZDXL_wuxiang=ZDXL;                            %记录无向直达线路,为后面一次换乘时删除直达点做准备[m,n]=find(1==xian_zhan_01(ZDXL_wuxiang,:));  %直达点就是直达线路上的站点ZDD=unique(n)';                               %直达点整理——去重%==========================================================================%% step3 区分上下行线路%==========================================================================for i=1:length(ZDXL)    if find(A==cell2mat(xian_zhan(ZDXL_wuxiang(i))))>...            find(B==cell2mat(xian_zhan(ZDXL_wuxiang(i))))        ZDXL=setdiff(ZDXL,ZDXL_wuxiang(i));    endendif isempty(ZDXL)    ZDXL=[];endif isempty(ZDD)    ZDD=[];end%==========================================================================%% step4 主要计算结果%==========================================================================% ZDXL% ZDD%==========================================================================

5. yicihuancheng.m

% =========================================================================% 一次换乘方案% 运算依赖于luwangshuju.m shujuchuli.m zhida.m% 主要计算结果:【HCD_1ci  HCX_1ci】%==========================================================================%% step1 找到一次换乘点%==========================================================================D_A=zeros(size(xian_zhan_01,1),size(xian_zhan_01,2));  %初始化,使得D_A,D_B具有和矩阵xian_zhan_01同样的维数(形状相同)D_B=D_A;D_A(S,:)=xian_zhan_01(S,:);                            %找出与起点直达的点的集合,并对应于线路SD_B(T,:)=xian_zhan_01(T,:);                            %找出与终点直达的点的集合,并对应于线路TD_A(ZDXL_wuxiang,:)=0;                                 %剔除直达线路上的点,(直达线路没有必要下车后再乘坐同一线路)D_B(ZDXL_wuxiang,:)=0;                                 %删除直达线路上的点时必须确保该线路的返程线路上的点也被删除,因此这里用无向直达线路剔除法[xian_A,zhan_A]=find(D_A==1);                          %找到与起点直达的点,并列出其所在的线路[xian_B,zhan_B]=find(D_B==1);                          %找到与终点直达的点,并列出其所在的线路HCD_1ci=intersect(zhan_A,zhan_B)';                     %换乘点即为剔除直达线路点后,既与起点直达又与终点直达的点%==========================================================================%% step2 分段求直达线路%==========================================================================if isempty(HCD_1ci)==0                 %若换乘点存在,继续执行    %第一段:起点-换乘点的直达线路    count=0;    for i=1:length(HCD_1ci)        A=qidian;        B=HCD_1ci(i);        zhida;        count=count+1;        HCX_1ci_qianmian(count)={ZDXL};    end        %第二段:换乘点-终点的直达线路    count=0;    for i=1:length(HCD_1ci)        A=HCD_1ci(i);        B=zhongdian;        zhida;        count=count+1;        HCX_1ci_houmian(count)={ZDXL};    endelse    HCD_1ci=[];                      %若没有换乘点,为了方便矩阵运算,令其为空矩阵    HCX_1ci_qianmian=[];             %没有换乘点也就不存在换乘线,为了方便矩阵运算,令其为空矩阵    HCX_1ci_houmian=[];end%==========================================================================%% step3 组合:第一行表示换乘前的线路,第二行表示换乘后的线路%==========================================================================HCX_1ci=[HCX_1ci_qianmian;HCX_1ci_houmian];                                    %第一行的第一个集合表示采用第一个换乘点的换乘前的线路,同理第二个集合表示采用第二个换乘点的换乘前的线路,类推。%==========================================================================%% step4 输出主要计算结果%%==========================================================================% HCX_1ci% HCD_1ci%%==========================================================================

6. ercihuancheng.m

%==========================================================================% 二次换乘方案% 运算依赖于luwangshuju.m shujuchuli.m zhida.m yicihuancheng.m huanchengsuanfa.m% 主要计算结果:【起点 换乘点1 换乘点2 终点】  【换乘线1 换乘线2 换乘线3】%==========================================================================%% 1.求第2次换乘点%==========================================================================E2=D_A;                            %与A直达的点的集合(矩阵的行是线路,列是站点,表示线路是否包含该站点)[X2,Z2]=find(D_A==1);              %Z2为与A直达的点,X2为Z2所在的线路Z2=setdiff(Z2,qidian);Z2=setdiff(Z2,ZDD_AB);Z2=setdiff(Z2,HCD_1ci_AB);count=0;if isempty(Z2)==0    for i=1:length(Z2)        count=count+1;        S2(count)={find(zhan_xian_01(Z2(i),:)==1)};    end    S2=unique(cell2mat(S2));        %过与A直达的点的线路    E2(S2,:)=xian_zhan_01(S2,:);    %把与A直达的点看作起点,求与该起点直达的点的集合    [xian_2_A,zhan_2_A]=find(E2==1);%找到[与起点直达的点的直达点对应的线路,与起点直达的点的直达点]    zhan_2_A=unique(zhan_2_A);    zhan_2_A=setdiff(zhan_2_A,ZDD_AB);    zhan_2_A=setdiff(zhan_2_A,HCD_1ci_AB);    HCD_2ci_AB=intersect(zhan_2_A,zhan_B)'; %找到二次换乘点else    HCD_2ci_AB=[];end%==========================================================================%% 2.确定第1次和第2次换乘点%==========================================================================if isempty(HCD_2ci_AB)==0            %如果存在二次换乘点,继续求二次换乘方案    for j=1:length(HCD_2ci_AB)       %j是针对二次换乘点的标号        A=qidian;        B=HCD_2ci_AB(j);             %重新定义起点和终点        zhida;        yicihuancheng;        HCD_1ci=setdiff(HCD_1ci,ZDD_AB);        HCD_1ci=setdiff(HCD_1ci,HCD_1ci_AB);        HCD_1(j)={HCD_1ci};    end    HCD_1;    HCD_2= {HCD_2ci_AB};    %======================================================================        %% 3.确定关键节点(【起点-换乘点1-换乘点2-终点】)    %======================================================================    count=0;    for i=1:length(HCD_1)        for j=1:length(HCD_1{i})            count=count+1;            p1(count)=qidian;          %起点            p2(count)=HCD_1{i}(j);     %换乘点1            p3(count)=HCD_2{1}(i);     %换乘点2            p4(count)=zhongdian;       %终点        end    end    Point=[p1;p2;p3;p4];    %======================================================================        %% 4.分三段求直达线路    %% 4.1 第1段:起点——换乘点1的路线    %======================================================================    count=0;    for i=1:length(p1)        A=p1(i);        B=p2(i);        zhida;        count=count+1;        HCX_1(count)={ZDXL};    end    %======================================================================        %% 4.2 第2段:换乘点1——换乘点2的路线    %======================================================================    count=0;    for i=1:length(p1)        A=p2(i);        B=p3(i);        zhida;        count=count+1;        HCX_2(count)={ZDXL};    end    %======================================================================        %% 4.3 第3段:换乘点2——终点的路线    %======================================================================    count=0;    for i=1:length(p1)        A=p3(i);        B=p4(i);        zhida;        count=count+1;        HCX_3(count)={ZDXL};    end    %======================================================================        else    %% 5. 没有二次换乘点,方案为空    %======================================================================    Point=[];    HCX_1=[];    HCX_2=[];    HCX_3=[];    HCD_1=[];    HCD_2=[];    HCX=[];    %==========================================================================endHCX=[HCX_1;HCX_2;HCX_3];

7. geshihuashuchu.m
%==========================================================================% 按格式输出% 运算依赖于huanchengsuanfa.m% 主要结果:【输出直达方案 输出一次换乘方案 输出二次换乘方案】%==========================================================================%% 直达方案fprintf('\n======================================================================\n')fprintf('直达方案:\n')if isempty(ZDX_AB)==0    for i=1:length(ZDX_AB)        fprintf('方案%d->:%d站上车,乘坐线路%d,到%d站下车;\n',i,qidian,ZDX_AB(i),zhongdian);    endelse    fprintf('没有直达线路,请参照换乘方案!\n');endfprintf('======================================================================\n\n')%% 一次换乘方案fprintf('======================================================================\n')fprintf('一次换乘方案:\n')HCX_1ci_AB=cell2mat(HCX_1ci_AB);if isempty(HCX_1ci_AB)==0    for i=1:size(HCX_1ci_AB,2)        fprintf('方案%d->:%d站上车,乘坐线路%d,到%d站下车;%d站上车,乘坐线路%d,到%d站下车.\n',i,qidian,HCX_1ci_AB(1,i),HCD_1ci_AB(1,i),HCD_1ci_AB(1,i),HCX_1ci_AB(2,i),zhongdian);    endelse    fprintf('没有一次换乘线路.\n\n');endfprintf('======================================================================\n\n')%% 二次换乘方案fprintf('======================================================================\n')fprintf('二次换乘方案:\n')HCX_2ci_AB=cell2mat(HCX_2ci_AB);if isempty(HCX_2ci_AB)==0    for i=1:size(HCX_2ci_AB,2)        fprintf('方案%d->:%d站上车,乘坐线路%d,到%d站下车;%d站上车,乘坐线路%d,到%d站下车;%d站上车,乘坐线路%d,到%d站下车.\n',...            i,qidian,HCX_2ci_AB(1,i),HCD_2ci_AB(2,i),HCD_2ci_AB(2,i),HCX_2ci_AB(2,i),HCD_2ci_AB(3,i),HCD_2ci_AB(3,i),HCX_2ci_AB(3,i),zhongdian);    endelse    fprintf('没有二次换乘线路.\n\n');endfprintf('======================================================================\n\n')

8. huanchengsuanfa.m

% =========================================================================% 换乘算法主程序(main)% 运算依赖于luwangshuju.m shujuchuli.m zhida.m yicihuancheng.m% ercihuancheng.m geshihuashuchu.m% 主要结果:求出【直达方案 一次换乘方案 二次换乘方案】的数据% =========================================================================clearclcfuhaoshuoming%% 数据准备luwangshuju;shujuchuli;%==========================================================================if ~ismember([A B],zhan)|A==B    %======================================================================    clc    warning('!!起讫点输入错误,重新输入请按任意键...')    pause    huanchengsuanfa    %======================================================================else        %% 1.求直达方案    %======================================================================    zhida;             %调用直达函数(查看zhida.m)    ZDX_AB=ZDXL;       %起讫点间的直达线路    ZDD_AB=ZDD;        %起讫点的直达线路上的点    %======================================================================        %% 2.求一次换乘方案    %======================================================================    yicihuancheng;     %调用一次换乘函数(查看yicihuancheng.m)    HCX_1ci_AB=HCX_1ci;%起讫点间的一次换乘线,按行分别表示首段和末段的线路    HCD_1ci_AB=HCD_1ci;%起讫点的一次换乘线路上的点    %======================================================================        %% 3.求二次换乘方案    %======================================================================    ercihuancheng;    %调用二次换乘函数(查看ercihuancheng.m)    HCX_2ci_AB=HCX;   %起讫点间的二次换乘线,按行分别表示首段、中间、末段的线路    HCD_2ci_AB=Point; %起讫点间二次换乘的4个关键点,确定分段的点    %======================================================================        %% 4.格式化输出    %======================================================================    geshihuashuchu    %======================================================================end

三、算例及运算结果

1.算例1

路网如图1所示,已知站数据、线数据及站-线数据。给定起点v4,终点v8。求路径方案。

1.1 运行结果

修改luwangshuju.m——qidian=4;zhongdian=8;

>> huanchengsuanfa

=======================================================================                   《换乘方案算法——不对方案排序》运行环境:MATLAB 8.3.0.532 作者信息:兰州交通大学  刘志祥   QQ:531548824说明:本程序用于在已知路网数据时,通过输入起讫点求直达、一次、二次换乘方案。=============================================================================================================================================直达方案:没有直达线路,请参照换乘方案!============================================================================================================================================一次换乘方案:方案1->:4站上车,乘坐线路4,到1站下车;1站上车,乘坐线路2,到8站下车.============================================================================================================================================二次换乘方案:方案1->:4站上车,乘坐线路4,到2站下车;2站上车,乘坐线路3,到5站下车;5站上车,乘坐线路2,到8站下车.方案2->:4站上车,乘坐线路1,到6站下车;6站上车,乘坐线路6,到5站下车;5站上车,乘坐线路2,到8站下车.======================================================================


2.算例2

路网如图2所示,已知站数据、线数据及站-线数据。给定起点v2,终点v9。求路径方案。


图2 简单网络结构图


2.1运行结果

修改luwangshuju.m——qidian=2;zhongdian=9;

>> huanchengsuanfa

=======================================================================                   《换乘方案算法——不对方案排序》运行环境:MATLAB 8.3.0.532 作者信息:兰州交通大学  刘志祥   QQ:531548824说明:本程序用于在已知路网数据时,通过输入起讫点求直达、一次、二次换乘方案。=============================================================================================================================================直达方案:方案1->:2站上车,乘坐线路1,到9站下车;============================================================================================================================================一次换乘方案:没有一次换乘线路.============================================================================================================================================二次换乘方案:没有二次换乘线路.======================================================================

四、结论与展望

在路网站点、线路、站点-线路关系已知时,通过输入起讫点可以计算出直达路径及一次、二次换乘路径。但是算法罗列了所有路径,当路网变得复杂时,该算法将失去实际意义,所以算法需要改进,需要将多余的路径过滤,或许可以通过定义有效路径的方法对路径过滤并排序。


五、代码下载

代码下载地址:http://download.csdn.net/download/lzx19901012/9709091

1 0
原创粉丝点击