在我的经济学研究中,我目前正在处理一个特定的最短路径问题:
给定有向权重的确定性动态图,在边缘上,我需要找到一个源S的最短路径,该路径穿过N条边缘。该图可以具有周期,边缘权重可以为负,并且路径可以多次通过顶点或边缘。
是否有解决此问题的有效算法?
答案 0 :(得分:1)
一种可能性是:
首先找到图中最低的边缘权重。
,然后建立一个从起始边缘开始的所有路径的优先级队列(最初是从起始点开始的空路径),在该队列中,所有尚未处理的边缘都被认为具有最低权重。
主循环:
但是,这种简单的算法有一个缺陷-您可能会以第i个边缘的形式多次访问顶点(访问第2个和第4个边缘是可以的,但是在两个不同的路径中访问第4个是可以的),这效率很低。
可以通过在上面的第3步中跳过它们来改进算法,因为优先级队列可确保到达顶点的第一部分路径的权重和最低,而其余路径不依赖于您到达顶点的方式(因为可以复制边和顶点)。
答案 1 :(得分:0)
“完全N
边”约束使此问题比不存在该约束容易得多。从本质上讲,您可以求解N = 0(仅是起始节点),使用它来求解N = 1(起始节点的所有邻居),然后求解N = 2(解决方案的邻节点N = 1,采用成本最低的路径)对于连接到多个节点的节点),等等。
在伪代码中(使用{field: val}
表示“具有值为field
的名为val
的字段的记录”)
# returns a map from node to cost, where each key represents
# a node reachable from start_node in exactly n steps, and the
# associated value is the total cost of the cheapest path to
# that node
cheapest_path(n, start_node):
i = 0
horizon = new map()
horizon[start_node] = {cost: 0, path: []}
while i <= n:
next_horizon = new map()
for node, entry in key_value_pairs(horizon):
for neighbor in neighbors(node):
this_neighbor_cost = entry.cost + edge_weight(node, neighbor, i)
this_neighbor_path = entry.path + [neighbor]
if next_horizon[neighbor] does not exist or this_neighbor_cost < next_horizon[neighbor].cost:
next_horizon[neighbor] = {cost: this_neighbor_cost, path: this_neighbor_path}
i = i + 1
horizon = next_horizon
return horizon
我们考虑使用edge_weight(node, neighbor, i)
的动态权重,意思是“在时间node
时从neighbor
到i
的成本。
这是像Dijkstra算法那样的单源最短路径算法的简并版本,但是它要简单得多,因为我们知道我们必须精确地走N步,所以我们不必担心陷入负重循环中,重量较轻的长路径等等。