【问题标题】:find first n edges,breadth first search找到前n条边,广度优先搜索
【发布时间】:2013-02-08 13:17:19
【问题描述】:

问题:在有向循环图中给定一个边对象,找到前 n 个最近的边(2000)。

数据结构:链接类和节点类。链接类有一个 from 和 to 节点,指向各自的节点对象。节点对象具有链接对象的传入和传出列表。

错误:我遇到 RuntimeError: 超出最大递归深度。您能帮我找到解决方法吗?如果逻辑有问题或代码需要解决,请告诉我进行优化。我相信我遵循 BFS 策略,即从对象相关节点中创建一个队列,我可以遍历这些节点并查看它是否已被访问并尝试递归。

def start_search(self,link_object,neighbour_links):
    buffer_links=[]
    link_object.visited_flag=1
    neighbour_links.append(link_object)
    from_node=link_object.from_node
    to_node=link_object.to_node
    [buffer_links.append(link_object) for link_object in from_node.incoming_links]
    [buffer_links.append(link_object) for link_object in from_node.outgoing_links]
    [buffer_links.append(link_object) for link_object in to_node.outgoing_links]
    [buffer_links.append(link_object) for link_object in to_node.incoming_links]
    while len(buffer_links)>0 and len(neighbour_links)<1000:
        link_object=buffer_links.pop()
        if link_object.visited_flag==0:
           self.start_search(link_object,neighbour_links)
    return neighbour_links

【问题讨论】:

  • 考虑将您的图表示为字典:successors[node] -> set([nodes])。这种形式紧凑且易于编写图算法。

标签: python algorithm breadth-first-search directed-graph


【解决方案1】:

您可以通过在节点上使用先进的波前算法(广度优先搜索)来避免使用递归。这是算法的概述,它是一个小的适应,使其适用于边缘:

  1. 使用最初为空的字典 top_dist 跟踪拓扑距离。
  2. dist = 0
  3. 将初始节点放入集合wavefront
  4. wavefront中的每个节点设置top_dist[node] = dist
  5. 对于与wavefront 相邻但不在top_dist 中的每个节点,添加该节点以设置next_wavefront
  6. 递增dist
  7. 设置wavefront = next_wavefront
  8. 从 4 开始重复,直到无法访问更多节点。

如果某些节点仍未被访问,则图有多个弱组件。

如果步骤 3 中的初始节点是初始边的端点,那么您可以在边的节点上使用 top_dist 映射来获取到边的距离。我认为到边缘的距离的有用定义是min(top_dist(e1), top_dist(e2)) + 1。现在你已经有了到每条边的距离,你可以抓取最近的 2000。

这个算法是 O(|N|+|E|)——在边数和节点数的总和上是线性的。

【讨论】:

    【解决方案2】:

    使用 DAG 表示为映射到其后继节点的节点字典,您可以在发现节点时循环遍历它们:

    >>> def bfs(dag, start, maximum):
            'Breadth-first search up to a given maximum number of nearest nodes'
            nearest = [start]
            seen = {start}
            for pred in nearest:
                for succ in dag.get(pred, ()):
                    if succ not in seen:
                        seen.add(succ)
                        nearest.append(succ)
                        if len(nearest) == maximum:
                            return nearest
            return nearest
    >>> dag = {'start': ['a', 'b', 'c'],
               'b': ['m', 'n'],
               'c': ['n', 'z'],
               'n': ['z'],
              }
    >>> bfs(dag, 'start', 5)
    ['start', 'a', 'c', 'b', 'z']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-31
      • 1970-01-01
      • 2013-05-05
      • 1970-01-01
      • 1970-01-01
      • 2016-02-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多