AI与游戏——吃豆人(5)树搜索算法(上)

查找搜索类算法可以说是被提及最多的人工智能方法,绝大多数AI问题都可以被看成一个搜索查找问题,也就是找到最好的方案,路径,模型等。搜索算法因此也最常在一些AI算法的核心部分看到,很多AI的书籍也都是从搜索算法开始的。

下面讲的查找算法是树搜索算法,或者说去建立一个搜索树,根节点表示开始搜索的状态,分支代表动作,结点代表状态。因为对于一个状态往往可以执行多种动作,而每个动作又可以进入一个新的状态。另外搜索树跟之前的行为树是大不一样的,搜索树的各个分支是没有先后顺序的,行为树则是事先安排好顺序,属于硬编码范围。树搜索算法主要有以下几种。

盲目搜索(Uninformed Search)
所谓的盲目搜索就是没有目标信息的最单纯的搜索,这在数据结构中也都学过,有深度优先搜索,广度优先搜索,这都并不属于AI的范畴。这种搜索方法在游戏中一般效率很低,但是在很多先进的算法中,盲目搜索也是组成算法的一部分。盲目搜索用于吃豆人这种游戏都会太大也太复杂了,这里也就不再细说了。

最优优先搜索(Best-first Search)
在BFS中,结点的扩展则依据一些关于目标的先验知识。通常,距离目标比较近的结点会优先展开。最知名的BFS算法是A* 算法。A* 算法最常用于游戏中的寻路(星际争霸,魔兽争霸,起源等游戏都使用了A* 算法),之前也有一篇将A* 算法用于吃豆人寻路的。A* 算法如何寻路这里不说了,网上有很多帖子大家可以自行查阅。

这里要说的是A* 算法其实还可以用来搜索游戏状态,也就是说,BFS可以用于拟定计划而不只是寻路。不同之处在于这里考虑的是全局状态的变化(而不是只考虑其中一个单位的状态改变)。有事运用A* 可以有惊人的效果,如2009年马里奥智能竞赛上的冠军就是使用的A* 算法来使马里奥到达最右方的终点。如下图所示。

AI与游戏——吃豆人(5)树搜索算法(上)

感兴趣大家可以搜索一下相关的论文,这里先讨论一下BFS如何用在吃豆人上。首先,我们要先有个表示全局情况优劣的方法,然后使用A* 算法判断那种操作会使全局的情况对pacman最有利(也就是最优),也就是每一步都考虑最优的情况。这种思想也有点类似贪心算法,问题在于如何评价全局优劣呢。最直接也最费时的方法,就是用吃豆人与魔鬼和豆子之间的距离来度量。除了对全局状态的表达,A* 还需要一个代价函数来驱动搜索。例如,一个代价函数往往是奖励那些可以靠近豆子的移动,同时惩罚那些靠近魔鬼的移动。详细一点说就是,如果向上可以靠近2个豆子,向左靠近1个豆子,向右靠近魔鬼,那么可以给定f(up)=2, f(left)=1, f(down)=-1,这样在查找时,只用搜索f(x)最大的分支就行。

A* 算法的效果如何呢,等用代码实现之后再来讨论吧。