如何使用 BFS 按顺序获取包含某些给定节点的路径?
How can I use BFS to get a path containing some given nodes in order?
我有一个带有未加权边的图,其中每个节点都标有字母 'a' 到 'z'。
我想修改 BFS 算法以获得包含顺序为 'c'、'o'、'd'、'e' 的最短路径。这四个字母之间可能还有其他字母。您有起始节点 'a' 和结束节点 'b'。您可以假设它始终是按顺序包含这四个字母的路径。如何修改 BFS 以满足该条件?
如果你知道如何用BFS找到两个节点之间的最短路径,那么问题就可以解决如下:
- 求从a到c
的最短路径
- 求从c到o
的最短路径
- 求从o到d
的最短路径
- 求从d到e
的最短路径
- 求从e到b
的最短路径
- 连接以上5条路径,得到一条从a到b.
的路径
这是 Python 中的一个实现:
class Node:
def __init__(self, name):
self.name = name
self.neighbors = []
def link(self, node):
# The edge is undirected: implement it as two directed edges
self.neighbors.append(node)
node.neighbors.append(self)
def shortestPathTo(self, target):
# A BFS implementation which retains the paths
queue = [[self]]
visited = set()
while len(queue):
path = queue.pop(0) # Get next path from queue (FIFO)
node = path[-1] # Get last node in that path
for neighbor in node.neighbors:
if neighbor == target:
# Found the target node. Return the path to it
return path + [target]
# Avoid visiting a node that was already visited
if not neighbor in visited:
visited.add(neighbor)
queue.append(path + [neighbor])
# Create the nodes of the graph (indexed by their names)
graph = {}
for letter in 'abcdefo':
graph[letter] = Node(letter)
# Create the undirected edges
for start, end in ['ab','ae','bc','be','bo','df','ef','fo']:
graph[start].link(graph[end])
# Concatenate the shortest paths between each of the required node pairs
start = 'a'
path = [graph['a']]
for end in ['c','o','d','e','b']:
path.extend( graph[start].shortestPathTo(graph[end])[1:] )
start = end
# Print result: the names of the nodes on the path
print([node.name for node in path])
代码中创建的图形如下所示:
输出为:
['a', 'b', 'c', 'b', 'o', 'f', 'd', 'f', 'e', 'b']
我有一个带有未加权边的图,其中每个节点都标有字母 'a' 到 'z'。
我想修改 BFS 算法以获得包含顺序为 'c'、'o'、'd'、'e' 的最短路径。这四个字母之间可能还有其他字母。您有起始节点 'a' 和结束节点 'b'。您可以假设它始终是按顺序包含这四个字母的路径。如何修改 BFS 以满足该条件?
如果你知道如何用BFS找到两个节点之间的最短路径,那么问题就可以解决如下:
- 求从a到c 的最短路径
- 求从c到o 的最短路径
- 求从o到d 的最短路径
- 求从d到e 的最短路径
- 求从e到b 的最短路径
- 连接以上5条路径,得到一条从a到b. 的路径
这是 Python 中的一个实现:
class Node:
def __init__(self, name):
self.name = name
self.neighbors = []
def link(self, node):
# The edge is undirected: implement it as two directed edges
self.neighbors.append(node)
node.neighbors.append(self)
def shortestPathTo(self, target):
# A BFS implementation which retains the paths
queue = [[self]]
visited = set()
while len(queue):
path = queue.pop(0) # Get next path from queue (FIFO)
node = path[-1] # Get last node in that path
for neighbor in node.neighbors:
if neighbor == target:
# Found the target node. Return the path to it
return path + [target]
# Avoid visiting a node that was already visited
if not neighbor in visited:
visited.add(neighbor)
queue.append(path + [neighbor])
# Create the nodes of the graph (indexed by their names)
graph = {}
for letter in 'abcdefo':
graph[letter] = Node(letter)
# Create the undirected edges
for start, end in ['ab','ae','bc','be','bo','df','ef','fo']:
graph[start].link(graph[end])
# Concatenate the shortest paths between each of the required node pairs
start = 'a'
path = [graph['a']]
for end in ['c','o','d','e','b']:
path.extend( graph[start].shortestPathTo(graph[end])[1:] )
start = end
# Print result: the names of the nodes on the path
print([node.name for node in path])
代码中创建的图形如下所示:
输出为:
['a', 'b', 'c', 'b', 'o', 'f', 'd', 'f', 'e', 'b']