综合算法05—考虑换乘的K短路算法
一、问题描述
在路网中,已知站点、线路和线路-站点数据,有条件:1、考虑到换乘时要花费一定的时间,因此对换乘路径费用要加上换乘时间。2、当路网复杂时,为了避免多余计算,定义有效路径,使得路径在有效路径范围内。有效路径为最短路径的(1+h)倍。求满足条件的K短路。
二、算法描述
1.K短路算法:
Step1:令k=1,求出最短路,并加上t换乘;
Step2:k=k+1,求出k短路,并加上t换乘;
Step3:判断,if是有效路径,保存并转Step2;else转Step4;
Step4:删除路径,结束。
2.换乘时间算法(假设换乘时间基于换乘次数):
if 路径所有站点都在线路j上,n=0;
else if 存在i站点,使得起点到i的所有站点都在线路j1上,i到终点的所有站点都在j2上,则n=1;
else if 存在i1、i2,使得起点到i1的所有站点都在线路j1上,i1到i2间所有站点都在j2上,i2到终点的所有站点都在j3上,则n=2;
else n=∞;
t换乘=n*换乘一次的平均时间。
三、算法程序
使用说明:将以下代码分别保存为m文件放在同一个目录下,注意名称不能错,修改案例请打开luwangshuju.m,运行程序请打开KSP.m。
1.fuhaoshuoming.mfprintf('======================================================================\n'); fprintf(' 《换乘方案算法——不对方案排序》\n'); fprintf('运行环境:MATLAB 8.3.0.532 \n'); fprintf('作者信息:兰州交通大学 刘志祥 QQ:531548824\n'); fprintf('说明:本程序用于在已知路网数据时,通过输入起讫点求直达、一次、二次换乘方案。\n') fprintf('======================================================================\n\n'); %% 符号体系 %% 路网数据符号 %========================================================================== % luwangshuju-路网数据,包括站数据(点编号),线数据(线编号),站—线数据(站与线的0-1矩阵,表示站是否在线上),线-站数据(线与站的0-1矩阵,表示线是否包含站),路权数据(如行驶时间或距离)。 % A-起点 % B-终点 % zhan-站集合,本程序中站点以V开头编号 % xian-线集合,可理解为公交车名称,如k102等 % zhan_xian-线与站的关系,表示线路上有哪些站点 %==========================================================================%% 数据处理符号 %========================================================================== % zhan_xian_01-线与站的01矩阵,行表示线,列表示站,0表示不在该线,1表示在该线上 % xian_zhan_01-站与线的01矩阵,行表示站,列表示线,0表示线不经过站,1表示经过,与zhan_xian_01互为转置矩阵 %==========================================================================%% 换乘次数符号 %========================================================================== % KHc_cishu-换乘次数 % KHc_hcd-换乘点 % KHc_hcqj-换乘区间 % KHc_hcld_a-换乘路段 %==========================================================================%% K短路算法符号 %========================================================================== % KPaths-有效路径 % KCosts-有效路径的费用(本文指时间) %==========================================================================
2.luwangshuju.m%========================================================================== % 路网数据 % 运行可得基础路网数据 % 主要计算结果:【输入起讫点 得到路网的站-线-权数据 】 %========================================================================== %% 输入始发点和目的地 % O=input('O='); % D=input('D='); O=2; D=9; %==========================================================================%% 数据for K短路算法 %========================================================================== % 例1 % Road_Net =[ % 0 3 2 Inf Inf Inf Inf Inf Inf % 3 0 Inf 1 3 Inf Inf Inf 2 % 2 Inf 0 Inf 2 Inf Inf Inf Inf % Inf 1 Inf 0 Inf 3 Inf Inf Inf % Inf 3 2 Inf 0 4 3 Inf Inf % Inf Inf Inf 3 4 0 Inf Inf Inf % Inf Inf Inf Inf 3 Inf 0 2 Inf % Inf Inf Inf Inf Inf Inf 2 0 Inf % Inf 2 Inf Inf Inf Inf Inf Inf 0]; % 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 %========================================================================== Road_Net =[0 2 Inf 3 Inf Inf Inf Inf Inf Inf Inf Inf Inf2 0 4 Inf 4 Inf Inf Inf Inf Inf Inf 3 InfInf 4 0 Inf Inf 3 Inf Inf Inf Inf Inf Inf Inf3 Inf Inf 0 8 Inf 2 Inf Inf 4 Inf Inf InfInf 4 Inf 8 0 9 Inf 2 Inf Inf Inf Inf InfInf Inf 3 Inf 9 0 Inf Inf 4 Inf 5 Inf InfInf Inf Inf 2 Inf Inf 0 3 Inf Inf Inf Inf InfInf Inf Inf Inf 2 Inf 3 0 6 Inf Inf Inf 3Inf Inf Inf Inf Inf 4 Inf 6 0 Inf Inf Inf InfInf Inf Inf 4 Inf Inf Inf Inf Inf 0 Inf Inf InfInf Inf Inf Inf Inf 5 Inf Inf Inf Inf 0 Inf InfInf 2 Inf Inf Inf Inf Inf Inf Inf Inf Inf 0 InfInf Inf Inf Inf Inf Inf Inf 3 Inf Inf Inf Inf 0]; 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对应起来,如果线路的始发站和终点站直接相连,即为环线。 %========================================================================== Cost_of_Transfer=2.5; H=1; a=0; Kmax=inf; %==========================================================================
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; end zhan_xian_01=xian_zhan_01'; %==========================================================================%以下代码用于K短路算法 %% 根据路网对路段进行自动标号并求出每个路段的距离 %========================================================================== for i=1:length(Road_Net)for j=1:length(Road_Net)if Road_Net(i,j)~=0&Road_Net(i,j)~=infa=a+1;luduan_zhan{a}={i,j};W_luduan{a}=Road_Net(i,j);endend end %==========================================================================
4.huanchengcishu.m%========================================================================== % 换乘次数 % 被KSP.m调用才可计算 % 主要运算结果【换乘次数、换乘点、换乘区间、换乘路段】 %========================================================================== KHc_hcd{k}=[]; KHc_hcqj{k}=[]; KHc_hcld_a{k}=[];%% 直达线路 %========================================================================== KHc_cishu=length(luduan_zhan); %最大换乘次数 m1=1; m2=length(KPaths{k}); for j1=1:length(xian_zhan)if all(ismember(KPaths{k}(m1:m2),xian_zhan{j1}))if find(O==xian_zhan{j1})<find(D==xian_zhan{j1})KHc_cishu=0;KHc_hcd{k}={[]};KHc_hcqj{k}={[]};KHc_hcld_a{k}={[]};endend end %==========================================================================%% 一次换乘 %========================================================================== for i=2:length(KPaths{k})-1for j1=1:length(xian_zhan)for j2=1:length(xian_zhan)if KHc_cishu~=0if all(ismember(KPaths{k}(1:i),xian_zhan{j1})) & all(ismember(KPaths{k}(i:length(KPaths{k})),xian_zhan{j2}))& j1~=j2if find(O==xian_zhan{j1})<find(KPaths{k}(i)==xian_zhan{j1})& find(D==xian_zhan{j2})>find(KPaths{k}(i)==xian_zhan{j1})KHc_cishu=1;KHc_hcd{k}={KPaths{k}(i)};KHc_hcqj{k}={[KPaths{k}(i) KPaths{k}(i+1)]};for a=1:length(luduan_zhan)if [KPaths{k}(i) KPaths{k}(i+1)]==cell2mat(luduan_zhan{a})KHc_hcld_a{k}={a};endendendendendendend end %==========================================================================%% 二次换乘 %========================================================================== for i1=2:length(KPaths{k})-1for i2=i1:length(KPaths{k})-1for j1=1:length(xian_zhan)for j2=1:length(xian_zhan)for j3=1:length(xian_zhan)if KHc_cishu~=0&KHc_cishu~=1if all(ismember(KPaths{k}(1:i1),xian_zhan{j1})) & all(ismember(KPaths{k}(i1:i2),xian_zhan{j2}))& all(ismember(KPaths{k}(i2:length(KPaths{k})),xian_zhan{j3}))if j1~=j2 &j2~=j3 &j1~=j3&KPaths{k}(i1)~=KPaths{k}(i2)if(find(O==xian_zhan{j1})<find(KPaths{k}(i1)==xian_zhan{j1})) & find(KPaths{k}(i1)==xian_zhan{j2})<find(KPaths{k}(i2)==xian_zhan{j2}) & find(D==xian_zhan{j3})>find(KPaths{k}(i2)==xian_zhan{j3})KHc_cishu=2;KHc_hcd{k}={KPaths{k}(i1) KPaths{k}(i2)};KHc_hcqj{k}={[KPaths{k}(i1) KPaths{k}(i1+1)];[KPaths{k}(i2) KPaths{k}(i2+1)]};for a1=1:length(luduan_zhan)for a2=1:length(luduan_zhan)if [KPaths{k}(i1) KPaths{k}(i1+1)]==cell2mat(luduan_zhan{a1})&[KPaths{k}(i2) KPaths{k}(i2+1)]==cell2mat(luduan_zhan{a2})KHc_hcld_a{k}={a1 a2};endendendendendendendendendendend end %==========================================================================
5.dijkstra.mfunction [shortestPath, totalCost] = dijkstra(netCostMatrix, s, d) n = size(netCostMatrix,1); for i = 1:nfarthestPrevHop(i) = i; farthestNextHop(i) = i; end visited(1:n) = false; distance(1:n) = inf; parent(1:n) = 0; distance(s) = 0; for i = 1:(n-1),temp = [];for h = 1:n,if ~visited(h) temp=[temp distance(h)];elsetemp=[temp inf];endend;[t, u] = min(temp); visited(u) = true; for v = 1:n, if ( ( netCostMatrix(u, v) + distance(u)) < distance(v) )distance(v) = distance(u) + netCostMatrix(u, v); parent(v) = u; end;end; end;shortestPath = []; if parent(d) ~= 0 t = d;shortestPath = [d];while t ~= sp = parent(t);shortestPath = [p shortestPath]; if netCostMatrix(t, farthestPrevHop(t)) < netCostMatrix(t, p)farthestPrevHop(t) = p;end;if netCostMatrix(p, farthestNextHop(p)) < netCostMatrix(p, t)farthestNextHop(p) = t;end; t = p;end; end; totalCost = distance(d);
6.KSP.mclear clc %% =============================================================== % K短路算法+换乘算法 % 运算调用huanchengcishu.m % 主要运算结果【KPaths KCosts Mxf】 %==========================================================================%% 1. 输入并处理相关的路网数据 %========================================================================== luwangshuju; shujuchuli; k=1; n=0; %==========================================================================%% 2. K短路算和换乘算法结合,求出有效路径 %========================================================================== if ismember([O D],zhan) & O~=D%% 2.1 调用Dijkstra算法求出最短路路径及费用[path costs]=dijkstra(Road_Net, O, D);if isempty(path)KPaths=[];KCosts=[];else%% 2.2 初始化path_number = 1; %路径从1开始编号P{path_number,1}= path; %单元数组P第一行表示路径P{path_number,2}= costs; %单元数组P第二行表示路径阻抗current_P = path_number;size_X=1;X{size_X}={path_number; path; costs};%1-编号,2-路径,3-阻抗值S(path_number)= path(1); %路径的开始站点KPaths{k}= path;KCosts{k}= costs;%% 2.3 调用换乘次数函数while (k<Kmax && size_X ~=0)huanchengcishu; %求出路径k的换乘次数KHc_n{k}=KHc_cishu;KCosts{k}=KCosts{k}+KHc_cishu*Cost_of_Transfer;%求出考虑换乘后的总费用costs=min(cell2mat(KCosts)); %更新最小费用%% 2.4 删除非有效路径if KCosts{k}>(H+1)*costsk=k-1;KCosts=KCosts(1:k);KPaths=KPaths(1:k);KHc_n=KHc_n(1:k);KHc_hcd=KHc_hcd(1:k);KHc_hcqj=KHc_hcqj(1:k);KHc_hcld_a=KHc_hcld_a(1:k);breakend%% 2.5 关闭已搜索的路径for i=1:length(X)if X{i}{1}== current_Psize_X = size_X - 1;X(i)=[];break;endendP_= P{current_P,1};w = S(current_P);for i=1:length(P_)if w==P_(i)w_index_in_path=i; %找到w在路径中的位置endend%% 2.6 更新路网矩阵for index_dev_vertex= w_index_in_path:length(P_)- 1temp_luwangjuzhen = Road_Net;for i = 1: index_dev_vertex-1v = P_(i);temp_luwangjuzhen(v,:)=inf;temp_luwangjuzhen(:,v)=inf;endSP_sameSubPath=[];index =1;SP_sameSubPath{index}=P_;for i=1:length(KPaths)if length(KPaths{i})>= index_dev_vertex %如果路径长度大于index_dev_vertex,即还没有完成搜索if P_(1:index_dev_vertex)== KPaths{i}(1:index_dev_vertex) %对比当前路径和K路径的前index_dev_vertex个点,如果匹配,继续对比,否则为不匹配index = index+1; %匹配成功则自动进入下一个节点对比SP_sameSubPath{index}=KPaths{i};endendendv_ = P_(index_dev_vertex);for j = 1: length(SP_sameSubPath)next=SP_sameSubPath{j}(index_dev_vertex+1);temp_luwangjuzhen(v_,next)=inf;endsub_P=P_(1:index_dev_vertex);costs_sub_P=0;for i=1:length(sub_P)-1costs_sub_P=costs_sub_P+Road_Net(sub_P(i),sub_P(i+1));end[dev_p c]= dijkstra(temp_luwangjuzhen, P_(index_dev_vertex), D);if ~isempty(dev_p)path_number=path_number+1;P{path_number,1}=[sub_P(1:end-1) dev_p]; %连接起点到终点的路径P{path_number,2}= costs_sub_P + c ; %计算子路径及偏差定点到终点费用的和(最终费用)S(path_number)= P_(index_dev_vertex);size_X = size_X + 1;X{size_X}={path_number; P{path_number,1};P{path_number,2}};% 更新当前数据(路径编号,路径,路径费用)endend%% 2.7 防错处理,如果指定路径数目大于路网穷举数目,防错,否则最后的结果会发生重复,也可能进入死循环。if size_X > 0shortestXCosts= X{1}{3}; %路径费用shortestX= X{1}{1}; %判定路径for i=2:size_Xif X{i}{3}< shortestXCostsshortestX= X{i}{1};shortestXCosts= X{i}{3};endendcurrent_P=shortestX;k=k+1;KPaths{k}= P{current_P,1};KCosts{k}= P{current_P,2};elsek=k+1;endendend elsewarning('起点或终点不在指定路网中!按任意键请重新输入。。。');pauseKSP end %========================================================================== %% 3.有效路径 %% 3.1 保留有效路径并排序 %========================================================================== KCosts=cell2mat(KCosts); yxlj=find(KCosts<min(KCosts)*(1+H)); KCosts=KCosts(yxlj); [KCosts,yxlj]=sort(KCosts); KPaths=KPaths(yxlj); KHc_n=KHc_n(yxlj); KHc_hcd=KHc_hcd(yxlj); KHc_hcqj=KHc_hcqj(yxlj); KHc_hcld_a=KHc_hcld_a(yxlj); %==========================================================================%% 3.2 根据有效路径求得路径-路段的01矩阵 %========================================================================== Mxf=zeros(length(KPaths),length(luduan_zhan)); m=1; while m<=length(KPaths)for i=2:length(KPaths{m})for k=1:length(luduan_zhan)if isequal(cell2mat(luduan_zhan{k}),KPaths{m}([i-1 i]))Mxf(m,k)=1;endendendm=m+1; end %==========================================================================%% 3.3 有效路径路径-换乘路段的01矩阵 %========================================================================== if ~isempty(KHc_hcld_a)M=zeros(size(Mxf));for k=1:length(KPaths)M(k,[cell2mat(KHc_hcld_a{k})])=Cost_of_Transfer;end end %==========================================================================%% 4. 主要计算结果 %========================================================================== KPaths %有效路径 KCosts %有效路径的费用(本文指时间) KHc_n %换乘次数 KHc_hcd=KHc_hcd %换乘点 KHc_hcqj=KHc_hcqj %换乘区间 KHc_hcld_a %换乘路段 % Mxf %有效路径与路段的0-1矩阵(为Frank Wolfe算法调用) % M %路径-换乘路段的01矩阵(为Frank Wolfe算法调用) %==========================================================================
四、算例及运行结果
1.算例1
路网如图1所示,已知站数据、线数据及站-线数据。给定起点v4,终点v8。求路径方案。
1.1 运行结果
修改luwangshuju.m——qidian=4;zhongdian=8;
>> KSP
KPaths = [1x5 double] [1x7 double] [1x5 double]KCosts =14.0000 15.5000 17.0000KHc_n = [2] [1] [2]KHc_hcd = {1x2 cell} {1x1 cell} {1x2 cell}KHc_hcqj = {2x1 cell} {1x1 cell} {2x1 cell}KHc_hcld_a = {1x2 cell} {1x1 cell} {1x2 cell}
1.2数据整理
查看并整理得:v4到v8有3条有效路径,排序后为KPaths,费用为KCosts,换乘次数分别为KHc_n,换乘区间为KHc_hcqj(换乘区间是换乘点到其紧后节点),换乘路段为KHc_hcld_a,数据见表1。表1 算例1计算结果
编号 KPaths KCosts KHc_n KHc_hcqj KHc_hcld_a k1 4->2->5->7->8 14 2 [2,5] [5,7] [5] [14] k2 4->2->1->3->5->7->8 15.5 1 [1,3] [2] k3 4->6->5->7->8 17 2 [6,5] [5,7] [16] [14] 2.算例2路网如图2所示,已知站数据、线数据及站-线数据。给定起点v2,终点v9。求路径方案。图2 某简单路网结构图2.1 运行结果
修改luwangshuju.m——qidian=2;zhongdian=9;
>> KSP
KPaths = [1x4 double] [1x4 double] [1x6 double]KCosts =11.0000 14.5000 16.0000KHc_n = [0] [1] [0]KHc_hcd = {1x1 cell} {1x1 cell} {1x1 cell}KHc_hcqj = {1x1 cell} {1x1 cell} {1x1 cell}KHc_hcld_a = {1x1 cell} {1x1 cell} {1x1 cell}
2.2数据整理查看并整理得:v2到v9有3条有效路径,排序后为KPaths,费用为KCosts,换乘次数分别为KHc_n,换乘区间为KHc_hcqj,换乘路段为KHc_hcld_a,数据见表2。表2 算例2计算结果
编号 KPaths KCosts KHc_n KHc_hcqj KHc_hcld_a k1 2->3->6->9 11 0 [] [] k2 2->5->8->9 14.5 1 [8,9] [25] k3 2->1->4->7->8->9 16 0 [] [] 五、结论及展望
在路网站点、线路、站点-线路关系已知时,通过输入起讫点可以计算出路径及其换乘次数。考虑换乘费用和有效路径后,路径数量大大减少,而过滤掉的路径为多余路径,在实际走行中不必考虑。该算法将在多领域得到应用,例如流量分配方面。六、代码下载
代码下载地址:
综合算法05—考虑换乘的K短路算法相关推荐
- 【阿良的算法之路】图论最短路算法模板
图论: [阿良的算法之路]图论最短路算法模板 [模板]dirjkstra单源最短路径 [模板]Bellman-Ford多源最短路 [模板]Spfa求最短路 [模板]Spfa判断负环 [模板]Floya ...
- 机器学习算法——系统性的学会使用 K近邻算法(KNN)
目录 1.K-近邻算法简介 1.1 什么是K-近邻算法 1.2 K-近邻算法(KNN)概念 (1)定义: (2)距离公式: 1.3 电影类型分析 1.4 KNN算法流程总结 2.k近邻算法api初步使 ...
- poj2449(k短路算法)
K 短路问题(A* 启发式广搜) 1.k 短路问题就是最短路问题的延申,要找出第 k 短的路径.用广搜进行路径查找,第一次找到的 就是最短路,第二次找到的是第 2 短 路⋯以此类推.所以我们只需要一直 ...
- 浅谈K短路算法(KSP)之二(YEN .J算法求解)
对于具有n个顶点和m条边且边的权值非负的简单图(无重边和环),K短路,是指的起点s到终点t的最短路径中第k个最小的.K短路分为有限制的K短路和无限制的K短路,有限制的K短路是指求得的路径中不含有回路( ...
- 浅谈K短路算法(KSP)之一(A*算法求解)
对于具有n个顶点和m条边且边的权值非负的简单图(无重边和环),K短路,是指的起点s到终点t的最短路径中第k个最小的.K短路分为有限制的K短路和无限制的K短路,有限制的K短路是指求得的路径中不含有回路( ...
- 第k短路 算法详解(图解)与模板(A* 算法)
本博文来自bestsort (转载请保留此信息) A*是一种启发式搜索,根据目标地点和当前点的距离和估计要走的步数来决策下一步走哪个方向.而这两个参数,一般用g(x)g(x)g(x)和h(x)h(x) ...
- ACM-ICPC 2018 沈阳赛区网络预赛 D. Made In Heaven (K短路算法模板)
题意 : 求第k短路的权值是否超过T(权值) 解法: 网上随便找的一个求K短路的算法模板套弄一下即可 (模板要好,不然邻接表存图会TLE , 网上换了两个模板才AC的) AC代码: #include& ...
- 我用Python把抖音上的美女图片转字符画,期望的AI目标更进一步【机器学习算法实战小项目,k聚类算法图片转化字符画】
大家好,我是辣条. 最近在学习算法,今天给大家带来一个机器学习实战小项目 项目效果展示 学习目标 1.cv2转换图片数据 2.numpy提取图片矩阵数据 3.k均值算法获取图片的分类 工具使用 开 ...
- zuc算法代码详解_最短路算法-dijkstra代码与案例详解
引言 在研究路径选择和流量分配等交通问题时,常常会用到最短路算法.用最短路算法解决交通问题存在两个难点: 一.算法的选择和程序的编写.最短路算法有很多种改进算法和启发式算法,这些算法的效率不同,适用的 ...
最新文章
- 概率和统计的matlab指令
- setlocal启动批处理文件中环境变量的本地化
- 9.1定时器 小时分秒
- Geth搭建以太坊主网公有节点笔记
- 无法解析com.oracle:ojdbc14:XXXXX问题解决方案
- 前照灯检测仪_前照灯检测仪
- 解决vue项目更新版本后浏览器的缓存问题
- 误删除数据恢复,试试这3个方法
- 人工智能AI系列 - 元宇宙 - 2D虚拟人
- cad画直线长度与实际不符_cad画规定长度直线的方法步骤图
- HTML网页图片背景以及图片自适应设置
- 接入支付宝支付 错误码4000,排查方法——开发记录
- 3dmax常见的八十个问题汇总
- APP加固新方向——混淆和瘦身
- springboot整合redis做缓存
- [CTO札记]武侠人物名称稀缺,上起点找吧
- buck电路上下管_Buck电路原理
- 高可用性系统在大众点评的实践与经验
- OrangeS一个操作系统的实现--保护模式
- 略论错误提示的人性化