数学建模.docx
《数学建模.docx》由会员分享,可在线阅读,更多相关《数学建模.docx(28页珍藏版)》请在冰豆网上搜索。
![数学建模.docx](https://file1.bdocx.com/fileroot1/2023-2/9/052ec879-1058-418d-a89c-c1998f4833eb/052ec879-1058-418d-a89c-c1998f4833eb1.gif)
数学建模
公交查询系统核心算法的讨论
摘要
问题一,我们采用C++ 编程实现最佳路线的查找,采用广度优先算法,依次讨论了零次换乘,一次换乘,两次换乘以及三次换乘的情况,求解了题目所给的站点,分别求出了三种衡量标准对应的最佳路线。
本文以转乘次数最少为首要目标,以路线经过站点最少、路线行车耗时最短为第二目标,考虑费用作为第三目标来设计算法,根据乘客的特殊要求,选出最符合乘客要求的路线。
在我们求出的解中,例如以换乘最少为衡量标准,问题一中的6组站点的最优路线为:
S3359→S1828在S3359站乘436路(下行)在S1784转167路车(下行)到终点S1828
S1557→S0481行车线路:
在S1557站乘0084路(下行)在S1919转189路车(下行)在S3186转460路下行车到终点S0481
S0971→S0485行车线路:
在S0971乘013路(下行)在S2184转417路车(下行)到终点S0485
S0008→S0073行车线路:
在S0008乘坐355路(下行)在S2303转345路车(上行)到达终点S0073
S0148--S0485行车线路:
在S0148乘坐308路在S0036转156路车在S2210转417路车到达终点S0485
S0087→S3676行车线路:
在S0087乘坐454路(上行)在S3496转209路车(下行)到达终点S3676
问题二,考虑到地铁站时,我们采取一种方式:
例如T1号线,我们把这条地铁线经过的所有的公汽站点依次罗列,这样就构成了一条较长的公汽行车线路,当然,原来在同一个地铁站的公汽站点被处理成了相邻的公汽站点,我们可以对程序输出这样的可行路线进行观察,进一步处理,将那条较长的公汽线路再转换成地铁路线,这样,就可以求出实际的行车路线。
其中,在问题二中,考虑地铁站之后,新线路的耗时可能会减少,例如S0008→S0073行车线路:
150路(下行)转(3874——D30)T2路车再转(D25——0525)103路(上行)车,时间缩短为55分钟;程序输出了第6组站点间的一条直达线:
T2号线(D27----D36)。
可以确定:
在以换乘次数为衡量标准时,此为最优。
其它站点也求得相应的最优路径,详述见正文部分。
问题三中,当考虑了步行之后,就可以将可能的路线中公交线路仅经过两站或三站的公交路线换为步行。
这样可以提高转乘一次和两次的覆盖率,大大减少了转三次车甚至更多次的必要。
具体的算法是可以把终点或者起点附近的站点作为新的终点和起点,然后利用新起点终点组合搜索路线,这样可以得出,两次转车或三次转车不能覆盖的路线。
在最后提出了以“查找表”思想辅助该算法,实现空间和时间的充分利用。
关键字:
查找表、线集合相交思想、公交换乘、广度优先算法,
1问题重述
公交查询系统是每个城市的重要公共设施,它方便了游客,学生以及其他的外来人员在城市中出行。
特别是第29届奥运会明年8月将在北京举行,届时有大量观众到现场观看奥运比赛,其中大部分人将会乘坐公共交通工具出行。
为了使得公众的出行更加通畅、便利,就面临多条线路的选择问题。
研制开发一个解决公交线路选择问题的自主查询计算机系统迫在眉睫。
为了设计这样一个系统,其核心是线路选择的模型与算法,应该从实际情况出发考虑,满足查询者的各种不同需求。
应该解决如下问题:
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问题分析时应该考虑的各种因素
公交查询系统的应该根据乘客的要求来设计。
对于大多数乘客来说,选择路线时最先考虑的是转乘的次数要少,其次是所选的路线的行车耗时,再者是路线的费用;但是也不排除有的乘客的考虑因素的侧重点不同。
2.2转乘次数、行车耗时、费用之间的关系
一般来说,转乘的次数决定了行车耗时和费用。
但是在有地铁的情况下,增加一次或者两次转车,可能会缩短行车耗时,但这毫无疑问增加了费用。
所以,转乘次数、行车耗时、费用对选择路线的重要性依次递减,但当路线中出现地铁的时候(即问题二所考虑的情况)应该考虑运行的费用。
2.3原始数据处理
一般的公路查询系统的数据的格式都采用数的形式存储,里面包括线号以及站号等信息,本文的数据处理非常简单,只是把把数据以数组的形式存起来,每条线路(L001—L520)包括上行线及下行线,共1040行,每行中储存的是路线上依照行驶到达顺序的站点号码,这样可以根据行号确定改改行站点号是那一条公交线路,实上行的还是下行的。
当处理地铁时,把两条地铁线加在公交路线的后面,代号由D1,D2改为L521,L522,在数组中添加四行来增加两条地铁的上下行路线。
2.3对于算法的选择
一点需要说明的是求最短路径一般使用Dijkstra算法,该算法可求出任一源点到其它所有网络结点的最短路径。
但是,我们的目的是求得任意一个点到另外任意一个点的最优路径,用这一经典算法算出的结果太繁杂,太浪费时间;所以,我们将起点和终点两头考虑,利用广度优先算法,这样行车线路查找范围就大大缩小了,当然,对于这种算法,站点和行车线路之间要灵活考虑,力求算法最简、最优。
3模型建立及求解
3.1问题一
3.3.1模型假设:
1、考虑到实用性,3次以上的换乘不会被查询者接受;
2、假设该地区的公交运行状况良好,很少出现堵车现象;
3、假设当两个转乘站之间的距离小于等于两站时,可以选择步行;
3.3.2参数说明:
A——起始站点;
B——终点站;
Ti——转乘站点;
3.1.2模型建立与算法分析
在题目所给的520条公汽线和2条地铁线中,考虑一对的车站间的最优路径,从不同的衡量角度有不同的结果,若从换乘次数考虑,则首先,最容易想到的是直达,如(图1)
图1
我们用C++编程来解决查找行车路线问题,然后再根据不同的衡量标准来确定最优解,下面再介绍另一种情况:
换乘1次,如(图2),T1,T2为中转站:
图2
对于以上两种情况,我们编写了程序qq1.cpp。
对题目要求的6对车站进行了求解,求得了所有经过直达或转乘1次的行车路线,并依据不同的衡量角度对结果进行了求取最优路径。
下面介绍一下程序qq1.cpp算法:
首先导入题目所给数据,一共520路行车路线,每条路线包括上下行,构成共1040条单向路线,在程序中,我们用1040×100的二维数组获取所有的站点信息,其中数字100是用来存放每条线路所包含的站点,接下来的算法是对这一个二维数组进行处理:
零次、一次换乘
零次换乘即在起点A和终点B之间有公交车直接往返,用户无需经过换乘就可以直达目的站点(如下图)。
一次换乘即在起点A和终点B之间没有公交车直接往返,用户需要在途经的某个站点下车,然后转乘另一线路公交车才能到达目的站点。
(1)首先获取起点A和终点B;
(2)求出所有经过起点A和终点B的线的集合R(A)和R(B),在集合R(A)中,将任意一条路线上点A以后的点求出,构成一个点的集合point(A),在集合R(B)中,将任意条路线上点A以后的点求出,构成一个点的集合point(B),图3中的小叉圆表示
图3
(3)设定一个循环,比较集合point(A)和point(B)中的每一个站点,如果有相同的站点T,则由路线连通A,B,此时再比较相同的站点T,如果T属于同一行,则存在至大路线,如果不同那就是要转一次车;
如果仍然查找不到换乘方案,可以考虑两次换乘。
我们接下来讨论两次换乘的情况如(图4):
两次换乘:
两次换乘就是当经过一次换乘不能到达目的地时,例如题目所给数据的第2组(S1557-S0481)和第5组(S0148-S0485),利用两次换乘可以扩大选择线路的范围,增大存在可行路线的概率,qq2.cpp对二次换乘的算法进行了描述。
(1)获取起点A和终点B;
(2)求出所有经过起点的线的集合R(A),在集合R(A)中,将每条路线上点A以后的点求出,构成一个点的大集合point(A),图4中的小叉圆表示
(3)以集合point(A)中的每一个点为源起点,从上图中的T1到B作一次换乘计算,如果T2点存在,即可以求出T2点
(4)这样A->T1->T2->B就构成了一条经过两次转乘的行车路线。
如果还没有找到,则进行三次转乘,但是两次转乘的路径覆盖已经很广,三路转乘只是为了得出更短的路径,当然,这是以转乘次数为代价的。
三次转乘
经过三次转乘之后,我们没有必要再考虑四次转乘,因为其路线的覆盖已经近100%,况且四次转乘的路线一般不会被乘客采纳。
qq3.cpp对三次换乘的算法进行了描述,以下是四次转乘的示意图(图5)和算法:
图5
(1)获取起点A和终点B;
(2)求出所有经过起点的线的集合R(A),在集合R(A)中,将每条路线上点aa以后的点求出,构成一个点的集合point(A),图4中的小叉圆表示;
(3)求出所有经过起点的线的集合R(T),在集合R(T)中,将每条路线上点bb以前的点求出,构成一个点的集合point(B),图4中的小叉圆表示;
(4)设定一个双循环,使得point(A)任意一点T1与point(B)中的任意一点T3点都能组合一次;
(5)对T1与T3的每一对组合进行一次换乘计算,这样,构成的A—T1—T2—T3—B线路就是所要求得三次转乘线路;如果连经过三次转乘都没有可行路线,则说明该地区公交线分布存在缺陷。
多次换乘
通过以上的三次以内的换乘求解规律,我们不难得出多次换乘的求解方法,多次换乘方案的计算,实际上是一次换乘计算的递归执行。
而超过三次换乘的方案,一般是用户不能接受的,本文不再详细求解。
根据以上的基于换乘次数的行车路线,我们可以求得耗时最短的行车路线,也可以求出花费最少的行车路线,一般情况下,换乘次数少,花费少;从起点到终点经过的站点少,耗时就少。
3.1.3模型的分析求解
在仅考虑公汽线路的情况下为了满足广大市民的不同乘车要求分类对行车线路进行筛选。
首先我们分析出一条线路所包含的信息有:
转车次数,车次,行车站数,行车耗时,花费钱数。
利用我们编写的程序可以在已知始发站与终点站的情况下,查找出所有的可能乘车路线,路线分为四类:
直达车,转乘一次,转乘两次,转乘三次(我们遍例了所有的车站之间的行车路线最高三次就能完成)并已经过车站数目为首要因素对所有可能的线路进行排队并取前五位候选。
这样就列出了一些乘车线路作为被选路线。
我们再对人们出行乘坐公交选择路线考虑的不同因素进行分析。
我们发现人们有时想以最快的乘车方式到达目的,以节省时间;有时想花较少的钱到达目的地,浪费点时间无所谓;有时想减少换乘车辆的次数,少走些路;更为复杂的时候,北京交通繁忙繁华地段经常堵车,有的人更愿意乘坐地铁这种交通工具,因为它非常守时。
为了综合考虑各个因素我们试图对不同选择因素的权重进行分析,但我们考虑到实际情况下,人们乘坐公交选择路线时往往是考虑比较单一的因素。
也就是说我们再给不同因素付权重的时候只要根据不同的需求将某一因素负值为一即可。
即当希望尽快到达目的时可以仅考虑时间进行挑选,当希望少花钱时就以花钱多少作为标准进行挑选。
当然在输出乘车线路时我们间输出多条路线被选,以便个人综合考虑各种因素的影响。
下面是利用我们的模型与算法,以下6对起始站→终到站之间的最佳路线要以及全面的评价说明
(1)、S3359→S1828
(2)、S1557→S0481(3)、S0971→S0485
(4)、S0008→S0073(5)、S0148→S0485(6)、S0087→S3676
以上六组数据在不考虑有地铁的情况下没有可以直达的车辆存在,
(1)、(3)(4)、(6)组最少转乘一次公车才能到达目的地,
(2)、(5)组最少转乘两次才能到达目的地。
注:
程序计算的可供选择路线见“问题一附录”:
第一组S3359→S1828
1、换乘次数最少:
在S3359站乘436路(下行)在S1784转167路车(下行)到终点S1828
途经车站数32花费3元耗时101分钟(可步行,走一站节约一元)
2、耗时最少:
在S3359站乘015路(下行)在S2903转485路车(下行)在S1784转167路车下行到终点S1828
途经车站数18花费3元耗时64分钟(可步行,走两站节约两元)
3、花费最少
在S3359站乘436路(下行)在S1784转167路车(下行)到终点S1828
途经车站数32花费3元耗时101分钟(可步行,走一站节约一元)
第二组S1557→S0481
1、换乘次数最少:
行车线路:
在S1557站乘0084路(下行)在S1919转189路车(下行)在S3186转460路下行车到终点S0481
途经车站数32花费3元耗时106分钟(可步行三站节约一元)
2、耗时最少:
行车线路:
在S1557站乘084路(下行)在S1919转189路车(下行)在S3186转091路下行车在S0902转239路下行车到终点S0481
途经车站数28花费4元耗时99分钟
3、花费最少:
行车线路:
在S1557站乘363路(下行)在S1919转189路车(下行)在S3186转460路下行车到终点S0481
途经车站数32花费3元耗时106分钟(可步行三站节约一元)
第三组S0971→S0485
1、换乘次数最少:
行车线路:
在S0971乘013路(下行)在S2184转417路车(下行)到终点S0485
途经车站数41花费4元耗时128分钟(可步行两站节约两元钱)
2、耗时最少:
行车线路:
在S0971乘013路(下行)在S2517转290路车(下行)在S2159转469路上行车到终点S0485
途经车站数31花费3元耗时103分钟(可步行两站节约一元)
3、花费最少:
行车线路:
在S0971乘013路(下行)在S2517转290路车(下行)在S2159转469路上行车到终点S0485
途经车站数31花费3元耗时103分钟(可步行两站节约一元)
第四组S0008→S0073
1、换乘次数最少:
行车线路:
在S0008乘坐355路(下行)在S2303转345路车(上行)到达终点S0073
途经车站数26花费2元耗时83分钟
2、耗时最少:
②行车线路:
在S0008乘坐043路(下行)在S1383转290路车(下行)在S2184转345路上行车到达终点S0073
途经车站数19花费3元耗时67分钟(可步行一站节约一元,四站节约两元)
3、花费最少:
行车线路:
在S0008乘坐355路(下行)在S2303转345路车(上行)到达终点S0073
途经车站数26花费2元耗时83分钟
第五组S0148--S0485
1、换乘次数最少:
行车线路:
在S0148乘坐308路在S0036转156路车在S2210转417路车到达终点S0485
途经车站数32花费3元时间106分钟(可步行三站节约一元)
2、耗时最少:
行车线路:
在S0148乘坐308路在S3604转081路车在S2361转156路车在S2210转051路车到达终点S0485
途经车站数29花费4元时间102分钟
3、花费最少:
行车线路:
在S0148乘坐308路在S0036转156路车在S2210转417路车到达终点S0485
途经车站数32花费3元时间106分钟(可步行三站节约一元)
第六组S0087→S3676
1、换乘次数最少:
行车线路:
在S0087乘坐454路(上行)在S3496转209路车(下行)到达终点S3676
途经车站数20花费2元时间65分钟
2、耗时最少:
行车线路:
在S0087乘坐021路(下行)在S0088转231路车在S0427转L097路(上行)车达终点S3676
途经车站数12花费3元时间46分钟(可步行一站节约一元,两站节约两
3、花费最少:
行车线路:
在S0087乘坐454路(上行)在S3496转209路车(下行)到达终点S3676
途经车站数20花费2元时间65分钟
总结以上六组可以看出存在很多通过多转一次车达到节省时间的目的的例子。
这在现实生活中也是很正常的,符合实际。
3.2问题二:
在同时考虑地铁线的时候,可以将地铁作为特殊的公交线路放到第一问的解题算法中进行处理输处结果。
把地铁各站对应的汽车站依照地铁站的顺序依次排成一条线作为一条公交线排在520条公交后面进行处理,这样地铁线T1对应公交线521,地铁线T2对应公交线522。
这样,问题二中,共含有522路行车路线,处理方法同问题一。
当输出的结果中含有公交线521或522时,将线路对应站点根据题目给出的地铁线换乘公交信息表,再将521或522转换成地铁T1或T2号线得出结果。
考虑到地铁的特殊性(不会发生堵车情况),可以在公交线路堵塞时起到不可替代的作用。
所以我们至少保留一组可以通3过地铁到达目的地的路线可供选择。
可供选择路线见“问题二附录”;
输出并整理过的线路如下:
(1)、S3359→S1828
行车线路:
474路(上行)转(0856—D28)T1路车再转(D34——0578)167路车(下行)
途经车站数38花费5元时间124分钟(D28-----D34)
评价:
与不加地铁比较此线路在时间,花耗,费用等方面均没有优势
只可能在公交堵车时选用。
最优路径相比问题一不变。
(2)、S1557→S0481
行车线路:
084路(下行)转(0978—D32)T2路车再转(D24——0537)516路(上行)车
途经车站数35花费5元时间114分钟(D32-----D24)
评价:
与不加地铁比较此线路在时间,花耗,费用等方面均没有优势
只可能在公交堵车时选用。
最优路径相比问题一不变。
(3)、S0971→S0485
行车线路:
094路(上行)转(0567——D01)T1路车再转(D20——2079)417路(下行)车
途经车站数32花费5元时间99.5分钟(D01-----D20)
评价:
与不加地铁比较此线路多花费两元钱,但是省时3.5分钟,优势很不明显,所以可能在公交堵车时选用。
最优路径相比问题一改变。
耗时最少:
99.5分钟
(4)、S0008→S0073
行车线路:
150路(下行)转(3874——D30)T2路车再转(D25——0525)103路(上行)车
途经车站数15花费5元时间55分钟(D30-----D25)(步行两站节约一元)
评价:
与不加地铁比较此线路少走了11站,省时50.9%,只是多花两元钱。
所以只有在少花钱的情况下选择非地铁线路。
最优路径相比问题一改变。
耗时最少:
55分钟
(5)、S0148→S0485
行车线路:
308路(上行)转(0302——D03)T1路车再转(D20——2079)417路(下行)车
途经车站数28花费5元时间67.5分钟(D03----D20)
评价:
与不加地铁比较此线路少走了4站,省时57.0%,只是多花两元钱。
所以只有在少花钱的情况下选择非地铁线路。
最优路径相比问题一改变。
耗时最少:
67.5分钟
(6)、S0087→S3676
行车线路:
地铁一号车站10[T]花费3元时间25分钟(D27----D36)
评价:
此线路是六组中唯一直达路线,优势非常明显。
3.3问题三
3.3.1模型假设:
(1)任意相邻的两个站点步行均能达到;
(2)上行线路与下行线路相同的站点处于相邻地理位置;
3.3.2参数说明:
A——起始站点;
B——终点站;
T——转乘站点;
S(A)——起始站与其相邻站点的集合;
D(B)——终点站与其相邻站点的集合;
R(AB)——所有满足从A到B的乘车路线的集合。
3.3.3模型的建立以及算法:
在知道所有站点之间的步行时间的情况下,亦即可以考虑乘客可以步行到达离自身比较近的站点,可以补充算法中只考虑转乘两次时,没有覆盖到的两站之间的可能路线。
两站之间路线转三次时,假如有一条路线包含的站数过少(如只有一两站,而且步行的时间很短),就可以采用转两次车,再步行到达目的地。
模型示意图如下:
同样该方法适用于转一次车时的路线选择,可以提高转一次车的路线的覆盖率。
根据这个思想,可以改进算法:
乘客输入起始站A后,计算机搜索与起始站点只有一站距离的所有站点,此时生成起始站点集合S(A),乘客输入终点站B后,计算机搜索与终点站只有一站距离的所有站点,此时生成终点站集合D(B)。
此时将集合S(A)和D(B)中的站点组成新的“起点——终点”组合,利用先前的算法搜索所有可能的路线集合R(AB)。
如果得到的路线集合中存在经过站点数目,费用相同的多条路线,则比较线路两端的站点离A和B的步行时间,取其中最短的作为最佳的路线。
以上算法中只搜索一站的距离内的相邻站点,如果相邻站点的平均步行时间比较短,则可以搜索与输入的起点终点相距两站距离的所有站点构成集合。
由于所给的数据只有线路和线路所经过的站点的信息,没有站点与站点之间的位置信息。
所以无法从距离的概念上搜索相邻站点,只能从站点在线路上的相对位置来考察,半搜索出相邻的站点。
例如:
L001线上与S0388相邻的站点为S1914和S0348。
如果给出了站点之间的位置信息,则可以将地理位置靠得很近,但没有单一公交线路相连的站点也考虑进去。
如下图中的站点a,b:
如果考虑这种情况,则采用全搜索的方法来搜索输入站点的相邻站点,利用已知的站点之间的步行时间,搜索任何与输入站点相邻的站点而不管它们之间是否有单一线路相连。
具体的搜索方法是利用所提供的站点之间的步行时间数据(数据中应该包括站点的标志),任何与输入站点有联系的站点均应包含在集合中。
以上模型,只考虑了在输入的起始站A和终点站B的附近搜索相邻的站点加入集合中,形成新的“起点——终点”组合。
其实当需要转乘的时候,也可以扩大转乘站点T的集合,实现在中途步行这种线路模型,但是这就会大大增加运算量。
模型示意图如下:
4模型及算法的改进
4.1算法改进
以上问题一的算法是以“点连线”的形式搜索所有的可能路线,如下图所示:
由于车站的数目远远大于公交线路的数目,所以考虑用“线连点”的形式来搜索,这样的算法更加简便,如下图所示:
1.零次转乘
零次转乘即在A和B之间有公交车直接往返,用户无需经过转乘就可以直达目的站点。
(1)首先在所有的线路L001——L520中找出包含A和B对应的路线集合,分别记为R(A)和R(B);
(2)接着在R(A)和R(B)中查找相同的公交线路,查找后得到集合BUS;
(3)如果BUS≠ø(非空),则表示查找成功。
否则要进行一次转乘计算。
在步骤
(2)中,假设R(A