sphinx中用的束搜索(Beam Search Algorithm)算法

来源:互联网 发布:linux 设置语言环境 编辑:程序博客网 时间:2024/05/16 07:35

            最近一直在看spinx中的连续语音识别算法,即束搜索算法

       束搜索算法是广度优先搜索算法(Breadth-First Search)的一种改进,它是一种节省内存的广度优先搜索算法,此算法包含一个启发函数h和一个给定的束宽度B。用启发函数h估计从给定节点到达目标节点的消费,用束宽度B,指定在每一级的Breadth-First Search中存储的节点数。

        Breadth-First Search在每一级搜索中把所有的边界节点(连接到关闭节点)存入内存,然而束搜索算法只存储启发值最好的B个节点。这个思想就是启发函数允许算法选择引导它到达目标节点的节点,束宽度只让算法存储重要的节点到内存,避免找到目标之前耗尽内存。

      

       用BEAM存储要在下次循环中扩展的节点,相当于Breadth-First中的open list,用hash table存储已经访问过的节点,相似于Breadth-First中的closed list。

       初始化的时候,把初始节点添加到BEAM和hash table中,然后在每一次的主循环当中,算法把所有连接BEAM中节点的节点添加到它的后继节点集SET中,然后从SET集中选出启发值最好的B个节点,添加到BEAM和hash table中。这里要注意,如果一个节点之前已经出现在hash table中,则不会再把它添加到BEAM中,因为到这个节点的一个更短的路径已经找到了,无需再寻找。这个过程一致持续到找到目标节点,hash table已满(说明可利用的内存耗尽),或者主循环完成之后BEAM为空。

       下面是算法的伪代码,变量g用于跟踪搜索的深度,表示到达一个节点的消费。

            

/* 初始化 */

g = 0;

hash_table = { start };    //添加初始节点

BEAM = { start };

 

/* 主循环*/

while(BEAM ≠){                             // 循环直到BEAM为空

  SET =;                                   // 初始化SET集合

 

  /* 产生SET中的节点*/

  for(BEAM中的每一个状态){

    for(状态的每一个后继){

      if(successor == goal) return g + 1;  

      SET = SET { successor };             // 把每一个后继添加到SET中

    }

  }

 

  BEAM =;                                 // 把BEAM中每个状态的后继都添加到SET集中之后,清空BEAM,准备下一次循环

  g = g + 1;

 

  /* 从SET集中选出启发值最好的B个节点,加入到BEAM和hash table中*/

  while((SET ≠) AND (B > |BEAM|)){         // SET不为空且BEAM中节点的数量小于

    state = SET集中有最小h值的后继;

    SET = SET \ { state };                   // 从SET中删除此state

    if(state hash_table){    // hash_table中没有此state,则把它加入,如果已有,则不用在hash_table和BEAM中重新添加

      if(hash_table is full) return ∞;

      hash_table = hash_table { state };   // 把此state加入到hash_table

      BEAM = BEAM { state };               // 把此state加入到BEAM

    }

  }      //继续下一次循环

}

 

// 如果目标节点没有找到,并且BEAM为空,则搜索失败

return ∞;

 

至此,算法结束,今天有事,先写到这里,有时间了再补充,希望对大家有用。

 

原创粉丝点击