【问题标题】:Breadth-first search with set instead of queue使用集合而不是队列的广度优先搜索
【发布时间】:2016-07-30 22:32:38
【问题描述】:

我正在使用 BFS 来查找连接的组件。我决定使用一组来跟踪访问的节点来实现它。这种方法的问题是一个顶点可能会被添加到队列中两次。所以我只是将队列更改为设置。我不关心访问顺序,所有节点都被访问一次并且算法工作正常。当然,这不再是经典的 BFS:顺序被打破了。

伪代码:

Set visited;
Set to_visit; 
visited.insert(start)
to_visit.insert(start)
while (to_visit is not empty){
    current = to_visit.first
    to_visit.delete(current)
    for each neighbour of current {
        isNew = visited.insert(neighbour)
        if (isNew) {
            to_visit.insert(neighbour)
        }
    }
}

我很确定我不是第一个“发明”它的人。我想知道:这个 I-dont-care-first 搜索是如何调用的?

【问题讨论】:

    标签: graph breadth-first-search


    【解决方案1】:

    如何将它添加到队列中两次?您必须确保队列上的元素是唯一的,如果顶点是对象添加标志“visited=false”,当您尝试将顶点添加到队列中时,您首先检查标志,只有在它为假时才继续,然后将其更改为真。

    如果顶点只是一个数字,则创建一个布尔数组来表示每个顶点的标志。

    伪代码:

    queue= []
    set = [0,0,0,0,0....,0]
    queue.push(firstVertex)
    
    while(!queue.isEmpty())
    {
         vertex curr = queue.pop()
    
         if(set[curr] == 1) //already visited
         {
              continue;
         }
         set[curr] = 1;
         foreach(child of curr)
         {
              queue.push(child);
         }
    }
    

    您还可以将标志从真/假更改为组件数。

    【讨论】:

    • 谢谢,我知道 BFS 的正确实施。实际上我也在做同样的事情,但是按组保持队列的唯一性。在我的实现中,一个顶点在真正被访问时被访问,而不是在添加到队列时被访问。
    • 是的,设置它也应该可以工作,只需将 isVisited 更改为 mySet[vertex] = 1 或其他什么?但是顺序还是一样的。我看到你的问题了!您可以在开头添加 if 语句并检查 curr 是否已被访问。我将我的伪代码更改为您的想法。
    • if(set[curr] == 1) 篡改了算法的复杂性。一个顶点可以被多次考虑。
    • 比使用一组标记添加到队列中的顶点和一组实际访问的顶点。
    • .... 这正是我所做的!但是队列本身是没用的,因为我可以从集合中取节点访问。
    猜你喜欢
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多