【问题标题】:How to find the nearest node using BFS?如何使用 BFS 找到最近的节点?
【发布时间】:2021-01-30 20:46:52
【问题描述】:

G(V,E) 为无向无权图,rV 的子集。现在将节点root 添加到G 并在rootr 的所有节点之间添加边。现在对于V-r 的每个节点,我想使用BFS 找到r 的最近节点。请帮忙。我试过下面的代码。

import networkx as nx
import matplotlib.pyplot as plt

def bfs(g, node):
    dist = 0
    visited = [node]
    queue = [(node, dist)]
    tr = {}
    while queue:
        s, dist = queue.pop(0)
        tr[s] = []
        for nbr in list(g.adj[s]):
            if nbr not in visited:
                visited.append(nbr)
                tr[s].append(nbr, dist+1)
                queue.append((nbr, dist+1))
    return tr

G=nx.erdos_renyi_graph(50,0.1)

r=[5,8,36,43,21]
G.add_node('root')
for i in r:
    G.add_edge(i,'root')

t = bfs(G, 'root')
print(t)

【问题讨论】:

  • 您显示的代码有什么问题,或者您对此有何疑问?请向minimal reproducible example 显示未按预期工作的内容。
  • 我想为 V-r 的每个节点找到 r 的最近节点。上面的代码用每个节点到根节点的距离构造了 G 的广度优先树。 @mkrieger1
  • 我想也许你正在寻找的是 Dijkstra 的最短路径算法,而不是 BFS。您的问题令人困惑的是,当您为 V-r 的“每个”节点说 r 的“最近”节点时。我想也许你的意思是,对于集合 V-r 中的每个节点,你想以尽可能低的成本从 r 到达那个节点,是吗?在这种情况下,您需要在每对节点 (r, node1), (r, node2), (r, node3) 上运行 Dijkstra,并随时跟踪列表列表中的路径。

标签: python graph-theory graph-algorithm breadth-first-search tree-traversal


【解决方案1】:

我不明白root 节点在这个问题中的用途。我认为,解决此问题的最简单方法是,您从所有 V-r 节点调用 bfs。每次,当您能够到达属于r 的节点时,您将其返回。因为它是属于r 的第一个可达节点。这是此过程的示例:

import networkx as nx
import matplotlib.pyplot as plt

def bfs(g, node, r):
    dist = 0
    visited = [node]
    queue = [(node, dist)]
    #tr = {}
    while queue:
        s, dist = queue.pop(0)
        #tr[s] = []
        for nbr in list(g.adj[s]):
            if nbr not in visited:
                if nbr in r:
                    return (nbr, dist+1)
                
                visited.append(nbr)
                #tr[s].append((nbr, dist+1))
                queue.append((nbr, dist+1))
    #return tr
    return (NaN, NaN)

G=nx.erdos_renyi_graph(50,0.1)

r=[5,8,36,43,21]
G.add_node('root')
for i in r:
    G.add_edge(i,'root')

for n in list(G.nodes):
    if n not in r:
        t, d = bfs(G, n, r)
        print("Node {}'s nearest node in r: {} with distance: {}".format(n, t, d))

由于erdos_renyi 是一个随机图,所以它可以在不同的运行中给出不同的结果。这是一个示例输出:

Node 0's nearest node in r: 5 with distance: 2
Node 1's nearest node in r: 8 with distance: 1
Node 2's nearest node in r: 43 with distance: 2
Node 3's nearest node in r: 36 with distance: 2
Node 4's nearest node in r: 36 with distance: 2
Node 6's nearest node in r: 5 with distance: 2
Node 7's nearest node in r: 36 with distance: 2
Node 9's nearest node in r: 36 with distance: 1
Node 10's nearest node in r: 36 with distance: 2
Node 11's nearest node in r: 8 with distance: 2
Node 12's nearest node in r: 8 with distance: 3
Node 13's nearest node in r: 8 with distance: 2
Node 14's nearest node in r: 8 with distance: 2
Node 15's nearest node in r: 36 with distance: 3
Node 16's nearest node in r: 36 with distance: 3
Node 17's nearest node in r: 8 with distance: 1
Node 18's nearest node in r: 8 with distance: 1
Node 19's nearest node in r: 8 with distance: 1
Node 20's nearest node in r: 21 with distance: 1
Node 22's nearest node in r: 36 with distance: 2
Node 23's nearest node in r: 21 with distance: 2
Node 24's nearest node in r: 21 with distance: 1
Node 25's nearest node in r: 5 with distance: 1
Node 26's nearest node in r: 5 with distance: 1
Node 27's nearest node in r: 36 with distance: 3
Node 28's nearest node in r: 36 with distance: 2
Node 29's nearest node in r: 5 with distance: 1
Node 30's nearest node in r: 21 with distance: 1
Node 31's nearest node in r: 43 with distance: 1
Node 32's nearest node in r: 36 with distance: 3
Node 33's nearest node in r: 5 with distance: 2
Node 34's nearest node in r: 8 with distance: 2
Node 35's nearest node in r: 36 with distance: 2
Node 37's nearest node in r: 36 with distance: 3
Node 38's nearest node in r: 43 with distance: 1
Node 39's nearest node in r: 8 with distance: 2
Node 40's nearest node in r: 43 with distance: 1
Node 41's nearest node in r: 43 with distance: 2
Node 42's nearest node in r: 8 with distance: 2
Node 44's nearest node in r: 43 with distance: 2
Node 45's nearest node in r: 43 with distance: 2
Node 46's nearest node in r: 5 with distance: 2
Node 47's nearest node in r: 8 with distance: 1
Node 48's nearest node in r: 36 with distance: 1
Node 49's nearest node in r: 5 with distance: 2
Node root's nearest node in r: 5 with distance: 1

您甚至可以进一步优化此解决方案。首先,为V-r 节点创建一个列表,该列表将存储从r 节点到该节点的最短距离。用一些大的(即无限的)值初始化这个列表。现在,您可以从所有 r 节点调用 bfs 并在可能的情况下更新距离列表,而不是为每个 V-r 节点调用 bfs。通过这个过程,如果len(r) << len(V-r),您将减少对bfs 的调用。我希望这能解决您的问题。

【讨论】:

    猜你喜欢
    • 2021-09-16
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-04
    • 2021-11-27
    • 2020-03-31
    相关资源
    最近更新 更多