您可以在这种情况下使用 BFS。这是我几年前根据我对一些 AI 课程的记忆编写的算法。我不能确保它完美无缺,但希望它能给你一些提示。
令X(p, d)表示节点X,其父节点为p,与父节点的距离为d。
function findAllShortestPaths(...):
RET = set()
queue = [S(None, 0)]
explored = set()
while queue is not empty:
Node = queue.dequeue()
if Node is the one we're searching for:
if Node is not in RET:
RET.add(Node)
else:
if Node.d <= d of the node in RET:
RET.add(Node)
continue
if Node is not in explored:
explored.add(Node)
else:
if Node.d <= d of the node in explored:
explored.add(Node)
else:
continue
for Child in Node.childrens:
if Child is not in explored:
queue.append(Child(Node, Node.d + 1))
return RET, explored
这是一个例子。假设您有一个 5 点(A、B、C、D、E)图,其线连接如下; AB、BC、CD、DA、EA、EB、EC、ED。您想找到从 A 到 C 的所有最短路径。
设X(parent, distance) ---> Y(...) Z(...) 表示 X 被添加到探索集,Y 和 Z 是 X 的孩子,它们被添加到队列中。
A(None, 0) ---> B(A, 1) E(A, 1) D(A, 1)
B(A, 1) ---> E(B, 2) C(B, 2)
E(A, 1) ---> C(E, 2) D(E, 2)
D(A, 1) ---> C(D, 2)
[E(B, 2) already in the explored list and the distance is 2 > E(A, 1), continue.]
C(B, 2) ---> Our GOAL, add to RET
C(E, 2) ---> Our GOAL, C already in RET but distance is equal, add to RET
[D(E, 2) already in the explored list and the distance is 2 > D(A, 1), continue.]
C(D, 2) ---> Our GOAL, C already in RET but distance is equal, add to RET
最后,RET 包含 C(B, 2), C(E, 2), C(D, 2)。从这里并结合探索列表,您可以追溯到源节点。例如,C(B, 2) B(A, 1) A(None, 0)。
可能会有一些错误,但我认为这没什么大不了的。对于第二个问题,一旦我们弄清楚了第一个问题,它就不会太远了。希望对您有所帮助!