综合算法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
- 综合算法04—非排序换乘算法
- 综合算法05—考虑换乘的K短路算法
- 综合算法01—考虑换乘的基于路径长度的所有点间K短路算法
- 公交换乘算法问题
- 公交车换乘算法
- 公交换乘算法
- 公交换乘简单算法
- 公交换乘算法
- 公交换乘算法初探
- 公交换乘算法
- 公交换乘算法
- 公交换乘算法
- 2014华为机试——地铁换乘寻找最少车站数和排序算法
- [I0A]排序算法综合实例
- 非比较排序算法
- 公交换乘一站算法
- C/C++ 排序算法代码综合
- 合并排序算法(非递归)
- ExternalAccessory.framework 第三方硬件接口
- 什么是依赖注入
- 使用openssl命令剖析RSA私钥文件格式
- yii-besic (五)视图
- Intellij IDEA 一些不为人知的技巧
- 综合算法04—非排序换乘算法
- vue.js 的起步
- Web前端 html实时预览
- jsp中out.println("");报错(IDEA)
- ubuntu安装phantomjs apt-get和下载安装包两种方式
- Android支付接入(二):移动游戏基地
- LOD技术——定义详解及相关知识介绍
- hdu1698 Just a Hook(线段树 区间更新+懒惰标记)
- jdbc:oracle:thin:@192.168.3.98:1521:orcl(详解)