人工智能第四章

一. 无信息搜索(uniformed search strategies)

无信息搜索的含义是搜索时,除了状态外,无额外信息来帮助你搜索. 从边缘节点中挑选某个节点进行扩展,直到找到我们的目标节点(含目标状态),如何挑选节点进行扩展这就是我们今天要讨论的内容.

首先先介绍下无信息搜索有哪些查询策略:
(1)广搜(breadth-first search)
(2)统一代价搜索(uniform-cost search)
(3)深搜(Depth-limited search)
(4) 迭代深搜(Iterative deepening search)
(5)双向查询(Bidirectional search)

评估查询策略有这4个标准:
(1) 完备性(completeness): 是否总能找到一个存在的解
(2)优解: 是否是最优解,例如每个节点是个城市,当然了节点还能存其他信息,例如它的父节点,子节点,深度等.节点之间相连接的边是代价,例如油钱,从城市A到城市B花多少油钱.最优解就是花最少的油钱到目的地城市.
(3)时间复杂度:花多久能找到这个解
(4)空间复杂度:需要多少内存,你也可以理解这整个数据结构例如树,图,毕竟这些你写代码的时候肯定会存在一个变量里,例如你的边缘节点们肯定会存在一个变量里这个变量的数据结构可能是队列,可能是栈,甚至是个列表.然后取个节点来开点. 如何取哪些点来开这就是你的查询策略.

开始讲查询策略前,我们在来定义下一些变量.
在这里插入图片描述

b:最大分叉数,例如上图,最大分叉数是2.
d: 最浅深度,d=2,就是上图哪个实心黑色节点处在最浅深度.
m: 最大深度,m=3

最后在解释搜索策略之前,和大家阐述策略代码里的三个核心变量.

(1)node: node这就是个变量名字你想叫啥都行,没别的意思,node这个变量就是存储我们的节点,这个节点存着我们的状态(state),代价(cost),深度(deep),子节点,父节点,等调用时,node.cost,node.state…
(2)frontier: 这是个数据结构,你可以是列表,队列,甚至字典也行,反正你怎么舒服怎么来,名字叫做frontier,用来存储边缘节点,去一个边缘节点用来开点,开点的意思就是我们看过这个节点了,或者经过这个节点了,那么这个节点又会有自己的边缘节点,再存储再这个数据结构中.至于选哪个节点开,这就是我们的查询策略.
(3)explored: 就是开点,经过的点.都存储在这个数据结构里,你用列表也行,怎么舒服怎么来.

二. 广搜(bread first search)

策略: 展开最浅深度没有展开的节点. 当然了,写程序的时候,我们会把边缘节点都存在某个数据结构里例如列表,那么我们展开边缘节点的策略就是FIFO,先到先服务,打开该边缘节点,那么打开这个边缘节点的边缘节点要放在列表中最后面,对吧.

我们可以来举下图例子.广搜就是把每一层节点开完,在往下一个深度开点.
在这里插入图片描述

完备性: 没错,广搜具有完备性. 当然了,前提是b和d要有穷.

时间复杂度: 1 + b + b 2 + b 3 + . . . + b d = O ( b d + 1 ) = O ( b d ) 1+b+b^2+b^3+...+b^d=O(b^{d+1})=O(b^d) 1+b+b2+b3+...+bd=O(bd+1)=O(bd)
很简单,就是把看分叉数,就是每个节点广度开点. 当然了,我们要开最浅深度所以用d.本质就是再算多少个节点,指数是深度,例如二叉树,
第2深度节点数为 ,第3深度节点数为 ,最后全加一起.

空间复杂度:
O ( b d + 1 ) O(b^{d+1}) O(bd+1)与时间复杂度一样,本质就是再算多少个节点.

优解: 当代价是1时,它是最优解.也就是节点和节点之间的边代价是1时,才是最优解,例如油钱都是1块钱,如果油钱代价不一样,有的是1快有的是3块,那找到的肯定不是最优解,因为我们开点策略仅仅是展开最浅深度没有展开的节点.

