第8章 搜索策略

Puzzle问题

本章以Puzzle问题为例,对搜索策略进行分析

image.png
image.png
image.png

深度优先与广度优先

最坏时间复杂度(可行解在树的右下角)最坏空间复杂度(可行解在树的右下角)
深度优先搜索θ(ωh)(h-1)(ω-1)
广度优先搜索θ(ωh)ωh-1
  1. ω为每个节点的子节点数,h为树的深度
  2. 一般用深度找可行解或可行解在左下角,用广度找最优解或可行解在中间层
  3. 深度使用的数据结构是栈(保存了搜索路径上的节点信息),广度使用的数据结构是队列(只需要保存当前层的所有节点,而不需要保存所有已访问过的节点的状态信息),数据结构决定了二者的最坏空间复杂度

搜索的优化

爬山法

来源:在深度优先搜索过程中,我们经常遇到多个节点可以扩展的情况,首先扩展哪个比较好?
基本思路:爬山策略使用贪心方法确定搜索的方向,是优化的深度优先搜索策略(使用启发式测度来排序节点扩展的顺序)
数据结构:栈

image.png
image.png

Best-First搜索策略

基本思路:结合深度和广度的优点(深度的空间节省、广度的横向比较)
数据结构:堆

image.png
image.png

image.png

分支界限

基本思想:先发现优化解的一个界限,再利用界限缩小解空间, 提高求解的效率

具体步骤

  1. 使用分支来表示问题的解,即确定分支划分的方法
  2. 通过爬山法或Best-First找到解的界限
  3. 进行分支界限搜索,即利用找到的界限剪除不可能产生优化解的分支

技巧

  1. 建立分支的时候选择能能使树变瘦长的分支方法

问题示例

人员安排问题

image.png

必要知识点——拓扑排序

输入:偏序集合(S, ≤)
输出::S的拓朴序列是<s1, s2, …, sn>,满足: 如果si≤sj, 则si排在sj的前面

8a50d668be33a60fd98abbb4735b8ef.jpg

确定划分方法

拓扑算法生成解空间

  1. 问题的解空间是所有拓朴排序的序列集合,每个序列对应一个可能的解
  2. 问题的树表示(即用树表示所有拓朴排序序列)
    image.png
  3. 代价矩阵“减0”操作
    image.png
    image.png
通过爬山法找到解的界限

爬山法得到可行解及上界

  1. image.png
利用找到的界限剪除不可能产生优化解的分支

分支界限得到最优解

  1. image.png
旅行商问题

输入:连通图G=(V, E),每个节点都没有到自身的边,每对节点之间都有一条非负加权边
输出:一条由任意一个节点开始,经过每个节点一次,最后返回开始节点的路径,该路径的代价(即权值之和)最小

确定划分方法
  1. 所有解集合作为树根
  2. 树的划分过程:
    1. 所有包含(i, j)的解集合作为左子树,所有不包含(i, j)的解集合作为右子树((i, j)的选择策略:选择图上边(i, j)使右子树代价下界增加最大)
    2. 计算出左右子树的代价下界
  3. 构造根节点
    1. 处理技巧1:优化代价矩阵
      image.png
      image.png
  4. 划分过程
    1. image.png
    2. image.png
      image.png
通过爬山法找到解的界限
  1. 从代价下界小的一边进行递归分支,直到找到一个解,这个解的代价实际就是优化解的上界α
  2. 递归分支
    1. 做出新的代价矩阵(左子树)
      image.pngimage.png
    2. 做出新的代价矩阵(右子树)
      image.png
      image.png
    3. 做出新的树
      image.png
    4. 爬山策略扩展左子树根
      image.png
利用找到的界限剪除不可能产生优化解的分支
  1. 从未扩展的节点开始继续扩展,如果一个节点的代价下界超过α, 则终止该节点的扩展
  2. 反复递归后得到
    image.png
  3. 通过解“1-5-6-7-3-5-2-1”得到优化解的上界为126,再看未扩展的节点,未扩展的节点中代价下界最小的是128,而128>126,不需要扩展(剪除),得到“1-5-6-7-3-5-2-1”即为最优解

A*算法

  • 分支界限策略是为了剪掉不能达到优化解的分支,其关键是“界限”
  • A*算法的核心是告诉我们在某些情况下, 我们得到的解一定是优化解, 于是算法可以停止
  • A*算法试图尽早地发现优化解
  • A*算法经常使用Best-first策略求解优化问题

正确性证明

  1. 我们先定义一些名词:
    当我们到达点n时,已经付出的代价为g(n),这是我们已经知道的
    然后假设有上帝,告诉我们从点n到终点t的最优解为h*(n)
    但是没有上帝,我们仅仅用n点下一步路径的最短值h(n)估计值h(n)
    设f(n)=g(n)+h(n)、f
    (n)=g(n)+h*(n),显然f(n)≤f*(n)
    f(n)是我们实际计算得到,并加入堆中进行Best-First比较的
    每次会有很多个可扩展的点(可扩展的点都称为点n),A*算法就是将这些可扩展的点加入堆中比较,找到最小的f(n’),然后再对n’进行扩展,扩展之后将点n’出堆,并将扩展后多出的可扩展的点再加入堆中进行比较,如此递归扩展,直到
    开始**对终点t进行扩展为止(不是扩展到终点t,而是开始对终点t进行扩展。扩展到终点t是指将t加入堆,开始对终点t进行扩展是指此时堆中 f(t)最小),这时f(t)=g(t)即为最优解
  2. 然后我们来证明正确性,即证通过不断对较小的f(n)对应的点n进行扩展,扩展到终点t后得到的g(t)为最优解
    1. f(t)≤f(n),n是任意可拓展的点,t是终点
    2. 进而因为f(n)≤f*(n),有f(t)≤f*(n)
    3. 当前所有可扩展的点n里面一定有一个是最优解,设它为s,那么根据c.有f(t)≤f*(s)
    4. 由于t是目标节点,进而h(t)=0,所以有f(t)=g(t)+h(t)=g(t)≤f*(s)
    5. f(t)=g(t)为一个可行解,而f*(s)为一个最优解,所以f(t)=g(t)≥f*(s),再由d.得f(t)=g(t)=f*(s),即g(t)为最优解

例子

  1. image.png
  2. image.png
  3. image.png
  4. image.png
  5. image.png
  6. image.png
  7. image.png
  8. image.png

如果你喜欢这篇文章,别忘了点点赞和收藏🥰
更多内容及实时更新请访问笔者语雀知识库,本篇内容可在第8章 搜索策略查看(打开文档后点击右上角演示可获得更好的阅读效果哦~)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你才是猪头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值