2023年12月11日发(作者:2005年的中考数学试卷)
数学建模全国一等奖论文系列(27)
乘公交,看奥运
摘要
由于可供选择的车次很多,各种车辆的换乘方式也很多,为了避免上下行站点不一样的车次等对路线产生的影响,我们以由易
到难的思路来完成模型。首先分析一辆车可以直接到达的情况,在这其中又考虑到环线的特殊性对其单独进行判断讨论;由于
一辆车可使乘客到达目的地的可能性太小,我们接下来讨论要进行一次换乘的情况,在这里巧妙地利用矩阵来判断两辆车是否
含有共同站这个思想,避免了至少两重循环,使运算速度大大提高;虽然这样就已经能够解决不少的问题,但并不完全,因此
我们继续计算换乘两次的乘车路线,经过大量的运算,我们发现基本所有的站点间都可以通过换乘两次到达,至此对公交线路
的讨论基本完成。对加入地铁的讨论与只有公交车时类似,从最简单的两辆地铁换乘的情况开始考虑,由浅入深。
论文中并没有运用大量的符号,而是用文字来说明程序的主要步骤,这样可以让不了解程序的读者也清楚地知道模型的思路,
而且,只要知道起始与终点,利用程序就可以计算所有可能路线,并可以在结果中为读者提供路线的相关信息,比如路费及所
需时间,以供选择。
对于最优的解释,我们除了以时间最少、车费最省为原则,还对时间与车费进行了加权平均,而权数便是乘客对时间与金钱的
偏好程度,当输入自己愿用1元钱去换多少分钟乘车时间时,程序会根据个人的不同喜好,来选择出适合每个人的最优路线。
这样将程序人性化,可以更符合实际中人们的需要。
关键词:公交线路选择最优化矩阵加权平均数组分类讨论自主查询
问题重述
北京是中国的首都,是政治、文化中心,同时也是国际交往的中心。在成功取得2008年第29届夏季奥运会的举办权后,北京
市城市建设的步伐将进一步加快。众所周知,可靠的交通保障是成功举办奥运会的关键之一,公共客运交通服务系统尤为重
要。
在保持公车票价一直相对较低的情况下,北京市又已经实行机动车单双号出行,目的就是为了鼓励人们乘公共汽车出行,缓解
交通阻塞状况。而北京现存的就有800多条公交线路,市民出行能否选择合理的公交线路,不仅关系到自身利益,也影响着整
个交通服务系统的优良程度。
那么如何做出最合理的选择就是一个迫待解决的问题。
所谓合理的选择,可以有以下几种解释:最节省时间的线路(尤其存在换乘的情况下),最节省车费的线路,或者是将时间与
车费作加权平均后的最小值,这就可以根据个人对时间与金钱的不同喜好来选择要搭乘的公车。
在公车系统日益完善的情况下,轨道交通也在蓬勃发展,地铁的快速运营不仅可以大大节省人们出行的时间,也同时减少了地
面的交通流量,使得车辆可以更畅通地行驶。
当然,对于不同的公交线路由于路面的拥挤情况不同,现实中人们可能会根据自己的经验来搭乘公交,或者,有的时候除了时
间与金钱方面的原因外,还有一些个人原因会影响人们的选择,比如公交的服务质量或环境质量等。
本模型就在一些合理假设的前提下,对附录中给出的可选公交线路的情况做出分析与比较,并举几个具体的例子,分别在时间
最省、金钱最省或时间与金钱按一定喜好比最优的情况下,向人们提供出行意见。
问题分析
人们出行要根据自己的出发地与目的地来选择公车线路,我们可以假设,一般情况下,如果人们可选择只乘一辆公车到达,则
不会选择要进行转乘的方案(环形除外),因为转乘不仅很可能会浪费金钱,还涉及到在车站等车的问题,所以,我们可以对
要解决的问题先进行一辆车的选择,看看能否不用换乘就直接到达(即同一线路的车是否包括出发和到达的两个车站),如果
不可以,再考虑换乘一次到达的情况。
换乘的时候,我们可以先将包括有出发地的所有车次选出,再选出所有包括目的地的车次,如果两边各选一趟车出来可以找到
一个可供换乘的车站(就是说,这个换乘站要在出发地的后面,而在目的地的前面,即不会让车次向相反方向运行(因为很多
车上下行站点不同)),我们就可以将此方案列出,以备比较。
当然,由于公交系统的不断完善,一般情况下,换乘三辆车还到达不了的情况极为少见,所以我们在只有公车的情况下最多考
虑换乘两次。在公车的基础上,我们可以考虑换乘地铁,或在地铁站换乘站名不同的公汽,这样人们就有了更多种选择,同时
也增加了问题的复杂程度。
在列出方案的同时,可以计算出这种换乘方式所需的时间和车费,当把所有的情况列出后,我们就自然可以比较出各种换乘方
案的时间与车费情况。此时涉及到同一问题在几组不同换乘方案都可执行的情况下,哪一种最优的问题(时间或金钱上的最优),时间最少与车费最
少都很容易选出,但更多的人倾向于时间与车费加权平均的结果最优。我们可以利用一个小的程序来根据乘客不同的喜好定义
不同的权数,最终选择乘客最满意的车次。
模型假设
1.交通系统始终正常运行,且路面状况各地区一致,不论市区或郊区车流量相同,即不考虑有些线路的阻塞情况等。
2.将一辆车次的第一站称为始发站,最后一站称为终点站;而将我们要解决的两个站点分别称为出发站与目的站(或目的
地)。
3.乘一辆车到达目的地时是不换乘,乘两辆车时我们称其为换乘一次,以此类推。
4.假设人们出行的等车时间、各车的行驶速度、车站间的间隔等条件都完全相同。具体时间安排参照如下参数设定:
相邻公汽站平均行驶时间(包括停站时间):3分钟
相邻地铁站平均行驶时间(包括停站时间): 2.5分钟
公汽换乘公汽平均耗时:5分钟(其中步行时间2分钟)
地铁换乘地铁平均耗时:4分钟(其中步行时间2分钟)
地铁换乘公汽平均耗时:7分钟(其中步行时间4分钟)
公汽换乘地铁平均耗时:6分钟(其中步行时间4分钟) 5.在计算时间时,我们只考虑乘车和换乘的时间。因为乘车时间是我们
设定的,并不与实际完全相符,只作比较用,且无论选择哪样的乘车
路线,在出发站的等车时间总是存在的,且可以认为所有的都相同,
所以不予考虑。
6.在车费的计算上,我们也作如下的参数设定:
公汽票价:分为单一票价与分段计价两种,标记于线路后;其中
分段计价的票价为:0~20站:1元;21~40站:2
元;40站以上:3元
地铁票价:3元(无论地铁线路间是否换乘)
7.我们假设人都是理性的,即乘客一般都选择时间和金钱都花费较小的路线,在给出最后的最优结果时,不考虑个人的其他
喜好问题(如服
务态度等)。
8.在选择线路时,我们假定如果人们可选择只乘一辆公车到达,则不会选择要进行转乘的方案,环行除外。
9.存在步行的模型中,根据北京市发改委的调查,我们假设出行者会选择的最合适的步行距离一般为1000米以内,即可认为
是两个站台间
的距离,时间为15分钟。见参考1
注:以上参数均为简化问题而作的假设,未必与实际数据完全吻合。
符号说明
S 加在数字前面构成车站的代号,如S2834表示2834号站点
L 加在数字的前面,表示车次的名称,如L235表示235路公共汽车
T T1和T2分别表示两条地铁线路
- 出发站与目的站的连接符,如S0342-S1352表示从342站到1352站
在论文中用到的符号并不多,在程序中用到的符号我们并没有引入论文中,其各个变量的代表意义,我们在程序的说明中明确
地给出了。模型建立与求解
我们的思路是由简到难,先从最简单的一辆车的情况开始搜索,如果不存在一辆可以直接到达的话,再进行换乘一次可到达的
情况进行搜索,一次比一次更为复杂、可选择情况也越来越多,但我们不断地进行循环判断来搜索可供换乘的车辆就可以挑选
出所有的可行方案,再对其进行筛选就可得到最优。
只有公共汽车的情况
一.只乘一辆车即可到达目的地的情况
在实际中,如果一辆车包含我们的出发站和目的站,在很大可能性下我们选择这辆车而放弃另外可以换乘一次公车到达目的站
的线路。一般情况下,乘一辆车要比进行换乘的车费要少,而且时间会节省,当然,这不包括选择环线的情况,因为环线有其
特殊性,我们后面会进行讨论。
关键计算步骤:
1.由于我们将所有车的上行都放在同一个数组中,所有的下行放在另外一个数组中,因此在搜索时分成两大部分,先在所有
的上行中进
行出发站及目的站的搜索。
2.在搜索到含我们所需两站点的车次后,判断在这个路线中,是否出发站比目的站的位置靠前(即是否可以乘坐)
3.如果可以乘坐的话,我们就分别对单一票制和分段票制进行判断,来计算出最后的车费与时间。如果不可以的话,我们继
续进行循环搜索。
4.对所有下行线路的搜索与上相同,如果可以得到结果,说明我们乘坐一辆车就可以到达目的地。
举例来说,我们考虑从2602站乘到3010站,运行程序(见附录chaxun123.m)后会出现如下结果:
结果表明,这两个站点间可以乘坐一辆车直接到达。
但对具体数据进行检验时会发现,一辆车可以达到目的的情况并不常见,这就需要我们对换乘进行考虑。
在此之前,我们先对环行的情况进行说明。
图1 图2
如图,假设线路A是一个有50站的分段计费的环形线路,第50站即为第1站,若乘客想从第48站乘到第2站,有两种情况:一
是从48到2的环形(如图1),这样只需乘一辆车;二是从2乘到50站(1站),再交费乘到第2站(如图2),这样同样是2元
的车费,时间会节省很多。
对我们的模型来说,如果只用上面提到的一辆车的程序而不进行环路的讨论的话,从732站到2082站,得到的结果如下:
但从车次表中我们可以发现,如果乘坐17路向反方向运行的话,虽然要经过终点站,会多收一次的车费,但车费仍旧是2元,
时间却会节省很多。
因此,我们在只有一辆车的程序后面加上判断,如果所选择的是环形车,那我们再看其反向乘坐到站时(过终点站就被算为是
换乘,因此一辆
车时不包括这种情况)的时间与路费是否更省,当到达终点站后再乘坐时,我们将其时间当作换乘时间(即使不需要换车,终
点站也应该考虑到司机的休息时间,所以按换乘考虑),见假设4,应在总的乘车时间中再加上5分钟。
这样,我们就得到了如下两个结果:
可以看出,同样车费的情况下乘坐时间少了很多,得到了更优的结果。
下面,我们就对一般换乘的情况进行讨论二.换乘一次公车可到达目的地的情况
当乘坐一辆公交车不可以直接到达目的地时,我们考虑换乘情况。由于我们将所有车的上行与下行放在了两个数组中,因此,
考虑换乘一次时,可以分成四种情况进行讨论:上行车换上行车、上行车换下行车、下行车换上行车和下行车换下行车。
这样,只要一种情况考虑清楚之后,其余情况类似。
关键计算步骤如下:(以上行车换上行车为例)
1.先将所有含出发站和目的站的车次分别放在两个向量中(见附见
xunzup.m),这样在接下来的循环中可直接进行挑选。
2.循环时,将所选的两辆车包括的所有站点分别放在两个向量中,然后
转换成矩阵,利用两个矩阵相减看是否有0的思想来判断这两辆车是
否有共同站,即可供换乘的站。
3.如果有,再计算出这一共同站分别在两条线路的哪一位置,与不换乘
情况类似,如果与公车行进的方向一致,就可以进行换乘,即此条线
路可以被执行。
4.计算出可执行线路的所需乘车时间与车费。
5.当这一种换行方式下(上行换上行)所有的可能性被挑选出后,我们
进入下一种情况的讨论,当四种可能性都结束后,我们可以对其进行
列出比较,从而选择出满意的换乘线路。
现对题目中6对待解决问题进行讨论:
1)S3359-S1828
将出发站与目的站输入后,12条可选路线显示如下:
可供选择的线路一目了然,运行结果中还会显示出时间最少的线路与车费最少的线路,当然,在选择并不是很多的情况下,乘
客可以根据自己的方式进行选择,但当可选择的结果过多时,我们就需要利用选择最优的程序为乘客进行筛选。
从表4很容易看出,第1列的结果,如果我们乘坐469路车在2364站换乘217路的话,只需3元的车费,89分钟时间即可到达目
的地。无论在时间与车费上面都是最优的结果。
但有的时候,这两个都最优的车次并不一定是同一辆,而且最优的选择线路也并不一定是指时间最少或车费最少,我们可以根
据个人的不同喜好来进行调配,比如,乘客可输入自己愿用1元的乘车费去换多少的乘车时间(20分钟或40分钟等),这样的
权数就会更符合乘客的个人选择。
而且,我们可以看出,同样的两辆换乘车的情况下,也有很多换乘站的选择,换乘站不同所需时间与路费有时也会不同。
2)S1557-S0481
得到的结果为一个全0的向量,说明我们并不能通过换乘一次到达目的地。后面我们会再次对其进行讨论。
3)S0971-S0485
运行程序,得到结果如下:
最优结果为乘坐13路到2184站换乘417路,共乘坐41站,花费128分钟,车费为3元,这在程序运行后会自动显示。
对于同样是13路换417路的情况下,我们发现,有几种不同的选择,而这几种选择所得到的结果(时间上)也完全不同,这对
我们的日常生活十分有帮助,这些细小的差别,可能是我们没有注意到的情况,但确实会影响到出行时间。
如果结果没有特别性的话,都与第(1)题类似,我们就不再重复分析。4)S0008-S0073
这道题共有104条查询结果,时间最少的有14种选择,都是83分钟,但车费就有2元和3元之分,而车费最少的有31种选择是
相同的。
时间和车费同时达到最少的有以下11种:
我们可以发现,这11种换乘选择其实只是4条线路,这就是前后换乘的两辆车不止一个共同站的结果,且这些共同站的行驶方
向及中间站也完全相同。
5)S1048-S0485
与(2)一样,在换乘一次的程序中,我们得不到这道题的结果,我们会在下面的模型中对其讨论。
6)S0087-S3676
我们得到两条路线选择:
显而易见,乘坐454路到3496站下车后换乘209路最省时省钱。
第(2)题与第(5)题在此没有结果,表明换乘一次车根本不能达到目的地,这就需要我们再对换乘两次公车的情况进行讨
论。
三.换乘两次公车可到达目的地的情况
换乘两次与换成一次的思路类似,但如果按照上面的搜寻方法进行编程,无论是程序的复杂程度还是运行速度,都不是十分理
想,因此,我们在这个思路的基础上,将程序简化。
换乘两次最困难的地方在于第二辆车是未知的,如何从出发站和目的站给出的第一条和第三条线路的信息得到第二条线路,就
是解决此问题的关键,最初,我们利用第一辆车和第三辆车的限定,得到所有转乘站点的情况,在用所有公交线路与各种转乘
线路匹配,得到所要结果,程序见附录chaxun123.m。
此种方法的缺点是显而易见的,因为过多的循环使得计算量极大,花费较多时间,使得程序的实用性较差,如何减少计算量,
关键在于减少循环,我们自然想到在解决两辆公交车的问题时,利用矩阵减少了两重循环,所以,我们将三辆公交车分成1-2
两部分,第一辆车换乘的车站就是后两辆车的出发站,而后两辆车的计算可以由已经得到的程序修改得到。
这样,我们既减少了计算量,又利用了已有的结果简化了编程的过程,从运行的结果看到,第一种单纯搜索的方法计算一个三
辆车的问题一般需要十分钟,而利用矩阵简化循环之后计算同样的问题一般不超过2分钟,可见效果是很明显的。
下面我们来解决上面未解决的问题
(2)S1557-S0481
运行程序后,我们得到时间最少的车次与路费最少的车次分别见表8及表9,并不是同一辆
在这种情况下,我们就可以用到加权平均取最优的程序,从以上两个表格可以看出他们的时间相差很多,只要一个人愿意用1
元钱去换84分钟以下,那么他都会选择表8的乘车路线。
(5)S0148-S0485
这个问题的运行后我们得到了在时间与车费上都最优的结果,而且不止一条:
结果对于这个模型并没有什么特别之处,但与现实已经越来越接近。
个人喜好的考虑
我们现在考虑加权平均数的情况,即前面提到过的乘客愿意用1元钱去换多少分钟的乘车时间,按照乘客的这个喜好,我们可
以对每道题最终选择出一个最优结果。假如,乘客愿用1元钱去换20分钟,则6道题结果如下:
其中,第四个问题有很多个运行结果,第五题也有三个,我们只各自挑选了其中一个。
那么如果我们假设,乘客不在乎乘车时间,不愿用1元钱去换任何乘车时间,则6道题结果如下:
可以看出与表11略有差别,但差别并不如想象中那么大,说明,当可供选择的路线很少,在相同车费,时间相差并不多的情
况下,个人喜好并不是主要决定因素。而当供选择的两种乘车路线比较极端时,即一个很省钱但很费时另一个很省时但不省钱
时,这种喜好就起到了决定性的作用。
下面我们来讨论有地铁加入的情况,由于在公车换乘时已经讨论得很详细,很多思想在有地铁的时候也是可以通用的,因此,
情况不再讨论得那么复杂
有地铁加入的情况
有地铁加入,并不一定指乘客要换乘地铁,有一种情况是:乘客可以通过地铁站而到达相临的不同车站,这在我们只考虑公车
换乘的时候是无法考虑的,因为显示给我们的数据表示他们并不是同一车站,因而无法进行换乘。
当加入了地铁后,人们通过地铁就可以到达站名不同车站去换乘,而导致汽车换乘的可能性大大增加了。
我们称其为地铁站的加入(见附录chaxunsub12.m)
一、地铁站的加入
与换乘一次的情况类似,只是将换乘的可能性加大了,因此,我们同样将换乘的可能性分成四种情况考虑:上行车换上行车,
上行车换下行车,下行车换上行车和下行车换下行车。在每一种情况中,我们再引用程序,将可由地铁站换乘的车次单独列出
进行挑选判断(见附录zdt.m)。
同样以上行车换上行车为例,我们分别看看选出的两辆车通过地铁T1的站、地铁T2站进行换乘的情况,以及在普通意义上的
换乘情况,这样就比原来多了很多个可能换站的情况,结果自然会比原来多一些,很有可能找到更优的结果。
比如,在运行S1839-S3024时,我们发现,在只考虑公交换乘的情况下他有300种线路选择方式,在加入地铁站之后,增加到
了304种。虽然增加并不多,也说明了地铁站的加入增加了线路的可选择情况。
二、地铁换乘地铁的情况
其实这种方式与公交的换乘类似,不过可以在只用一次交通费的前提下不断地进行换乘,因此,在实际中,如果可以乘坐地
铁,则可以考虑是否能尽量利用地铁的这种优点减少路费与时间。
例如,S456-S567,我们可以通过附录subtosub得到结果:乘坐时间为
86.5分钟,车费为3元。但如果不乘坐地铁而只乘坐公交车的话,我们得到
的最优结果为
我们可以看到,车费同样为3元,但运行时间却为161分钟,由此可见,加入地铁的相当一部分情况下,大大降低了人们的出
行时间。为人们的出行带来方便。
三、地铁与公交的互换情况
地铁转公车和公车转地铁可以归为一类讨论,具体算法以地铁转公车为例说明,地铁作为出发线路,分为T1、T2两种可能,
同样公车分为上行路线与T1相交或与T2相交,下行路线与T1相交或与T2相交,综上共有八种情况,分别对以上情况讨论就会
得出换乘的线路,如,在Matlab中键入>> [a,b]=subway(576,2410) 见附录subway.m
因为在zdt.m的程序中已将各与地铁相交的公车交于T1还是T2、交于第几个地铁站分类归总,所以,在计算本程序是大多是判
断,从而提高运算速度。
考虑更复杂的情况——公车转地铁转公车,与三辆公车相似,分为公车—地铁公车两部分,利用已有程序,将第一辆公交车的
转乘站作为地铁转公交的出发站,解出此种情况,但因时间有限没有做出程序。考虑有步行的情况
当只需坐一站时,人们可能不会选择坐车,而是选择步行,因为坐车的话除了要多花上1元钱的车费外,还要需要加上等车或
者走到公交车站的时间,这样相对于坐车也不会多出太多时间。所以基于上述考虑,如果我们知道了所有站点间的步行时间
后,可以对上述模型进行相应的改进。
根据假设,出行者会选择的最合适的步行距离一般为1000米以内,时间为15分钟,即大约是两个站台间的距离。这样当只需
要坐一站时,我们可以对于坐车和步行作比较,让人们根据自己对于时间和车费的不同偏好而做出选择。
如我们可前面讨论过的从S3359-S1828的例子,如果考虑从436路到S1784站换乘167路或217路,则后一辆车只需坐一站即
到达目的站,现我们按上面的分析,把最后一站步行的情况拿出来,并于原来换乘的作比较,最后得到相应的
(其中,我们假设同一线路相邻站点间的步行时间为15分钟,从而步行时间应为108(=101-3-5+15)分钟。第一列为原来的
最优解。)
由上表可以看出,如果坐436路到站S1784,然后再步行目的站的话只需花
费2元车费,而时间上只比原来多了7分钟。虽然相对于最优解来说,时间上多花了19分钟,但如按前面所考虑的,根据某些
人的喜好,愿意用1元钱去换20分钟乘车时间的话,这种步行的方案还是可以考虑的。
在一般情况下,由于考虑到有可能步行,因此我们必须在出发站、中转站及目的站附近考虑步行的情况,这样我们前面的运算
步骤和程序不能直接应用,为此我们对该问题分以下几步进行转化。
1.对于每个站点每,我们先找出含这个站点的所有线路;然后对于每条线
路,我们找出该站点前后的两个车站。
2.我们把上面找出的所有车站放到一个集合里,这样每一个站点就对应一
个集合并以该站名为集合名;
3.我们把上述每个集合看成一个地铁车站,把集合名看成地铁名,把每条
公交线路看成一条地铁线路。
有了上述的转化,我们知道对于同一个集合下的所有车站可以像一个地铁站下的各个公交站那样可以直接步行过去,而对于在
同一线路上的集合,跟地铁线路一样,只有各个集合名那一站可以通过该线路直接到达。从而我们可由如下的步骤得到我们所
需的结果:
1.如果出发站和目的站是在同一个集合里,那么我们可以把坐车和步行来
两种情况都列出来,最后根据乘客们的喜好来选择;
2.如果出发站和目的站不是在同一集合里,我们可以参照前面讨论的同时
考虑公交和地铁的情形,只是在这里把公交线和地铁所有的站都是一个
集合,只是二者在票价和乘车时间上有一些差别;
3.和前面不同的是,在循环筛选中,对于公交线路,我们除了考虑集合名
那一站与集合中其它各站之间可能换乘和步行的所有情况。
4.最后我们根据找出来的各种可行方案,根据乘客的不同喜好,进行最优
化选择,从而筛选出最好的一条或几个方案。
当然我们前面所讨论的和我们的实际生活还是有一些差别,因为在现实中可能两个车站之间的距离也就不超过1000米(相邻
两站台间距离),但二者之间是没有一辆公交线路或地铁能直接到的,那么此时最好的选择当然是步行了。为此,我们需对上
述的讨论稍微修改一下。一个是应该把由此类情况的两个车站放到同一个集合里;二是在循环筛选中,只考虑二者的步行情
况。这样,我们模型就更接近于我们的现实生活。
模型分析
由于这个模型的思路简单明了,就是不断地搜索车次来寻找换乘机会,并且主要由程序来完成,因此,在模型分析中我们主要
谈一下在程序编写及运行中产生的一些问题,并对其优缺点进行逐个分析:1.根据由简到难的思路,我们在编写只有公交车的程序时,是将几辆车的
情况分开来的,但在附录中给出的是最后总程序的一部分,这并不影响
运行,因为在是否要换乘时我们做了判断,如果前面已经运行出结果,
则下面的程序不再进行运算,这样看似程序更加繁杂,但其实比起要一
个一个进行人工判断要快很多。
2.在一个单独的程序中,将每种车次的上行与下行分开来,把所有车的上行录入在一个数组里面,下行也同样,这样可以避
免同一辆车包含所需
两个站点但是不能够直接乘坐到达的情况(因为分别在上下行,需要换
乘)。
3.因为有些内容要反复用到(比如车费的计算等),我们将寻找线路、计算车费、选择最优线路等程序单独存放,既节省了
总程序的篇幅,又可以
让人一目了然。并将所有单一票价的车次及所有环形的车次分别放在一
个向量中,在进行判断时只要看所判断车次是否在此向量中即可,十分
方便。
4.在对程序的反复修改中,我们将问题尽量简化,比如用矩阵来对是否有共同站进行判断时,省掉了两个循环,运行速度就
大大地提高了,可有
的程序还是很长,时间也并不是十分理想,也许可以再进行优化。
由于数据繁多,在附录中我们并不将所有程序完全给出,在此也对未给出程序及数据进行一下说明,SHUJ1,shuj2分别是只
用公车时和加入地铁后的原始数据,第二个只比第一个多了一些地铁上面的数据,之所以用两个是因为加入的有关地铁的数据
时用到了原始数据,如果都放在一起,会引起死循环。在这里面用到了附录中的daoxu,对上下行站点一样的公交车进行下行
的站点变化,因其行驶方向不同,必须将先到的站点放在前面在程序中才能进行正确的判断。
在模型的建立过程中,我们也发现了一些数据上的错误,如:290路的环形路线,最后的1479与开始的1477不相符;338路的
第一站和第二站都是1839站,因此在运行时产生错误,应将其删除了一个。
模型的评价与改进
1.本模型思路较明确,由简到难,论文中没有用到很多符号,这样,不会
让人总是产生一头雾水的感觉。并且在模型建立中列出了程序中的主要
思路与步骤,清晰明了,即使不了解程序的人也可以清楚地知道模型的
结构与内容。
2.很多情况下,大大简化了程序的复杂程度,比如,对很多反复用到的小
程序单独列出调用,巧妙地利用矩阵进行判断,以尽量减少循环、提高
运行速度。
3.本题对于很多种乘车情况都进行了讨论,能够比较全面地解决问题,且
给出程序对几乎所有的出发站和目的站,都可以进行路线的选择,给出
最优的出行意见,比较实用。但由于时间问题,还是有一些情况没有时
间讨论,但原理相同只要将原有程序不断地扩大就可以完全地解决。
4.在很多细节上,比如,对于同样两辆车在不同站点都可以进行换乘的情
况,因为不同的换乘站而产生了不同的换乘时间与车费(问题3,表5);
再比如,在某一站点下车只需走几百米就可以换乘到比原来直接在同一站点换乘车辆更省时省钱的车次(第三个包括步行的部分),这可能是我
们平时没有注意到的情况,对我们的出行十分有帮助。
5.在这个模型中,对于运行结果我们只能检验其是否存在于所给路线中,
时间是否正确、价钱是否正确等,而并不能检验其是否真的是最优乘车
路线。如果可以再想出一种建模方式,就可以两边同时计算,大大提高结果的准确性。
6.由于时间的分配与精力问题,我们对于地铁问题的讨论才刚刚展开,模
型可以在现有基础上进一步完善,得到更好的结果。
7.对于将近4000个站点的公交系统,我们可以在其中任意选择两个进行线
路的求解,将所有的结果运行出后存入数据库,这样乘客在进行查询时就可以直接调入结果,省掉了程序的运行时间。这样我
们就将其做成计算机自主查询系统,方便人们进行线路选择。此外,还可以在此系统上加入是否愿意换乘地铁等条件满足人们
的不同需求。
参考文献:
[1]北京市城市规划设计研究院,“十五”期间北京市城市交通改善对策研究,
/doc/ /fzgh/qqyj/200508/,2007年9月22日[2]王沫然,
《MATLAB与科学计算》,北京,电子工业出版社,2005年附录
由于本题主要是进行程序的运算,因此程序的内容极多,而附录的篇幅有限,在此,我们仅列出程序的关键部分,所有程序在
电子版中都有,并且都可以运行。
busfare.m
function f=busfare(c,r,beg,en,p,l)
SHUJ1;
%输入参量说明
%c为第p条公交线路的第c站,r为第l条公交线路的第r站
%beg表示初始站对应于第p条公交线路的第beg站,en表示目的地对应于第l条公交线路的第en站
if find(d==p)
if find(d==l) %p,l线路都是单一费制
f=2;
else
f=1+ceil((en-r)/20); %p线路都是单一费制,l是分段计费
end
else
if find(d==l) %p是分段计费,l线路是单一费制
f=1+ceil((c-beg)/20);
else %p,l线路都是分段计费
f=ceil((c-beg)/20)+ceil((en-r)/20);
end
end
ion ku=xunzup(m) %上行寻找含所寻车站的线路
SHUJ1;
for i=1:520
if find(ucell{i}==m)
ku(i)=min(find(ucell{i}==m));
else
ku(i)=0;
end
end
function tu=xunzd(m,i) %下行寻找含所寻车站的线路SHUJ1;
for i=1:520
if find(dcell{i}==m)
tu(i)=min(find(dcell{i}==m));
else
tu(i)=0;
end
end
zdt.m
function [ubusT1, ubusT2,dbusT1,dbusT2]=zdt
SHUJ1;
for k=1:size(T1,2)
c=[];
for i=1:length(find((T1(:,k))))
s=T1(i,k);
for q=1:length(ucrosub)
line1=ucell{ucrosub(q)};
if find(line1==s)
c=[c,ucrosub(q)];
end
end
end
ubusT1(k)={c};
end
for k=1:size(T2,2)
c=[];for i=1:length(find((T2(:,k))))s=T2(i,k);for q=1:length(ucrosub)line1=ucell{ucrosub(q)};if find(line1==s)c=[c,ucrosub(q)];endendendubusT2(k)={c};end for k=1:size(T1,2)c=[];for i=1:length(find((T1(:,k))))s=T1(i,k);for q=1:length(dcrosub)line1=ucell{dcrosub(q)};if find(line1==s)c=[c,dcrosub(q)];endendenddbusT1(k)={c};endfor k=1:size(T2,2)c=[];for i=1:length(find((T2(:,k))))s=T2(i,k);for q=1:length(dcrosub)line1=ucell{dcrosub(q)};if find(line1==s)c=[c,dcrosub(q)];endendenddbusT2(k)={c};end
zuiyou.m
function zuiyou(q,p)
t=find(q(end,:)~=0);
[r,k]=find(q(end,:)==min(q(end,t))); [l,j]=find(q(end-1,:)==min(q(end-1,t))); disp(\'时间最短的路线\')
q1=q(:,j)
disp(\'车费最少的路线\')
q2=q(:,k)
tmin=min(q(end,t));
smin=min(q(end-1,t)); s=min(q(end,j)); %时间最少的最小花费t=min(q(end-1,k));
if (s-smin)*p+tmin>t
m=find(q(end-1,k)==t);
q3=q2(:,m);
else
n=find(q(end,j)==s);
q3=q1(:,n);
end
disp(\'时间车费喜好加权的最优路线\')
q3
chaxun123.m
function chaxun123(m,n,p) %m为出发站,n为目的站,p为人们的权数偏好
%====================================================================== %乘坐一辆车就可到达目的地
%======================================================================
ku=[];tu=[];kd=[];td=[]; %换成两辆车的情况时会说明
q1=[0;0;0];q2=[0;0;0]; %q1为上行不用转车的线路的集合,q2为下行不用转车的线路的集合
for i=1:520 %在上行路线中寻找
if find(ucell{i}==m)&find(ucell{i}==n) %将上行与下行的线路分别放在两个数组中,返回值若不是0说明第i次车有m和n站
beg=find(ucell{i}==m); %出发站在上行线路中的位置
en=find(ucell{i}==n);
if beg
if find(d==i) %d中的所有线路都是单一费制
t=(en-beg)*3;
q1=[q1(1,:),i;q1(2,:),t;q1(3,:),1]; %q1为不用转车的上行线路的集合
else %线路为分段计价
fare=ceil(abs(beg-en)/20); %向上舍入,可得到分段计价的车费情况t=(en-beg)*3;
q1=[q1(1,:),i;q1(2,:),t;q1(3,:),fare];
end
end
end
end
for i=1:520 %在下行路线中寻找
if find(dcell{i}==m)&find(dcell{i}==n)
beg=find(dcell{i}==m);
en=find(dcell{i}==n);
if beg
if find(d==i)
t=(en-beg)*3;
q2=[q2(1,:),i;q2(2,:),t;q2(3,:),1]; %q2为不用转车的下行线路的集合
else
fare=ceil(abs(beg-en)/20);
t=(en-beg)*3;
q2=[q2(1,:),i;q2(2,:),t;q2(3,:),fare];
end
end
end
end
q=[q1,q2];
for i=1:size(q,2)
if find(ring==q(1,i))
beg=find(ucell{q(1,i)}==m);
en=find(ucell{q(1,i)}==n);
if en-beg>length(ucell{q(1,i)})-en+beg
if find(d==i)
t=(length(ucell{q(1,i)})-en+beg)*3+5;
q=[q(1,:),i;q(2,:),t;q(3,:),2]; %q2为不用转车的下行线路的集合
else
fare=ceil((length(ucell{q(1,i)})-en+beg)/20)+1;
t=(length(ucell{q(1,i)})-en+beg)*3+5;
q=[q(1,:),q(1,i);q(2,:),t;q(3,:),fare];end
end
end
end
%======================================================================
%乘坐两辆车到达目的地
%======================================================================
if q==0 %乘一辆车不能到达的情况下,继续运行
q=zeros(6,1);
%在上行路线中寻找
ku=xunzup(m); %寻找含出发车站的线路含0
tu=xunzup(n); %寻找含目的车站的线路
au=find(ku);bu=find(tu);%只有含出发站的线路名
%在下行路线中寻找
kd=xunzd(m); %寻找含出发车站的线路
td=xunzd(n); %寻找含目的车站的线路
ad=find(kd);bd=find(td);
%---------------------------------------------------------------------
%从上行的路线开始,在上行的车中寻找可转乘线路
%---------------------------------------------------------------------
for p=1:length(au)
line1=ucell{au(p)}; %au(p)对应的线路
for l=1:length(bu)
line2=ucell{bu(l)}; %bu(l)对应的线路
M1=ones(length(line2),1)*line1;
M2=line2\'*ones(1,length(line1));
M=M1-M2; %length(line2)*length(line1)
if find(M==0) %若M中含0,说明两条线路有共同的车站
k=find(M==0);
beg=find(line1==m);
en=find(line2==n);
for s=1:length(k)
if mod(k(s),length(line2))==0
c=floor(k(s)/length(line2));
elsec=floor(k(s)/length(line2))+1;
end
r=mod(k(s),length(line2)); %c表示line1的第c站,r表示line2的第r站if c>beg&r
Num=c-beg+en-r; %Num表示一共乘车的站数
tuu(s)=3*Num+5; %t表示乘车花费的时间
fareuu(s)=busfare(c,r,beg,en,au(p),bu(l)); %fare表示车费
hc=[au(p),bu(l),line1(c),Num,tuu(s),fareuu(s)];
q=[q,hc\'];
end
end
end
end
end
%----------------------------------------------------------------------
%从上行的路线开始,在下行的车中寻找可转乘路线
%----------------------------------------------------------------------
……
%---------------------------------------------------------------------
%从下行的路线开始,在上行的路线中寻找可转乘线路
%---------------------------------------------------------------------
…...
%----------------------------------------------------------------------
%从下行的路线开始,在下行的路线中寻找可转乘线路
%----------------------------------------------------------------------
……
%===================================================================== %乘坐三辆车到达目的地
%===================================================================== if q==0
q=zeros(8,1);
%----------------------------------------------------------------------
for p=1:length(au)
line1=ucell{au(p)}; %au(p)对应的线路
beg=find(line1==m);
if beg~=length(line1)
for z1=beg+1:length(line1)
q1=zhongzh(line1(z1),n);q2=[au(p);line1(z1)]*ones(1,size(q1,2));if q1==0q=q;elseif find(d==au(p))
更多推荐
时间,情况,进行,线路,程序,选择
发布评论