宽度查询的逻辑(图片搜索)
在这里插入图片描述
我们来看看上述伪代码.先将初始节点放入变量node里. 然后检查这个节点是否是目标节点, 即proble.FOAL-TEST(node.STATE). 如果是则return解,若不是接着运行下一条命令. 现在我们将这个初始点放入我们的frontier里,准备取出开它,按照先进先出,它开后会有它自己的边缘点,再放入frontier里. 开过的点我们放入explored里,但初始它是空的.你用列表也行,队列也行(推荐队列).

之后就是循环loop do,开先进的边缘点,记录代价cost,记录行为action,它自己的边缘点再放入frontier里,放到最后边.开过的点放入叫explored的数据结构里.

宽度查询(简单二叉树搜索)
在这里插入图片描述
很简单,就是横着找.

缺点:
随着深度增加,指数级增长节点个数,内存需求和执行时间都太大了,宽度优先搜索不能解决指数复杂性问题.仅仅cost 均相同时,才能找到最优解,当cost不相同,仅仅找到目标点而已.

三. 统一代价查询(Uniform cost search)

我们来定义下,g(n):意味着到某个节点n的总代价即到第n点一路的代价. 统一代价搜索: 扩展的是路径消耗g(n)最小的节点n,用优先队列来实现,对解的路径步数不关心,只关心路径总代价。即使找到目标节点也不会结束,而是再检查新路径是不是要比老路径
好,确实好,则丢弃老路径。

策略:展开代价(cost)最小的没有展开的节点.

举个例子:
在这里插入图片描述
假如我们初始点Sibiu,目标点是Bucharest. 那我们开始用统一代价来走走, 先看g(Rimnicu)=80和g(Fagara)=99,那么选Rimnicu, 然后再看g(Pit)=80+97,g(Fagara)=99, 那选Fagara, g(Buch)=99+211=310, 那么走Rim那 g(Buch)=80+97+101=270, 总之,用新路的一路代价和旧路的一路代价进行比对.

完备性: 是的, 但条件是代价是正数. ϵ \epsilon ϵ>0. ϵ \epsilon ϵ为最少的代价

时间复杂度: 我们来定义下 C ∗ C^* C为解的最优代价(一路上的总代价).那么时间复杂度为 O ( b 1 + C ∗ ϵ ) O(b^{1+\frac{C^*}{\epsilon}}) O(b1+ϵC), 其中 C ∗ ϵ \frac{C^*}{\epsilon} ϵC为最多需要多少步才能到达目标点,相当于d。

全代价搜索代码
在这里插入图片描述
我们来看看上述代码,首先给初始节点,例如上述例子假如我们初始点Sibiu,那么node这个就是关于Sibiu的节点. frontier这个变量是个优先队列,代价最小的节点优先,例如Sibiu它有俩城市Fagaras和Rimnicu,这俩节点. 那么frontier=[Rimnicu,Fagras], 先开Rimnicu,因为Rimnicu的代价才80,Fagras代价要99. 那么已开点explored=[Sibiu, Fagras], frontier=[Fagaras,Pitesti],为啥Pitesti在Fagaras后面,因为Pitesti的代价是80+97=177,比99代价的Fagras要小.所以下一步我们会开Fagras,那么explored=[Sibiu, Fagras,Pitesti]. …以此类推开点.

四. 深搜(Uniform cost search)

策略:开深度最深的未开节点. 它的frontier是最后进的节点先开.
在这里插入图片描述
我们试试深搜,深搜我们会发现,它好像不考虑代价. 还是这仨变量node,frontier,explored. 我们从Sibilu要到Bucharest. 那么当我们开Sibilu这个节点,我们要看它的状态,node.state,我们发现是Sibilu,不是我们的目标节点. 那它的边缘节点即子节点是Fagaras和Rimunice,那么frontier=[Fagaras,Rimunice],因为是最后进的节点先开,那么,我们会先打开Rimunice这个节点,explored=[Sibilu,Rimunice],那么它的边缘节点,有Pitesti,存到frontier里,那么frontier=[Fagaras,Pitesti], 所以,我们最后看到,深搜是一口气一路搜下去,直到找到目标点.我们会发现深搜没有考虑代价,所以它不能找到最优解.

