AI中的搜索主要分为两大类:启发式搜索和对抗搜索
搜索分为盲目式搜索和启发式搜索
dfs和bfs是盲目式搜索,而A*和IDA*式启发式搜索。
原因式A*和IDA*式有目的的朝着目标状态搜索,排序了很多没必要的搜索路径。
其精髓就是乐观估价函数f^(n)=g^(n)+h^(n):
启发式搜索 Heuristically Search
启发式搜索,也叫有信息搜索(Informed Search)。它是利用问题拥有的启发信息来引导搜索,达到减少搜索范围、降低问题复杂度的目的
启发式搜索就是在当前搜索结点往下选择下一步结点时,可以通过一个启发函数来进行选择,选择代价最少的结点作为下一步搜索结点而跳转其上(遇到有一个以上代价最少的结点,不妨选距离当前搜索点最近一次展开的搜索点进行下一步搜索)。
何为盲目?何为启发?
举个例子,加入你在学校操场,老师叫你去国旗那集合,你会怎么走?
假设你是瞎子,你看不到周围,那如果你运气差,那你可能需要把整个操场走完才能找到国旗。这便是盲目式搜索,即使知道目标地点,你可能也要走完整个地图。
假设你眼睛没问题,你看得到国旗,那我们只需要向着国旗的方向走就行了,我们不会傻到往国旗相反反向走,那没有意义。
这种有目的的走法,便被称为启发式的。
我们知道的BFS和DFS,便是盲目式搜索,而A*跟IDA*,便是启发式搜索。
一个经过仔细设计的启发函数,往往在很快的时间内就可得到一个搜索问题的最优解,关键就是如何设计这个启发函数。
最佳优先搜索(Best-First Search)
就是greedy search,也叫贪婪最佳优先搜索(Greedy Best-First Search)
最佳优先搜索(Best First Search),是一种启发式搜索算法(Heuristic Algorithm),我们也可以将它看做广度优先搜索算法的一种改进;最佳优先搜索算法在广度优先搜索的基础上,用启发估价函数对将要被遍历到的点进行估价,然后选择代价小的进行遍历,直到找到目标节点或者遍历完所有点,算法结束。
BFS算法不能保证找到的路径是一条最短路径,但是其计算过程相对于Dijkstra算法会快很多。
最佳优先搜索算法很类似dijkstra算法,只不过它的队列是一个优先队列,比如此时队列中有(6,2),(5,10),(3,1)
(6,2)就表示起始点到6号点的距离为2
按Dijkstra来说是按照进队的顺序一次出,就是(6,2),(5,10),(3,1)顺序
而最佳优先搜索是(3,1) (6,2) (5,10),先出到起始点距离最小的点
在贪婪最佳优先搜索算法里面,评价函数f(n) 等于启发函数h(n)
f(n) = h(n)
A*搜索算法
A*算法属于启发式搜索
A*是AI算法应用最广泛的算法之一,经常用到游戏里寻找最短路的算法里
A*算法与最佳优先搜索算法相比优化了评价函数f(n)
A*算法最为核心的部分,就在于它的一个估值函数的设计上:
f(n)=g(n)+h(n)其中f(n)是每个可能试探点的估值,它有两部分组成:
①g(n),它表示从起始搜索点到当前点的代价(通常用某结点在搜索树中的深度来表示)②h(n),它表示启发式搜索中最为重要的一部分,即当前结点到目标结点的估值。
h(n)设计的好坏,直接影响着具有此种启发式函数的启发式算法的是否能称为A*算法。
A*算法可以看作是BFS算法的升级版。A*算法跟BFS一样,扩展周围的几个点,但是A*会评估这几个点哪个到终点比较近,然后选择近的走,然后继续评估,又选择近的走,直到走到终点
迭代加深搜索
在DFS的搜索中加一个搜索深度的限制,搜索层数超过这个限制就返回
由于深度d是慢慢递增的,这样的得出了的答案毫无疑问是最小深度(即少步数),但是缺点很明显,重复遍历解答树上层多次,造成巨大浪费
在紫书上还有讲
IDA*算法
IDA*算法属于启发式搜索
IDA*是在迭代加深搜索的基础上,多了评估函数(或者说剪枝),每次预估如果这条路如果继续下去也无法到达终点,则放弃这条路(剪枝的一种,即最优性剪枝)。IDA*原理实现起来简单,非常方便,但难的地方是评估函数的编写,足够好的评估函数可以避免走更多的不归路,如果评估函数太差或者没有评估函数,那会退化到迭代加深搜索那种浪费程度
IDA*可以看作是改进DFS来的