zoukankan      html  css  js  c++  java
  • 【信息学奥赛一本通 提高组】第四章 广搜的优化技巧

     一、基本算法

      如果我们把问题状态空间类比成一个图,那么广度优先搜索就相当于对这个图的广度优先遍历。类似地,我们依然借助一个队列来实现广度优先搜素,起初队列中仅包含起始状态,在广度优先搜索的过程中,我们不断地从队头取出状态,对于该状态面临的所有分支,把沿着每一条分支到达的下一个状态(如果尚未访问过或者能够被更新成更优的解)插入队尾。重复执行上述过程直到队列为空

    二、双端队列BFS

      在最基本的广搜优先搜索中,每次沿着分支的扩展都记为“一步”,我们通过逐层搜索,解决了求起始状态到每个状态的最少步数的问题。这其实等价于在一个边的边权均为1的图上执行广度优先遍历,求出每个点相对于起点的最短距离(层次)。并且我们知道,每个状态在第一次被访问并入队时,计算出的步数即为所求。然而,如果图上的边权不全为1呢?换句话说,如果每次扩展都有各自不同的“代价”,我们想求出起始状态到每个状态的最小代价。

    三、Hash判重

      深度优先搜索的另外一类应用——给出起始和目标状态,以及状态转移的规则,要求找到一条到达目标状态的路径或者方法。这类问题我们称它为路径寻找问题(例如,走迷宫问题),解决这类问题最有效的算法选取合适的方法构造Hash表。

      在路径寻找问题中,经常会遇到走回头路的问题,所以在搜索的过程中都必须做一件事,就是判重。判重是决定程序效率的关键,而如何构造一个优秀的Hash表决定了一切。一个好的Hash函数可以在很大程度上提高程序的整体时间效率和空间效率。

      Hash表的构造方法一般有;

      1、状态压缩——运用2进制来记录状态。

      2、直接取余法——选取一个质数M作为除数。

      3、平方取中法——计算关键值平方,再取中间r位形成一个大小为2r的表

      4、折叠法——把所有字符的ASCII码加起来。

    四、双向宽度搜索

      从正反两个方向进行宽度优先搜索,可以大大减少搜索量,提高搜索速度。

      从起始状态和目标状态两个方向同时进行扩展,如果两颗解答树在某个结点第一次发生重合,即可终止此搜索过程,则该结点所连接的两条路径所拼成的路径就是最优解。

      

    1、双向宽度优先搜索通常有两种搜索方法

      1、两个方向交替扩展

      2、选择结点个数较少的那个方向先扩展。

      方法2只需要略加修改控制结构,每次while循环时值扩展正反两个方向中结点数目较少的那一个,可以使两边的发展速度保持一定的平衡,从而减少总扩展结点的个数,加快搜索速度。

      很明显方法2优于方法1

    2、算法说明

      设置两个队列,Q[2][maxn],分别表示正向和逆向的扩展队列。

      设置两个头指针L[2]分别表示正向和逆向将扩展结点的头指针。

      设置两个尾指针R[2]分别表示正向和逆向将扩展结点的尾指针。

     

  • 相关阅读:
    DEBUG_PRINT
    FFMpeg的解码流程
    解决Cannot open the disk 'E:\my Ubuntu\Ubuntu000001.vmdk' or one of the snapshot disks it depends on.(虚拟机突然断电之后)
    关于mov.c的demuxer
    dts
    fprintf
    H264学习(1)
    如何安装不能识别的驱动错误代码为10
    mplayer先播视频后播音频的解决方法
    团队作业(二) IS191x
  • 原文地址:https://www.cnblogs.com/Osea/p/11214441.html
Copyright © 2011-2022 走看看