搜索_常见搜索算法概述

版权声明:本文为博主原创作品, 转载请注明出处! https://blog.csdn.net/solider98/article/details/84821711

常见搜索算法概述

注意:

     DFS(包括各种DFS变形)和BFS(包括各种BFS变形)均可建立起算法中访问的结点与解空间树中结点的映射关系, 以这种映射关系为基础可以证明这两种所有算法及其变形的诸多重要性质.

     搜索的过程实际是遍历解空间树的过程, 搜索的内容可分为, 搜索所有可行解, 搜索一个可行解, 搜索一个最优的可行解, 搜索所有状态的最优解, 搜索目标状态的最优解.

约定:

     (1)对于解空间树, 设L为解空间树中从根到结点A的路径, A对应状态a且代价最小, 那么L上所有结点均对应某个状态的最小代价

     (2)下面讨论中涉及到的所有结点和状态均指从解空间树根结点可达的结点和状态.

1.深搜(DFS)     

1.1常规DFS

性质:

     (1)还原性(还原现场, 数据修改操作和数据还原操作成对出现)

     (2)子集性(如果当前访问的结点为解空间树中的结点, 那么下次递归或回溯到的结点仍为解空间树中的结点)

     (3)唯一性(程序栈(或称之为递归调用链)的每个状态至多出现一次, 可据此证明程序必在有限时间内终止)

扫描二维码关注公众号,回复: 4730490 查看本文章

     (4)完全覆盖性质(程序将访问所有有必要访问的结点, 比如包含最优解的结点)

     (5)两次递归调用相同,要求当前递归程序栈相同且进行该次递归调用时全局变量的值和函数参数均相同

1.2双向DFS

     主要优点: 减小搜索树规模

1.3 迭代加深DFS

     适用场景: 目标结点位于解空间树较浅层的情况

1.4 IDA*

     特点:基于迭代加深DFS的A*算法 

2.广搜(BFS)    

2.1常规BFS

性质:

     (1)使用先进先出队列, 可用于求解最小步数

     (2)边权值(每次扩展结点的代价)均为1

     (3)队列满足两段性和单调性

2.2用于权值为正数的先进先出队列BFS

性质:

     (1)程序必在有限时间内终止

     证明: 根据解空间树中不同状态的个数为有限个, 每次对结点扩展时新入队列的状态的代价值小于该状态之前更新得到的代价值, 且代价值非负即可证明之.

     (2)算法结束后所有状态的代价值被更新为其最小值

     证明: 假设状态a的代价值未被更新为其最小值, 设L为解空间树中从根到结点A的路径, A对应状态a且使得a的代价最小, 如果a的代价未被更新为其最小值, 则其前驱结点的代价也未被更新为其最小值, 使用数学归纳法可以推出路径L上的所有结点(包括根节点)的代价值均不会被更新为对应代价的最小值, 这显然与路径L上根节点对应状态的代价值被更新为其最小值矛盾, 因此假设不成立, 结论得证.

2.3用于权值为正数的优先队列BFS

