关于算法:图中节点之间的最短路径

The shortest path between nodes in graph

我不知道是否应该在这里问这个问题,这个问题与算法有关。假设您有一个无向图。边具有不同的值。想象一下,有些顶点是"好",有些顶点是"坏"。现在,我要确定两个良好的节点,以使它们之间的路径最短(如果路径中包含不良节点,这不是问题)。


您想要做的是立即开始从所有好的节点开始增加路径,然后在发现两个节点相遇后立即停止。然后,您找到了最短的路径。

有一个细微的并发症。考虑一个三角形的ABC。如果A-B和B-C的权重均为2,而A-C的权重为3,则在A-C之前查看边缘A-B和B-C。这意味着您在A-C(权重3)之前找到路径A-B-C(权重4)。但是,在所有这些情况下,您都会在找到第一个边缘之前就已经看到边缘存在。

这里是伪代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
node_path_info is is a dictionary of vertex to information about the path
upcoming is priority queue of vertices to consider next, sorted on .cost

initialize node_path_info and upcoming
for node in list of good nodes:
    upcoming.add( {
       "node": node,
       "node_from": None,
       "cost": 0,
       "good_node", node,
    } )

best_path_cost = None
best_middle1 = None
best_middle2 = None
while upcoming:
    current = upcoming.pop()
    if current.node in good_node_from:
        if current.good_node == good_node_from[current.node]:
            pass # We found a loop
        else:
            cost = current.cost + node_path_info[current.node].cost
            if best_path_cost is None or cost < best_path_cost < best_path_cost:
                best_path_cost = cost
                best_middle1 = current.node
                best_middle1 = current.node_from
    else:
        node_path_info[current.node] = current
        if best_path_cost is not None: # still looking for first path
            for (next_node, weight) in get_connected_weight(current.node):
                upcoming.add({
                   "node": next_node,
                   "node_from": current.node,
                   "cost": current.cost + weight,
                   "good_node", current.good_node,
                })

path1 = path from best_middle1 back
path2 = path from best_middle2 back
path1 + reversed(path2) is your answer.

在最坏的情况下,您将需要两次访问所有边缘。使用随机连接的图和2个良好的节点,您将访问连接到O(sqrt(n))顶点的所有边。


一种方法是向每个良好节点添加具有定向连接(权重为0)的源节点。

然后运行Dijkstra的算法来查找从源节点到其他每个节点的最短路径。

在运行Dijkstra的算法时,还要跟踪哪个好节点是最近的。

然后在边缘A-> B上进行最后遍历,以找到"距A的良好节点的距离","距边缘的权重"和"距B的良好节点的距离"的最便宜值,仅包括距离最近的良好A的节点不等于B的最近的良好节点。