我使用的是我在网上找到的用Python编写的Dijkstra算法版本,效果很好。但因为这是公交线路,改变10次可能是最短的路线,但可能不是最快的,绝对不是最简单的。我需要以某种方式修改它以返回具有最少数量的更改的路径,无论距离是否诚实(显然,如果2条路径具有相同数量的更改,则选择最短的更改)。我目前的代码如下:
from priodict import priorityDictionary
def Dijkstra(stops,start,end=None):
D = {} # dictionary of final distances
P = {} # dictionary of predecessors
Q = priorityDictionary() # est.dist. of non-final vert.
Q[start] = 0
for v in Q:
D[v] = Q[v]
print v
if v == end: break
for w in stops[v]:
vwLength = D[v] + stops[v][w]
if w in D:
if vwLength < D[w]:
raise ValueError, "Dijkstra: found better path to already-final vertex"
elif w not in Q or vwLength < Q[w]:
Q[w] = vwLength
P[w] = v
return (D,P)
def shortestPath(stops,start,end):
D,P = Dijkstra(stops,start,end)
Path = []
while 1:
Path.append(end)
if end == start: break
end = P[end]
Path.reverse()
return Path
stops = MASSIVE DICTIONARY WITH VALUES (7800 lines)
print shortestPath(stops,'Airport-2001','Comrie-106')
我必须诚实 - 我不是数学家,所以尽管我对它进行了全部研究,但我并不完全理解这个算法。
我尝试过改变一些事情,但我甚至不能接近。
有任何帮助吗?谢谢!
答案 0 :(得分:1)
这是一个可能的解决方案:
1)从起始顶点开始广度优先搜索。它将找到具有最少变化的路径,但不是最短的路径。让我们假设在运行广度后第一次搜索dist [i]是开始和i顶点之间的距离。
2)现在可以在修改的图上运行Djikstra算法(仅添加满足此条件的初始图中的那些边:dist [from] + 1 == dist [to])。此图表中的最短路径是您要查找的路径。
P.S如果你不想使用广度优先搜索,你可以在制作所有边缘之后使用Djikstra算法。权重等于1.
答案 1 :(得分:0)
如果您需要更改线路,我会做的是为实际成本添加一个偏移量。例如,如果边缘权重代表2个站之间所需的时间,我会在搜索过程中在站X的Line1 Line2之间添加平均等待时间(例如0.5 * maxWaitingTime)。当然,这是该问题的启发式解决方案。如果你的时间表已知,你可以计算一个&#34;确切的&#34;解决方案或至少满足模型的解决方案,因为实际上你不能假设每辆公交车都是准时的。
答案 2 :(得分:0)
解决方案很简单:不使用距离作为权重,而是每次停止使用1的wright。 Dijkstra的算法将根据您的要求最小化更改次数(总路径权重是乘坐次数,即+1的变化次数)。如果你想用距离打破关系,可以使用
之类的东西 vwLength = D[v] + 1+ alpha*stops[v][w]
其中alpha <&lt;&lt; 1,例如阿尔法= 0.0001
实际上,我觉得你的方法被夸大了。即使两个航班最少,您也不想通过巴黎从波士顿飞往多伦多。我会使用alpha来获得总旅行时间的近似值,这可能很重要。