集束搜索BeamSearch

在开始写关于集束搜索的文章之前,我发现我对很多相关的算法都不是很熟悉,这严重影响到了我对集束搜索的理解,为了能让自己更好的理解集束搜索,我又回顾了一些基础。

我的回顾之旅:

BFS算法中,我总结了两篇二叉树的BFS搜索无向图的BFS搜索,在理解BFS搜索算法的过程中又额外涉及到了通过树的中序和先序遍历生成二叉树存储无向图的邻接矩阵和邻接链表这两个知识点,有兴趣的朋友可以查看我的文集“算法之旅”。

好了,闲话不多说,我们先开始说一说什么是集束搜索吧。

Beam Search

尽管广度优先搜索BFS能够保证在无权无向图中找到起点与终点之间的最短路径,但是由于该算法对存储的消耗是指数级别的,因此对于搜索空间较大的问题,广度优先搜索算法几乎无用武之地,因为往往在找到最优解之前,存储内存就已经消耗完了,但是如果我们不得不去在一个搜素空间较大的图中寻找两点之间的路径时,我们该怎么办呢?前人给了我们这样一个解决方法:那就是放宽对路径的要求,不再要求路径一定是最短路径,退而求其次,寻找一个相对较短的路径,这个相对值是可以在我们能接受的范围之内的,这种解决方案就是集束搜索的算法思想了。

集束搜索Beam Search借助了一个启发式代价函数henuristic cost function,h用来预测当前节点到目标节点的代价的大小,这个启发式代价函数我们不是第一次接触了,在上一篇文章A*搜索算法中我们已经详细介绍了,除此之外,集束搜索还是用了一个束宽度beam width,B来限制在每一层的遍历时存储该层的节点数量。

在BFS算法中,我们是将每一层的所有节点都存储到队列queue中,而集束搜索是根据h的值,只选择B个节点存储到队列中,这样的话我们就能保证在得到结果之前将存储耗尽的情况了。

现在我们来分析一下集束搜索:

通过考虑四个特征来分析图搜索算法通常是有效的:

    完整性:如果搜索算法在解决方案存在时找到解决方案(目标节点),则搜索算法已完成。

    最优性:如果找到最优解,搜索算法是最优的。在波束搜索算法的情况下,这意味着算法必须找到从起始节点到目标节点的最短路径。

     时间复杂度:这是算法速度的数量级估计。通过分析算法执行期间生成的节点数来确定时间复杂度。

    空间复杂度:这是算法的内存消耗的数量级估计。空间复杂度由算法执行期间任何时候必须存储的最大节点数决定。

完整性

通常,光束搜索算法不完整。这在上面的跟踪1中说明。即使内存没有耗尽,算法也无法找到目标,因为它无法向BEAM添加任何节点。因此,即使给定无限的时间和存储器,当存在从起始节点到目标节点的路径时,波束搜索算法也可能错过目标节点。更准确的启发式功能和更大的波束宽度可以提高Beam Search找到目标的机会。然而,这种完整性的缺乏是光束搜索算法的最重要的弱点之一。

最优

正如光束搜索算法不完整一样,它也不能保证是最佳的。这由上面的跟踪2显示。在此示例中,Beam Search找到了目标节点,但未能找到目标的最佳路径,即使图1中的启发式是可接受的(低估了每个节点的目标成本)和一致性(低估了相邻节点之间的成本) )。这是因为波束宽度和不准确的启发函数导致算法错过扩展最短路径。更精确的启发式功能和更大的波束宽度可以使Beam Search更有可能找到达到目标的最佳路径。

时间复杂性

光束搜索算法完成的时间往往取决于启发式函数的准确性。不准确的启发式函数通常会强制算法扩展更多节点以找到目标,甚至可能导致它无法找到目标。在最坏的情况下,启发式函数将Beam Search一直引导到搜索树中最深的层次。因此,最坏情况时间是 O(Bm),其中B是波束宽度,m是搜索树中任何路径的最大深度。这种时间复杂度是线性的,因为波束搜索算法仅扩展B每个级别的节点; 它不会像许多具有指数时间复杂性的搜索算法那样在每个级别上进行更广泛的分支。该算法执行的速度是其最大优势之一。

空间复杂性

Beam Search的内存消耗是其最理想的特性。因为该算法仅在搜索树中的每个级别存储B个节点,所以最坏情况的空间复杂度为 O(Bm),其中B是波束宽度,m是搜索树中任何路径的最大深度。这种线性内存消耗允许Beam Search深入探测大型搜索空间,并可能找到其他算法无法达到的解决方案。

集束搜索算法的伪码:

/ *初始化* /
g = 0;
hash_table = {start};
BEAM = {start};

/ *主循环* /
while(BEAM≠∅){//循环,直到BEAM不包含节点
  SET =∅; //空集

  / *生成SET节点* /
  for(each state in BEAM){
    for(each successor of state){
      if(successor == goal)返回g + 1;
      SET =SET∪{successor}; //添加SET的后继者
    }
  }

  BEAM =∅; //空集
  g = g + 1;

  / *为下一个循环填充BEAM * /
  while((SET≠∅)AND(B> | BEAM |)){// set不为空且BEAM中的节点数小于B
    state =具有最小h值的SET中的后继者;
    SET = SET \ {state}; //从SET中删除状态
    if(state∉hash_table){//状态不在hash_table中
      if(hash_table为full)返回∞;
      hash_table = hash_table∪{state}; //将状态添加到hash_table
      BEAM = BEAM∪{state}; //将状态添加到BEAM
    }
  }
}

//未找到目标,BEAM为空 -  Beam Search未能找到目标
返回∞;

 

具体的代码实现将在下一篇博文展现给大家。

参考文章:http://jhave.org/algorithms/graphs/beamsearch/beamsearch.shtml

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
集束搜索是一种启发式搜索算法,用于在大规模搜索空间中快速找到最优解。它通过保留一定数量的最有希望的候选解,来减少搜索空间。下面是一个用Python实现集束搜索的示例代码: ```python import heapq class BeamSearch: def __init__(self, beam_width): self.beam_width = beam_width self.heap = [] def search(self, start_state, goal_fn, successor_fn, heuristic_fn): # Add the start state to the heap with a priority of 0 heapq.heappush(self.heap, (0, [start_state])) while self.heap: # Pop the state with the lowest priority from the heap priority, path = heapq.heappop(self.heap) current_state = path[-1] # Check if the current state is the goal state if goal_fn(current_state): return path # Generate successor states and add them to the heap successor_states = successor_fn(current_state) for successor_state in successor_states: successor_path = path + [successor_state] successor_priority = priority + heuristic_fn(successor_state) heapq.heappush(self.heap, (successor_priority, successor_path)) # Keep only the top beam_width paths in the heap self.heap = heapq.nsmallest(self.beam_width, self.heap) # If the heap is empty, no solution was found return None ``` 这个实现使用了一个最小堆来存储候选解,每次从堆中取出当前最优路径进行扩展。在每次扩展时,生成后继状态,并计算他们的启发式值,然后将它们加入堆中。最后,保留堆中最优的 beam_width 条路径,并继续迭代,直到找到目标状态或者堆为空。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值