【问题标题】:Python Breadth First Search optimisationPython 广度优先搜索优化
【发布时间】:2013-05-20 18:32:25
【问题描述】:

鉴于此代码...

import Queue

def breadthFirstSearch(graph, start, end):
    q = Queue.Queue()
    path = [start]
    q.put(path)
    while not q.empty():
        path = q.get()
        lastNode = path[len(path) - 1]
        if lastNode == end:
            return path
        for linkNode in graph[lastNode]:
            if linkNode not in path:
                newPath = []
                newPath = path + [linkNode]
                q.put(newPath)

其中graph是表示有向图的字典,例如{'stack':['overflow'], 'foo':['bar']},即stack指向overflow,foo指向bar。

这种广度优先搜索可以进一步优化吗?因为我打算在一个非常大的字典上使用它。

【问题讨论】:

  • 虽然这可能不是一个大的优化,但Queue.Queue 旨在用于多个线程之间的同步。如果只需要一个简单的队列数据结构,请改用collections.deque,避免同步开销。
  • 当我使用它时,我得到了不同的答案,但我不知道为什么......

标签: python optimization dictionary


【解决方案1】:

为什么不保留一组访问过的节点,这样您就不会一直访问相同的节点?这应该可以工作,因为它看起来不像您使用的是加权图。像这样的:

import Queue

def bfs(graph, start, end):
    q = Queue.Queue()
    path = [start]
    q.put(path)
    visited = set([start])

    while not q.empty():
        path = q.get()
        last_node = path[-1]
        if last_node == end:
            return path
        for node in graph[last_node]:
            if node not in visited:
                visited.add(node)
                q.put(path + [node])

【讨论】:

  • 感谢您的回复,我现在要测试它并回复您。再次感谢。
  • 我不知道为什么,但是代码卡在了线上:while not q.empty():
  • @Clay 我完全忘记在我的代码中添加path = q.get(),这可能无济于事......
  • 你是个天才。我试过了,现在我没有访问 100000+ 个节点两次,它的工作速度更快!非常感谢:)
  • 顺便说一句,我认为使用collections.deque 会更快,因为Queue.Queue 是高度同步的,在这种情况下这只是一个负担。请参阅 Keith Gaughan 的 this answer
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-16
  • 1970-01-01
相关资源
最近更新 更多