Algorithm 如何在无向图中加速广度优先搜索

Algorithm 如何在无向图中加速广度优先搜索,algorithm,Algorithm,我认为我们可以使用队列进行广度优先搜索(BFS)遍历,因为队列中的add()和remove()是常数时间,所以我认为BFS从起始节点到目标节点的遍历是线性时间 但是如何加速BFS呢?是否有一种数据结构可以降低这种时间复杂度?您可以通过执行来加快BFS从源到目标的速度 双向搜索基本上是同时从源和目标进行BFS,每次一步,直到两条战线相遇 为什么更好? 最坏情况下的BFS发现O(B^d)节点(B是分支 系数,每个节点的阶数)和d是 解决方案 最坏情况下的双向BFS发现O(B^(d/2)*2)=O(

我认为我们可以使用队列进行广度优先搜索(BFS)遍历,因为队列中的add()和remove()是常数时间,所以我认为BFS从起始节点到目标节点的遍历是线性时间


但是如何加速BFS呢?是否有一种数据结构可以降低这种时间复杂度?

您可以通过执行来加快BFS从源到目标的速度

双向搜索基本上是同时从源和目标进行BFS,每次一步,直到两条战线相遇

为什么更好?

  • 最坏情况下的BFS发现
    O(B^d)
    节点(
    B
    是分支 系数,每个节点的阶数)和
    d
    是 解决方案
  • 最坏情况下的双向BFS发现
    O(B^(d/2)*2)=O(B^(d/2))
    节点 通常要小得多

根据经验,对于大型/无限图,双向搜索通常比常规BFS更快。

最坏情况下的时间在节点数量上是线性的(这是可以明显实现的)。您可以通过启发式方法加快搜索速度,也就是说,不要将新节点添加到队列中,而是将它们添加到优先级队列中,其中优先级是衡量新节点似乎离目标有多近的某种度量

另一种加速的方法是并行工作,即将要处理的节点队列分配给工作线程。但是,您需要确保没有(或至少没有太多)节点被多次访问


除非您试图处理的图形非常庞大,否则我不会太担心这一点,因为从性能角度来看,这里没有什么可压缩的。测量系统的瓶颈所在,并集中精力解决它们。只有在性能不够的情况下才这样做,否则就花时间在海滩上(或者你最喜欢做的任何事情)。

我建议避免使用缩写词,因为你不能假设每个人都知道BFS代表什么(我假设它的广度优先搜索)@扎克斯彭斯:我认为人们几乎可以假设人们知道BFS在图形算法中的含义。我仍然认为链接到维基百科的文章或其他东西是个好主意。我同意大多数人都会知道BFS的意思。哈哈,我不知道你多久会在[algorithm]上提出双向图搜索(bi-directional graph search):D令人惊讶的是,这种情况经常出现up@NiklasB. 从我的经验来看,它比未提供信息和未加权的图形快得多,为什么不分享这些知识呢?当然,我以前并不知道这个概念。绝对没什么问题,很酷,谢谢。它确实减少了遍历的节点数,但时间仍然是线性的,对吗?@Amny:是的,运行时是线性的。它需要的是,因为它需要考虑最坏情况下的所有节点和边,所以线性时间是该算法的下界,因此,在人工智能领域中,图FS是非常常用的,其中图是状态图。我不喜欢你提出的避免优化的建议。广度优先搜索的最坏情况是节点数的二次方,而不是线性。然而,它的边数是线性的。@Gassa,不可能。如果搜索失败,BFS将只访问每个节点一次。对,我们访问每个节点不超过一次。但是我们如何在恒定的时间内从每个节点遍历多达N条边呢?这里,N是节点数。好的,这是一个图表。它由名为1、2、100-199和200-299的顶点组成(总共202个顶点)。我们搜索从1到2的路径。有100条边1-1x(即1-100、1-101、…、1-199),10000条边1XX-2YY和100条边2YY-2,总共10200条边。现在,当访问顶点1xx时,我们必须考虑所有10000个边到2yy。如果我们不这样做,考虑向图中添加一个边,例如,134-2,改变最短路径。我们不确定没有从1xx到2的这种边缘,除非我们把它们都考虑在内。