性质:

     (1)算法必定在有限时间内终止

     证明: 根据解空间树中不同状态的个数为有限个, 每个状态只在第一次出队列时被扩展, 且每次扩展时加入队列中的新元素(之前未出过队列)个数为有限个即可证明之.

     (2)出队列的元素对应的代价值非递减

     证明: 根据每次扩展时新加入队列的结点(之前未出过队列)的代价均大于被扩展结点即可证明之.

     (3)每个状态至少出(入)队列1次

     证明: 假设状态a在算法执行过程中未进入过队列, 设L为解空间树中从根到结点A的路径, A对应状态a且使得a的代价最小, 如果a未入过队列, 则其前驱结点对应状态b也未入过队列(如果b入队列, 那么在b第一次出队列时必定将a入队列), 使用数学归纳法可以推出路径L上的所有结点(包括根节点)均不会入队列, 这显然与路径L上根节点对应状态入队列矛盾, 因此假设不成立, 结论得证.

     (4)每个状态第一次出队列对应代价值为该状态的最小代价值

     证明: 假设存在某个状态a第一次出队列时对应的代价值并非其最小代价, 设L为解空间树中从根到结点A的路径, A对应状态a且使得a的代价最小, 根据假设, 在a第一次出队列之前, 路径L上A的前驱结点对应的状态b的代价不会被更新为其最小值(如果b对应代价被更新为最小值, 那么在状态b第一次出队列时将把状态a的最小代价加入队列), 使用数学归纳法可以推出路径L上所有结点对应代价均不会被更新为其最小值, 这显然与根结点对应状态的代价被更新为其最小值矛盾矛盾, 故假设不成立, 结论得证.

     (5)如果每个状态不论是否为第一次出队列均会被扩展, 且扩展时不进行任何剪枝, 那么状态a第k次出队列时对应状态a的第k小的代价.

     证明: 根据结论(2)状态a第k次出队列时对应的代价值b不小于状态a的第k小 代 价t, 假设b > t, 那么必有a的某个第c(c <= k)小代价对应的结点p在a第k次出队列之前未入队列, 设从根到p的路径为L, 显然L上所有结点的代价均小于t, 故代价为t的结点出队列之前, 路径L上所有的结点均应该入(出)队列.

2.4双向BFS

性质:

     (1)适用于起始状态的目标状态明确的搜索过程, 可减小解空间树的规模

     (2)每次对当前队首结点进行扩展时检查新加入的结点是否同时存在于起始状态和目标状态已经搜索到的结点集中

     (3)如果某次迭代之前两个队列中的某个为空, 且之前未发现两棵搜索树中的公共结点, 那么必有以起始状态为根的搜索树与以目标状态为根的搜索树的交集(状态的集合)为空

     (4)如果在将一个方向上某个第k层结点(根为第0层)v入队列时发现在v进入过另一个方向上的队列, 且另一个方向已经扩展m层(不包括根), 那么整体解空间树中从起始状态到目标状态的最短路径上边的个数为k + m.

2.5双端队列BFS

性质:

     (1)适用于边权值为0或1(可同时存在)的解空间树

     (2)每次扩展当前队首结点a时, 设a对应代价为f(a), 从a扩展至其子结点b的代价为z(z等于0或1), 如果f(a) + z小于当前b对应状态最后一次更新后的代价值, 那么如果z为0则将b入队头, 如果z为1则将b入队尾.

     (3)算法可能多次更新同一状态的代价, 算法结束后所有状态的代价值被更新为对应状态的最小代价值

2.6 A*

性质:

     (1)带估价函数的优先队列BFS

     (2)目标状态第k次出队列对应的代价为目标状态的第k小代价

     证明: 先证明k = 1时结论成立, 当k = 1时也即目标状态第一次出队列, 假设目标状态第一次出队列时的代价值t大于目标状态的最小代价m, 设结点A对应目标状态的最小代价m, L为从根到A的一条路径, 则路径L上所有结点的实际代价与估价函数值之和小于t, 因此在代价值为t 的结点出队列之前路径L上的所有结点均已经(入)出队列.   这显然与目标状态第一次出队列的代价值为t矛盾. 假设k = i, i >= 1时上述结论成立, 当k = i + 1时, 假设目标状态第i + 1次出队列对应的实际代价值d大于目标状态的第i + 1小代价, 使用类似的方法,设结点e对应目标状态的第i + 1小代价q, 为从根到e的一条路径, 则路径上所有结点在代价值为d的结点出队列之前均已经(入)出队列, 这与假设的目标状态第i + 1次出队列对应的实际代价值d大于q矛盾, 因此假设不成立, 结论得证.

猜你喜欢

转载自blog.csdn.net/solider98/article/details/84821711
今日推荐