公交查询系统最佳路线设计
公交查询系统最佳路线设计
摘要
本文研究的是在三种不同情况下,确定任意两站点最优路线问题。结合生活实际,我们定义最优路线标准是换乘次数最少,所用时间最短,乘车费用最低,并将其分别位作为第一、第二、第三目标建立多目标规划模型。利用广度优先遍历原理编程得到满意的乘车路线。
针对问题一,只考虑公交的情况下,对公交路线进行抽象化处理。根据网上调查结果,确定多目标规划模型,利用matlab 编程求解得到依次满足三个目标的任意两点的乘车路线。以下为6对起始站→终到站之间的部分可行路线: 起始→终到站 路线 转乘 时间/分 费用 S3359→S1828 436167335917841828L L S S S ????→????→(下)(下)
1 101 3 S1557→S0481 084080312()1557338923610481L L L S S S S ????→????→????→(下)(下)下
2 130
3 S0971→S0485 013417097121840485L L S S S ????→????→(下)(下) 1 128 3 S0008→S0073 159058000826830073L L S S S ????→????→(下)下)
1 83
2 S0148→S0485 024140104()0148034530370485L L L S S S S ????→????→????→(环)(下)下 2 130
3 S0087→S 3676 216506008701453676L L S S S ????→???→(下)
1
125
3
针对问题二,将地铁站点与其周围的公汽站抽象为同一站点。同样建立以转乘次数最少的为第一目标,所用时间短和费用低分别为第二、三目标的多目标规划模型。利用matlab 编程求解,得到满意的乘车路线。
针对问题三,以乘客所在站点为中心,步行时间上线为半径的区域内站点均考虑步行。将此区域内站点抽象为同一站点,建立多目标规划模型,进行编程求解,并与问题二结果进行比较。
关键字 多目标规划模型 广度优先遍历 抽象化
1、问题重述
1.1背景信息:
我国人民翘首企盼的第29届奥运会明年8月将在北京举行,届时有大量观众到现场观看奥运比赛,其中大部分人将会乘坐公共交通工具(简称公交,包括公汽、地铁等)出行。这些年来,城市的公交系统有了很大发展,北京市的公交线路已达800条以上,使得公众的出行更加通畅、便利,但同时也面临多条线路的选择问题。针对市场需求,某公司准备研制开发一个解决公交线路选择问题的自主查询计算机系统。
为了设计这样一个系统,其核心是线路选择的模型与算法,应该从实际情况出发考虑,满足查询者的各种不同需求。
1.2需要解决的问题:
1、仅考虑公汽线路,给出任意两公汽站点之间线路选择问题的一般数学模型与算法。并根据附录数据,利用你们的模型与算法,求出以下6对起始站→终到站之间的最佳路线(要有清晰的评价说明)。
(1)、S3359→S1828 (2)、S1557→S0481 (3)、S0971→S0485
(4)、S0008→S0073 (5)、S0148→S0485 (6)、S0087→S3676
2、同时考虑公汽与地铁线路,解决以上问题。
3、假设又知道所有站点之间的步行时间,请你给出任意两站点之间线路选择问题的数学模型。
2、模型假设与符号说明
2.1模型假设
假设1:相邻站点平均时间一定;
假设2:公交运行不出现交通堵塞,公交准时到达每个站点;
假设3:交通工具票价稳定,不考虑其他因素对票价的影响;
假设4:所有人的步行速度相等;
假设5:不会出现车辆拥挤或超载而使乘客误车的情况。
3、问题分析
本文主要研究的交通网络中的寻优问题,要求在三种不同情况下,找出任意两站点之间最佳路线。联系生活实际,考虑公众乘坐公交的出行,确定目标函数,找出乘客满意的乘车路线。
对于问题一,在仅考虑公汽线路的情况下,根据公众乘坐公交出行的考虑因素,建立以换车次数最少为第一目标,所花时间和费用最少分别为第二、第三目标下的多目标规划模型。通过题中给出数据运用matlab编程得到任意两点之间的乘车路线,再结合目标函数对所得路线进行筛选,找出换车次数最少,所花时间和费用较小的路线作为最佳路线。
对于问题二,在同时考虑地铁和公交的情况下。根据问题一中的抽象化方法,将地铁线路 T1抽象为一条单向的公交线路,T2抽象为一条环形的公交线路;对于地铁站点,由于地铁与邻近公汽站点可换乘,我们认为地铁站点与周围的公汽站点距离较近,将其抽象化为同一站点,重新构造站点间的关系矩阵。结合问题一,建立优化模型进行编程求解。
对于问题三,将步行考虑在出行方式中。一般来说,出行者选择步行的目的是为了减少换乘次数或花费时间。当两个站点相邻近时,乘客才愿意选择步行换乘,因此我们需确定一个邻近站点的范围界限。但考虑到本文的目标之一是所用时间最短,为此将邻近站点的范围界限转化为时间界限,即所用步行时间在某一范围之内时,乘客才考虑步行。基于这种思想,再结合问题一,确定多目标优化模型进行编程求解。
4、数据处理
4.1对站点数据处理
利用matlab编程从文本中按行读取数据,将每一行数据作为一个元胞,按行存放在元胞矩阵中,如下图1示:
L001
分段计价
S0619-S1914..
元胞1
元胞
2
元胞3
…
元胞...
4.2地铁线路的抽象处理
地铁与邻近公汽站点可换乘说明地铁站点及其周围的公汽站点距离较近,所以考虑将其抽象为新的站点,如下图2:
4.3公交乘客出行心理调查分析:
在研究乘公交出行最优算法时,首先要了解乘客出行时所要考虑的因素。通过对公交乘客的出行心理、行为的调查研究来确定模型的优化目标及约束条件是必要的。
根据网上搜索得到合肥市关于公交乘客出行需求的调查结果,如图3所示:
从图中可以看出公交乘客在出行时,考虑最多的是换乘次数,其次时间最短(在此将时间最短和路程最短统一作为时间最短来考虑)和费用最少。所以在换乘次数已经确定的情况下,选择时间较短和费用较少的路线作为最佳路线。
4.4所能接受的最长步行时间调查表:
结合实际情况,乘客对距离较近的站点会考虑步行换乘,省钱的同时也可能节省时间。当步行时间较短时,才会选择步行。以下是通过网上搜索得到的换乘时乘客所能接受的最长时间调查表,如下图4:
通过观察发现,大多数人所能接受的最长步行时间是6-10分钟。所以对于问题三,我们考虑以步行8分钟为乘客的步行时间上限。
5、 问题一的解答
5.1模型建立
根据问题一的分析,建立以换车次数最少为第一目标,所花时间和费用最少分别为第二、第三目标下的多目标规划模型。 5.1.1确立目标函数: 目标一:转乘次数最少
设从始发站到终点站总共转乘次数为Y ,则转乘次数最少的目标函数:
min Y
目标二:所用总时间最短
总时间包括转乘时间和经过站点所用时间,得所用时间最少的目标函数:
11min T tx t y =+
目标三:所花费用最少
判断线路i 是否为分段计价:
{
1i i u w =单一票价 分段计价
在路线1(1)i i y ≤+(分段计价)经过站数为i x ,则:
1(020)2(2140)3(40)
i i i i x w x x <≤??=<≤?>??
得出所花费用最少的目标函数:
11
1min y i i W u +==∑
5.1.2确定约束条件
在分段计价路线上经过的站不超过A B →经过的共站点,即:
11
1
y i
i x
x +=≤∑
只考虑换乘次数不超过两次的情况下的乘车路线,得:
12y ≤
综上得问题一的多目标优化模型为:
min min min Y T W ????? 11
1
1.2
y i i x x
s t y +=??≤??≤?∑
5.2模型求解:
5.2.1求出换乘次数最少的可行路径
设S(A) 、S(B)分别为经过起点A 、终点B 的所有公汽线路的集合,即
(){|1,2,3}i S A A i a == ,(){|1,2,3}j S B B j b == 设第i
条线路123,,i i i i im A A A A A = ,其中1,i im A A 分别表示第i 条线路的起点和终点;第j
条线路123,,j j j j jn B B B B B = ,其中1,j jn B B 分别表示第j 条线路的起点和终点。算法如下:
1、 若()()S A S B ?≠?,即存在,i j 使i j A B =,表示站点A,B 间可以通过一次乘车直接到达,线路如:
i j
A B
A B =???→
找出经过站点最少的路线作为最优路线。
2、 若()()=S A S B ??,则A,B 两站点间没有直达路线,需要换乘。模型只考虑换成两次的情况:
① 一次换乘:经过起点站A 的某条公汽线路与经过终点B 的某条公汽线有公共站点()ip jq A B ,得出线路如:
()j
i B
A ip jq A A
B B ??→??→
若可以一次转乘,则计算出起始站与终点站间经过站点最少的路线为最优路
线。
② 二次换乘:设()S C 为()S A 中所有能转乘车次的集合
(){|1,2,3}r S C C r c ==
如果()()S C S B ?≠?,即存在rp jq C B =,则找出此交集,并按顺序找出这个交集中的车由哪些车次转来,可知经两次转车可达到目的站点。路线如下:
()()j i r
B A
C i r rp jq A A C C B B ??→??→??→ 计算出A,B 之间所经站点最少的路线作为最优路线。
5.2.2算法步骤:
首先我们将文本数据按行存在一个元胞矩阵的每一行中,然后从外部输入要
查询线路的起点与终点。
查找线路时,我们先考虑能否直达,步骤如下: a. 建立一个记录经过某一点的所用线路的函数; b. 然后将输入的点分别代到上述函数中,分别得到经过起点A 和终点B 的所有线路S(A),S(B);
c. 判断两者是否在S(A)=S(B)。如果存在,将A,B 两之间经过的站点数n 记录下来,与初始A,B 间站点数0n (初始值设为无穷大)比较。如果0n n <,则记录次线路,同时将0n 赋值为n ;否则舍去此线路;
d. 以此循环,直到找出所有S(A)=S(B)且n 最小的情况。 考虑转乘一次,步骤如下:
a. 先输入始发站A ,搜索经过A 的所有线路S(A);
b. 然后在上述线路上分别用A 之后的每个站点搜索经过它的所有线路;
c. 重复直达的情况下的算法步骤。
考虑转乘两次和上面一样,不同的是在转乘一次的基础上增加一个搜索线路。
5.2.3模型结果
依照以上的算法步骤,运用matlab 编程进行求解。在路线的选择时,首先考虑换乘次数最少的,其次是经过站点最少(所用时间最少),最后考虑的是费用。问题一的具体结果如下:
5.3结果分析
从以上六个表中的数据可以看出,根据模型求出的任意两点之间所用时间和费用均相等,乘车路线也无太大差异,所以以上所有路线均可供乘客选择。
6、 问题二的解答
6.1模型建立
将地铁与相邻公交站点抽象为同一站点,结合问题一,建立以转乘次数最少为第一目标,所用时间和费用最少分别第二、三目标的多目标优化模型。 6.1.1确定目标函数 目标一:换乘次数最少
总换乘次数为两种交通工具互转乘次数的和,得转乘次数最少的目标函数:
1234min ()Y y y y y =+++∑ 目标二:所花时间最少
总时间包括转乘时间和经过站点所用时间,其中乘公交所用时间
1T xt =
乘地铁所用时间
2T x t ''=
则所用总时间最少的目标函数:
1211223344min ()T T T y t y t y t y t =+++++
目标三:所花费用最少
总费用等于各条路线上所花费用之和。判断线路i 是公交线还是地铁线;若i 为公交线,判断线路i 是单一票价还是分段计价
1i i u ??=???公交(单一票价)
w 公交(分段计价)
3
地铁
得总费用最少的目标函数:
+1
1min Y i i W u ==∑
6.1.2确定约束条件
总转乘次数少于两次:02()Y Y N ≤≤∈ 综上得问题二多目标模型为:
min min min Y T W
????? .02()S t Y Y N ≤≤∈
6.2模型求解
依照问题一的算法步骤,运用matlab 编程进行求解得出题中6对起始站→终到站之间的最佳路线。
7、 问题三的解答
7.1模型建立:
根据分析,当步行时间在某一范围之内乘客时才会选择步行。以乘客所在的站点为中心,以步行时间上限为半径,找出在范围内的所有站点(邻近点)。同问题二,将这些点抽象为同一点,如下图:
7.1.1确定目标函数
目标一:换乘次数最少
1234min ()Y y y y y =+++∑
目标二:所花时间最短 乘公交所用时间:
1T xt =
乘地铁所用时间:
2T x t ''=
步行所花时间:
3pq T x t ''=∑
其中{
1pq x =站点p,q 间步行0站点p,q 间不步行
得出从始发站到终点站所用时间最少的目标函数为:
12311223344min ()T T T T y t y t y t y t =++++++
目标三:所花费用最少
同问题二,总花费最少的目标函数:
+1
1min Y i i W u ==∑
7.1.2确定约束条件:
从站点p 到站点q 所花时间不超过乘客步行时间上限:
pq t t ''≤
总转乘次数不超过两次:
02()Y Y N ≤≤∈
综上得问题三的多目标优化模型:
min min min Y T W
????? {
02.pq
Y s t t t ≤≤''≤
8、 模型的评价、改进及推广
8.1模型评价
8.1.1优点:
1、模型舍弃了对问题影响不大的因素,只保留换乘次数,乘车时间,所花费用这几个核心目标建立模型,使问题简化清晰。
2、根据网上搜索的公交乘客出行调查表的结果确立目标函数,使模型更贴近实际情况。
3、模型将距离较近的站点抽象为同一站点,使问题得到简化。
8.1.2缺点
1、在模型中我们只考虑了最多两次转乘就能够到达目的地的情况。如果2次转乘还不能到达目的地本模型将不能给出答案。
2、本模型没有考虑到乘客在乘公交时的其他需求,如沿途观光旅游等。
8.2模型改进
1、像观看奥运会这样的大型赛事,对游客而言,更希望在乘车途中可观赏到北京的特色景观及建筑,如奥运场馆、名胜古迹等。基于这些因素,我们所设计的查询系统在给出常规最佳路线的同时,也应提示一条观光路线供乘客自由选择。
2、题中给出的是一个静态的交通系统,只要给出始发站和终点站,我们就可以通过算法求得可行路线。但是在现实生活中,交通系统随时都可能在发生变化,常见的如:上下班时候的高峰期,由于交通事故某两个站点之间的线路暂时中断等,这些在本题中都没有能够反应出来。所以应考虑从实际出发,建立动态系统模型,可以根据最新的数据信息得出最优方案。
8.3模型推广
本文解决的是最佳路线的设计问题,结合实际情况建立优化目标模型。本模型不仅适用于乘车路线的选择,还可用于观光旅游及公交站点位置的选择等。
9、参考文献
【1】邓化宇李康弟黄建雄,改进的Dijkstra矩阵算法在城市公交线路选择中的应用[J],上海电力学院学报,第25卷第1期;
【2】王林曹帅王欢李扬,基于广度优先的城市公交出行线路选择[J],沈阳化工学院数理系,辽宁沈阳,110142;
【3】扈震张发勇刘书良,城市公交换乘数据模型研究及算法实现[J],中国地质大学信息工程学院,湖北武汉,430074
【4】百度,出行者所期望的地铁与公交换乘步行时间和换乘候车时间问卷调查表,(https://www.360docs.net/doc/6c5072000.html,/report/222042.aspx)
附录
基本参数设定
相邻公汽站平均行驶时间(包括停站时间):3分钟
相邻地铁站平均行驶时间(包括停站时间): 2.5分钟
公汽换乘公汽平均耗时:5分钟(其中步行时间2分钟)
地铁换乘地铁平均耗时:4分钟(其中步行时间2分钟)
地铁换乘公汽平均耗时:7分钟(其中步行时间4分钟)
公汽换乘地铁平均耗时:6分钟(其中步行时间4分钟)
公汽票价:分为单一票价与分段计价两种,标记于线路后;其中分段计价的票价为:0~20站:1元;21~40站:2元;40站以上:3元
地铁票价:3元
问题一的matlab程序
%%
%function main
clear ;clc;
s0=input('请输入起点站\n');
s1=input('请输入终点站\n');
%s0='S3359';s1='S1828';
n=0;a={};b1={'线路/过站数'};
a1=fopen('d:/我的文档/桌面/1.1 公汽线路信息.txt');
while n<520*4+1
t=fgetl(a1);
n=n+1;
if ischar(t)
a=[a;t];
end
end
k1=f(a,s0);
k2=f(a,s1);p0=inf;
%直达
for i=1:size(k1,1)
for j=1:size(k2,1)
if
k1{i}(1)==k2{j}(1)||k1{i}(1)+1==k2{j}(1)||k1{i}(1)-1==k2{j}(1)
b=[s0];p=g(a,s0,s1);
m=k1{i}(1);
for i1=1:4
m=m-1;
if strncmp(a{m},'L',1)
b=[b,'-',a{m},'-',s1,' ',p];
if all(strcmp(b,b1(size(b1,1),:)))||p>p0
b=[];
else
b1=[b1;b];p0=p;
end
end
end
end
end
end
if size(b1,1)~=1
disp(b1);
break;
end
%转乘一次
for i=1:size(k1,1)
for i1=k1{i}(2):6:size(a{k1{i}(1)},2)-4
k3=f(a,a{k1{i}(1)}(i1:(i1+4)));
p1=g(a,s0,a{k1{i}(1)}(i1:(i1+4)));
p2=g(a,a{k1{i}(1)}(i1:(i1+4)),s1);
for i2=1:size(k3,1)
for j=1:size(k2,1)
if
k3{i2}(1)==k2{j}(1)||k3{i2}(1)+1==k2{j}(1)||k3{i2}(1)-1==k2{j}(1)
b=[s0];p=p1+p2;
m1=k1{i}(1);
for i3=1:4
m1=m1-1;
if strncmp(a{m1},'L',1)
b=[b,'-',a{m1},'-',a{k1{i}(1)}(i1:i1+4)]; end
end
m=k3{i2}(1);
for i4=1:4
m=m-1;
if strncmp(a{m},'L',1)
b=[b,'-',a{m},'-',s1,' ',num2str(p)];
if all(strcmp(b,b1(size(b1,1),:)))||p>p0 b=[];
else
b1=[b1;b];p0=p;
end
end
end
end
end
end
end
end
if size(b1,1)~=1
disp(b1);
break;
end
%转乘两次
for i=1:size(k1,1)%确定线路
for i1=k1{i}(2):6:size(a{k1{i}(1)},2)-4%确定站点
k3=f(a,a{k1{i}(1)}(i1:(i1+4)));
p1=g(a,s0,a{k1{i}(1)}(i1:(i1+4)));
for i2=1:size(k3,1)%再次确定线路
for i3=k3{i2}(2):6:size(a{k3{i2}(1)},2)-4%确定站点
k4=f(a,a{k3{i2}(1)}(i3:(i3+4)));
p2=g(a,a{k1{i}(1)}(i1:(i1+4)),a{k3{i2}(1)}(i3:(i3+4)));
p3=g(a,a{k3{i2}(1)}(i3:(i3+4)),s1);
for i4=1:size(k4,1)%确定线路
for j=1:size(k2,1)%经过终点站的线路
if
k4{i4}(1)==k2{j}(1)||k4{i4}(1)+1==k2{j}(1)||k4{i4}(1)-1==k2{j}(1) b=[s0];p=p1+p2+p3;
m1=k1{i}(1);
for i5=1:4
m1=m1-1;
if strncmp(a{m1},'L',1)
b=[b,'-',a{m1},'-',a{k1{i}(1)}(i1:i1+4)];
end
end
m2=k3{i2}(1);
for i6=1:4
m2=m2-1;
if strncmp(a{m2},'L',1)
b=[b,'-',a{m2},'-',a{k3{i2}(1)}(i3:(i3+4))];
end
end
m3=k4{i4}(1);
for i7=1:4
m3=m3-1;
if strncmp(a{m3},'L',1)
b=[b,'-',a{m3},'-',s1,' ',num2str(p)];
if
all(strcmp(b,b1(size(b1,1),:)))||p>p0
b=[];
else
b1=[b1;b];p0=p;
end
end
end
end
end
end
end
end
end
end
disp(b1);
%子函数,搜索经过该点的线路
%function k1=f(a,n)
%k1={};
%for i=1:size(a,1)
% k=0;
% k=findstr(a{i},n);
% if k~=0
% k1=[k1;[i,k]];
% end
%end
%计算过站数
%function p=g(a,s0,s1)
%k1={};k2={};p=inf;
%for i=1:size(a,1)
% k=0;
% k=findstr(a{i},s0);
% if k~=0
% k1=[k1;[i,k]];
% end
%end
%for i=1:size(a,1)
% k=0;
% k=findstr(a{i},s1);
% if k~=0
% k2=[k2;[i,k]];
% end
%end
%for i=1:size(k1,1)
% for j=1:size(k2,1)
% %起始站与终点站在同一条线路,终点站在后
% if k1{i}(1)==k2{j}(1)&&k1{i}(2)<=k2{j}(2)
% p=(findstr(a{k2{j}(1)},s1)-findstr(a{k1{i}(1)},s0))/6; % end
% %起始点在“上行线”,终点在“下行线”||起始点在“下行线”,终点在“上行线”
% if k1{i}(1)+1==k2{j}(1)||k1{i}(1)-1==k2{j}(1)
%
p=(findstr(a{k2{j}(1)},s1)-4+size(a{k1{i}(1)},2)-4-findstr(a{k1{i}(1) },s0))/6;
% end
% %起始站与终点站在同一条线路,终点站在前
% if k1{i}(1)==k2{j}(1)&&k1{i}(2)>k2{j}(2)
% if a{k1{i}(1)}(1)=='上'
%
p=(size(a{k1{i}(1)},2)-4-findstr(a{k1{i}(1)},s0)+findstr(a{k2{j}(1)}, s1)-4+size(a{k1{i}(1)+1},2)-8)/6;
% end
% if a{k1{i}(1)}(1)=='下'
%
p=(size(a{k1{i}(1)},2)-4-findstr(a{k1{i}(1)},s0)+findstr(a{k2{j}(1)}, s1)-4+size(a{k1{i}(1)-1},2)-8)/6;
% end
% if a{k1{i}(1)}(1)=='环'
%
p=(size(a{k1{i}(1)},2)-4-findstr(a{k1{i}(1)},s0)+findstr(a{k2{j}(1)}, s1)-4)/6;
% end
% if a{k1{i}(1)}(1)=='S'
%
p=(size(a{k1{i}(1)},2)-4-findstr(a{k1{i}(1)},s0)+size(a{k2{j}(1)},2)-4-findstr(a{k2{j}(1)},s1))/6;
% end
% end
% end
%end