完备性: 对于树搜索它会有循环,反复见到重复的节点(详见第三章图与树的区别),而且还有深度无穷的情况,所以树搜索时,深搜不具有完备性.换句话说,如果是深度查询图搜索(graph search),避免了重复状态和冗余的路径,is complete是完备的(即能找到解),因为它会打开所有节点 如果是深度查询树搜索(tree search),它是不完备的,因为会有loop循环,A→B→A→B.
虽然在树图中深度查询可以改进,使其避免重复节点,但避免不了冗余路径.

时间复杂度: O ( b m ) O(b^m) O(bm),当 m m m远大于 d d d时,需要时间很多.如果解很多,因为毕竟条条大路通罗马,深搜又不考虑代价,所以有时候表现情况比广搜要好.

空间复杂度: O ( b m ) O(bm) O(bm) 线性空间.

优解: 不能,深搜没考虑代价.

对于图像查询,深度搜索一无事处,一点用没有对比广度查询,但是在树查询中,深度搜索空间复杂度是O(bm),只需要bm个节点.比广搜空间复杂度要小很多.

深搜会得到很多个解,但广搜会得到一个很短的解,啥意思,我们的解不是说找到目标就够了,我们还要返回它的路径,也就是说深搜能找到路径最短的解.

深度查询的变种backtracking search 回溯查询, 在CSP满足问题里,我们会见到的. 先告诉你结论,通过回溯查询,空间复杂度才仅仅O(m).也就是说只要做O(m)个操作.因为回溯查询,每次仅仅开一个后继者,所以没有b个,只有1个所以O(1*m)不是树查询的O(bm).

深度查询(基于树查询)

在这里插入图片描述

五. 有限深搜(Depth-limited search)

有限深度查询(DLS).当状态空间无穷(其实是问题太深太复杂),那么需要节制深度.

时间复杂度: O ( b l ) O(b^l) O(bl)
空间复杂度: O ( b l ) O(bl) O(bl)

有限深度查询(基于树查询)
在这里插入图片描述
这里的limit就是限制深度.它在不断的减少limit,当然了,你可以自己设置个深度界限,如果达到就停.代码里的cutoff相当于flag,就是不要再往下搜的意思.

六. 迭代深搜(Iterative deepening search, IDS)

迭代深搜时结合了广度查询优点(最短解)和深度查询的优点(空间复杂度小).逐渐增加深度,利用广搜.

完备性: 是的

时间复杂度:就是算多少个节点,IDS的时间复杂度和广度查询的时间复杂度一样 O ( b d ) O(b^d ) O(bd).

空间复杂度:就是存储了多少个节点,IDS的空间复杂度和深度查询的空间复杂度近似 O ( b d ) O(bd) O(bd).

优解:当代价均为1时,是最优解.
在这里插入图片描述
黑色点是开点. 绿色点是边缘点.

下面则是迭代深搜的伪代码

在这里插入图片描述

cutoff:叫IDS增加limit的上限

六. 双向查询(Bidirectional search)

策略:从初始位置出查询发,于此同时从终点位置出发查询,两个查询在中间碰头. 所以两个查询的时间复杂度相加,空间复杂度相加.深度为一半!

如果用广度查询进行双向查询:
时间复杂度: O ( b d / 2 ) + O ( b d / 2 ) = O ( b d / 2 ) O( b^{d/2})+ O(b^{d/2} )= O( b^{d/2}) O(bd/2)+O(bd/2)=O(bd/2)
空间复杂度: O ( b d / 2 ) + O ( b d / 2 ) = O ( b d / 2 ) O( b^{d/2})+ O(b^{d/2} )= O( b^{d/2}) O(bd/2)+O(bd/2)=O(bd/2)

难点:
backward search,从终点位置查询,要找到一个对于终点位置查询来说x是前任节点,对于
forwardsearch,起点查询来说x是继任点.也就是这个中间点很难办.
优点:
空间复杂度和时间复杂度为原来一半.

七. 结语

下章为大家解释有信息查询。
若有谬误,请指出,感谢.

  • 1
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值