算法题换乘
A. 公交换乘查询算法如何计及步行
先搜索一条最优路径,再从目的地反向查找,将找到的点和条最优路径对比,
比如:最优路径倒数点为A,现在查找的为B,判断B到A的距离,小于我们的要求即为所要求的点,存入(这里可以有多个符合的点)然后再对每个点按上面的那样寻找,直到找到出发点。。
还有一种是随便找到一条路线,再以中间点做为换乘点,搜寻附近的点,再判断搜寻到的点到起始和结束点的距离,进行判断,。
B. 换乘缺陷的算法应用
新线开通与漏洞
随着广州地铁8号线北延段开通,广州地铁的很多站点都换上了新的票价指示图。但是我发现,由于8号线西村站无法和5号线进行换乘,导致很多区段的票价仍然按照原票价执行,并未能达到减价的目的。
除此之外,有些站去近的站点反而比去远的站点绕远路,造成加价。
本文将以最短路径算法的应用为例,去寻找8号线西村站造成的票价问题(准确来说是里程问题)。
背景知识
本文将用迪杰斯特拉算法进行分析,算法如下:
本文为简化地铁线路图的分析,仅截取2号线飞翔公园以南,昌岗以北,5号线小北以西,1号线公园前以西,6号线海珠广场以西,沙贝以东,8号线昌岗以西,同德以南,广佛线燕岗以西,西塱以东的部分进行分析。
同时取精确到0.1公里的站距,票价按4公里内2元,4-12公里每4公里加1元,12-24公里每6公里加1元(因区域内只存在最高5元票价,后略)计算。规定超过临界票价里程0.5公里加1元(即4.4公里2元,4.5公里3元)。(但为方便计算,里程乘10后再写入算法。)
具体分析
为进一步简化模型,规定起始站为1号节点,途径的站点仅换乘站和区域内的端点站标注节点,其他一律不计。本文将选取芳村、燕岗、陈家祠、西村、沙贝和公园前6个代表性车站作为示例,说明西村换乘对线网票价的影响。
这两张图是芳村站前往各站的里程图,上图是西村开通之后的,下图是西村开通之前的。主要差距在于西村(节点11),广州火车站(节点12),小北(节点14),尤其是西村,换乘与否增加了2.7公里,甚至超过了相邻的鹅掌坦站的里程,可见对于1号线西段来说,西村换乘与否会影响前往5号线西段的便捷程度。
这是陈家祠站的里程对比,众所周知,由于陈家祠换乘的开通,荔湾区北片前往海珠西部不需要再通过6号线迂回换乘,所以沙园加入了陈家祠的2元俱乐部。但是依然是西村(节点10),广州火车站(节点11),小北(节点13)存在问题,所以说,解决西村换乘问题对老西关地区和西村联络还是有帮助的。
和芳村、陈家祠不一样,公园前由于2号线的强力作用(北通机场,南接顺德),所以8北开通对公园前影响很有限,最多就是西村换乘通车之后,可以减少西村前往北京路商圈的换乘问题。
西村——影响太大了,除了去5号线本线的滘口(节点14),坦尾(节点9),广州火车站(节点11),小北(节点13)外,其他都可以减里程。尤其是西村-西塱,相比5-6-1,8-广佛的换乘更加快捷(可以省2.7公里,还有沙园站同台换乘的便利)。这说明西村换乘对西村本站的优势是最大的,对西村长期依靠地面交通联络老西关、芳村和海珠有极大帮助。
燕岗可以说是近几年市区站点中的大赢家,2018年,广佛线最后3个站开通,燕岗不再是终点;2019年,8号线凤凰新村-文化公园开通,燕岗站前往6号线沿途各站无需绕行2号线;2020年,8号线再次向北延伸,陈家祠换乘让荔湾北片不再遥远。但如果西村换乘开通,燕岗的潜力更大,至少前往5号线沿线的站点可以不用绕行2号线,充分体现了8号线北延段为2号线分流的作用。
沙贝受到西村换乘的影响很小,但不能忽视,因为西村换乘开通以后,通过6-5-8进行白云区西部内部的联络会更多,从沙贝-鹅掌坦可以省3.5公里可以看出,这在白云区内东西向动脉12号线开通前很有必要。
总结
总的来说,8北的西村换乘开通与否,对大多数区域而言,仅仅是锦上添花而已,但是对于1号线西段、广佛线前往5号线西段等方向的线路而言,就意义重大。这只是在一个小区域内简化分析,虽然本文主要分析西村换乘对已有线路和站点的影响,但是,西村换乘的开通,最大受益者是8号线北延段的人们前往5号线的小北、珠江新城等区域。
所以通过这个迪杰斯特拉算法的应用,表明了路径是可以被新路径覆盖的。例如芳村-广州火车站就可以由1-2改为1-8-5,充分体现了迪杰斯特拉算法的思想,就是路径被更近的路径覆盖。
不过这只是一个模拟,真正有没有人这样坐地铁,就是开通以后的事情了。我只能希望,这种因换乘未开通而绕路的加价行为不要再发生了。
C. 求公交换乘算法程序
用一个邻接表有向图来表示一个公交系统
如果乘坐某辆公交车能从站点u到达站点v而不需要换线、调头,那么添加一条有向边e=(u,v),并且在边e上附加信息:从u到v的距离(即该边的权值)、该边所属的公交车编号、该边在该公交线路的哪个方向上(因为有可能同一条公交线路两个方向经过不同的站点)
之所以用邻接表是因为这样的图是有重边的
当查询从节点i到节点j的换乘线路时,用dijkstra找出i和j之间的最短路径,那么根据这条路径上的边的附加信息就知道要怎么换乘了
另外,如果需要知道路径最短的基础上怎样换乘的次数最少(也就是在上述的图中经过的边数最少),可对dijkstra作少量调整,对于图中的每个点u,除了记录当前找到的到该点的最短距离dis[u]以及该点的前趋pi[u],还要记录在这样的最短距离和前趋下从起点到该点经过的最少的边数min_edge[u]
那么作dijkstra的时候,对于当前刚找到的路径最短的点u,以及从点u出发的某条边e=(u,v),如果dis[u]+e.length==dis[v]
&&
min_edge[u]+1<min_edge[v](也就是经过边(u,v)与原先的到v的最短路径长度相同但是经过(u,v)可以得到边数更少的路径,那么也要采用(u,v))
回溯是效率非常低的算法,如果没有非常好的优化方案,没事少用
D. 公交线路最少换乘算法设计遇到的一个问题
考虑成两趟不同的公交车试试
公交换乘问题---java解决方案: http://lizemin314.blog.163.com/blog/static/11128512200782331512355/
F. 求教公交换乘算法,我不聪明,麻烦说的明白些,谢谢,财富值有回答时在加,避免浪费,谢谢
三个表(最简单化,不考虑模糊查询,单行线等其他东西):
1,站点表stop(stop_id,stop_name)
2,路线表line(line_id,line_name)
3,路线站点表(点线路关系表)linestops( line_id, stop_id, seq )此处的seq指某站点在某线路中的顺序。
现在分析算法:
1,直达线路
首先根据两个站点名获取两个站点各自的id,这里定义为id1,id2
然后查询
select line_id from
(select line_id from linestops where stop_id = id1) A,
(select line_id from linestops where stop_id = id2) B
where A.line_id = B.line_id
即得到可直达的线路列表
2,一次换乘
首先根据两个站点名获取两个站点各自的id,这里定义为id1,id2
然后搜寻两个站点通过直达方式各自能够到达的站点集合,最后他们的交集就是我们所需要的换乘站点。
select stop_id from
(
select distinct stop_id from linestops where line_id in
(select line_id from linestops where stop_id = id1)
)A,
(
select distinct stop_id from linestops where line_id in
(select line_id from linestops where stop_id = id2)
)B
where A.stop_id= B.stop_id
得到换乘站(可能有多个或0个)后,剩下的就是显示能够到达换乘站的两边线路,这通过前面的直达查询即可。
3,二次换乘
首先根据两个站点名获取两个站点各自的id,这里定义为id1,id2
算法的中心思想是:站点1能够通过直达到达的所有站点集合A,站点2能够通过直达到达的所有站点集合B,A和B之间有直达的线路。
一步一步来:
站点1能够通过直达到达的所有站点集合A:
select distinct stop_id from linestops where line_id in
(select line_id from linestops where stop_id = id1)
站点2能够通过直达到达的所有站点集合B:
select distinct stop_id from linestops where line_id in
(select line_id from linestops where stop_id = id2)
而直达的查询是
select line_id from
1/4页
(select line_id from linestops where stop_id = id1) C,
(select line_id from linestops where stop_id = id2) D
where C.line_id = D.line_id
我们把=id1和=id2换成 in (select ....)A 和 in (select ...)B
这样最后我们的查询是
select line_id from
(select distinct line_id from linestops where stop_id in 【A】) C,
(select distinct line_id from linestops where stop_id in 【B】) D
where C.line_id = D.line_id
其中【A】是
(select distinct stop_id from linestops where line_id in
(select line_id from linestops where stop_id = id1))
其中【B】是
(select distinct stop_id from linestops where line_id in
(select line_id from linestops where stop_id = id2))
这样子我们找到了作为中间换乘的线路(可能有多条或者0条),对列举的的每一条假设命名为X线,下一步就是找出可以从站点1到达X任意一个站点的直达线路、和可以从站点2到达X任意一个站点的直达线路即可。
那么与前面的算法相似,我们在站点1所有能够到达的站点中去寻找和线路X相交的站点,然后再去找这两个点的线路
select stop_id from
(select distinct stop_id
G. 公交2次换乘算法
呃,我来给你说说。先假设一个情况:你的公交次数卡里面有10次余额。你拿公交次数卡在8:13第一次刷卡(还剩下8次),那么在10:13之内的这段时间,你可以在任意一辆接受次数卡的公交车上(除了你在8:13时刷卡的那辆公交车,当然一般不会出现这种情况)再另外刷3次(仍然剩8次)。但是有一个条件:你刷过之后的公交车(注意是公交车,不是公交线路)是不再接受你再次刷次数卡的,这时就要扣你电子钱包里面的钱,如果没有电子钱包你就只有投币。2小时之内你刷卡的次数超过了4次,比如你在8:13刷了一次,在10:13之内,你已经又刷了3次,那么在10:13之内你仍旧需要转乘的话就要另外计算次数。比如你在9:55的时候你已经是乘坐了四次,达到了最高次数,那么转乘就要重新扣你的次数。9:55时你又转乘另外一趟公交车刷次数卡,这时就要重新扣你的次数(只剩下6次)。刷卡的原则是次数优先,如果没有次数就扣电子钱包的钱,如果两种方式都不能足够支付你乘车费用,就只能投币了。转乘不分普通车和中级车,你在普通车上刷了之后拿到中级车上也是不扣次数,但要计入转乘次数的记录。
H. c语言问题: 什么是算法试从日常生活中找3个例子,描述它们的算法。 详细点,谢谢!
c语言中的算法是指:一系列解决问题的清晰指令,用系统的方法描述解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。通俗说就是解决问题的方法和步骤。
描述算法的例子:
问题:从上海去到北京。
其中的算法:做汽车、做飞机、或者徒步。
问题:喝茶。
其中的算法:先找到茶叶,再烧一壶开水,然后将茶叶放到杯子里,将开水倒入杯中,等茶叶泡好。
问题:开车。
其中的算法:首先要打开车门,驾驶员坐好,插上车钥匙,发动汽车。