Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 什么时候使用深度优先搜索(DFS)和广度优先搜索(BFS)是可行的?_Algorithm_Graph Algorithm_Graph Theory_Depth First Search_Breadth First Search - Fatal编程技术网

Algorithm 什么时候使用深度优先搜索(DFS)和广度优先搜索(BFS)是可行的?

Algorithm 什么时候使用深度优先搜索(DFS)和广度优先搜索(BFS)是可行的?,algorithm,graph-algorithm,graph-theory,depth-first-search,breadth-first-search,Algorithm,Graph Algorithm,Graph Theory,Depth First Search,Breadth First Search,我理解DFS和BFS之间的区别,但我想知道什么时候使用一个比另一个更实用 有谁能举例说明DFS如何胜过BFS,反之亦然?DFS比BFS更节省空间,但可能会达到不必要的深度 他们的名字很能说明问题:如果广度大(即分支因子大),但深度非常有限(例如“移动”次数有限),那么DFS可能比BFS更受欢迎 关于IDDFS 应该提到的是,有一种不太为人所知的变体,它结合了DFS的空间效率,但(累积)BFS的级别顺序访问是最重要的。该算法重新访问一些节点,但它只提供了一个渐近差的常数因子。这在很大程度上取决于

我理解DFS和BFS之间的区别,但我想知道什么时候使用一个比另一个更实用


有谁能举例说明DFS如何胜过BFS,反之亦然?

DFS比BFS更节省空间,但可能会达到不必要的深度

他们的名字很能说明问题:如果广度大(即分支因子大),但深度非常有限(例如“移动”次数有限),那么DFS可能比BFS更受欢迎


关于IDDFS
应该提到的是,有一种不太为人所知的变体,它结合了DFS的空间效率,但(累积)BFS的级别顺序访问是最重要的。该算法重新访问一些节点,但它只提供了一个渐近差的常数因子。

这在很大程度上取决于搜索树的结构以及解的数量和位置(也称为搜索项)

  • 如果您知道一个解决方案离树的根不远,那么 广度优先搜索(BFS)可能更好

  • 如果树很深,而解决方案很少,则使用深度优先搜索 (DFS)可能需要非常长的时间,但BFS可能会更快

  • 如果树很宽,BFS可能需要太多内存,因此 可能完全不切实际

  • 如果解决方案是频繁的,但位于树的深处,那么BFS可能会 不切实际

  • 如果搜索树很深,则需要限制搜索 深度优先搜索(DFS)的深度,无论如何(例如 迭代深化)

但这些只是经验法则;你可能需要进行实验


另一个问题是并行性:如果您想并行化BFS,您需要在线程之间共享数据结构,这是一件坏事。如果您不坚持访问节点的确切顺序,DFS可能更容易在连接的计算机之间进行分发。

当树的深度可能不同时,广度优先搜索通常是最佳方法,您只需要搜索树的一部分来寻找解决方案。例如,找到从起始值到最终值的最短路径是使用BFS的好地方


当需要搜索整个树时,通常使用深度优先搜索。它比BFS更容易实现(使用递归),并且需要更少的状态:虽然BFS要求您存储整个“前沿”,但DFS只要求您存储当前元素的父节点列表。

某些算法依赖于DFS(或BFS)的特定属性来工作。例如,用于查找2连接组件的Hopcroft和Tarjan算法利用了这样一个事实,即DFS遇到的每个已访问的节点都位于从根节点到当前探索的节点的路径上。

当您作为程序员处理这个问题时,有一个因素很突出:如果您使用递归,那么,深度优先搜索的实现就更简单了,因为您不需要维护一个包含尚未探索的节点的额外数据结构

如果要在节点中存储“已访问”信息,请使用深度优先搜索非定向图:

def dfs(origin):                               # DFS from origin:
    origin.visited = True                      # Mark the origin as visited
    for neighbor in origin.neighbors:          # Loop over the neighbors
        if not neighbor.visited: dfs(neighbor) # Visit each neighbor if not already visited
如果在单独的数据结构中存储“已访问”信息:

def dfs(node, visited):                        # DFS from origin, with already-visited set:
    visited.add(node)                          # Mark the origin as visited
    for neighbor in node.neighbors:            # Loop over the neighbors
        if not neighbor in visited:            # If the neighbor hasn't been visited yet,
            dfs(neighbor, visited)             # then visit the neighbor
dfs(origin, set())
这与广度优先搜索形成对比,在广度优先搜索中,您需要为尚未访问的节点列表维护一个单独的数据结构,不管发生什么。

来自

BFS的一个例子

这里有一个BFS的例子。这类似于级别顺序树遍历,我们将使用队列和迭代方法(大部分递归将以DFS结束)。这些数字表示在BFS中访问节点的顺序:

在深度优先搜索中,从根开始,尽可能沿着树的一个分支进行搜索,直到找到要查找的节点或找到叶节点(没有子节点的节点)。如果您点击了一个叶节点,那么您将继续在最近的祖先处搜索未探索的子节点

DFS的一个例子

下面是一个DFS的示例。我认为二叉树中的后序遍历将首先从叶级开始。这些数字表示在DFS中访问节点的顺序:

DFS和BFS之间的差异

与BFS和DFS相比,DFS的最大优势在于它的内存需求比BFS低得多,因为它不需要在每一级存储所有的子指针。根据数据和您要查找的内容,DFS或BFS都可能是有利的

例如,给定一个家谱,如果一个人正在寻找树上还活着的人,那么可以安全地假设这个人在树的底部。这意味着BFS需要很长时间才能达到最后的水平。然而,DFS会更快地找到目标。但是,如果一个人正在寻找一个很久以前去世的家庭成员,那么这个人就会离树顶更近。然后,BFS通常比DFS快。因此,这两种方法的优点都因数据和您所寻找的内容而异


另一个例子是Facebook;关于朋友之友的建议。我们需要直接的朋友的建议,我们可以使用BFS。可能是寻找最短路径或检测循环(使用递归),我们可以使用DFS

根据DFS和BFS的性质。 例如,当我们想要找到最短路径时。 我们通常使用bfs,它可以保证“最短”。
但是dfs只能保证我们可以从这一点出发,可以达到那一点,不能保证“最短”。BFS的一个重要优点是,它可以用来找到未加权图中任意两个节点之间的最短路径。 鉴于,.

深度优先搜索 深度优先搜索常用于搜索引擎
1,1,1,1,1,1,1,1, 
1,1,1,1,1,1,1,1, 
1,1,1,1,1,1,1,1, 
0,0,0,0,0,0,0,0,