A*启发式搜索

http://www.jiong3.cn/blog/article.asp?id=230

 

OIProject恢复更新。争取达到一天一篇的速度吧。明天预计发出凸包相关知识。

在平时的做题过程中对于一部分搜索题,我们总能看到“这道题用启发做嘛……这样快很多的!”之类的话语。启发式搜索似乎总是一种比广搜、深搜快很多的搜索方法。事实上,在下面我们可以看到,这种方法其实跟普通搜索的本质是一样的,不同之处在于搜索的方向的不同。
我们先来看一道经典的例题:
桐桐有一款时尚、潮流的手机,里面有一款很好玩的游戏,我们暂且称之为“拼图”游戏。
实际上,这个游戏一般可归纳成以下样式:
 
 
 
 
 
 
 
 
 
其中这些格子的长宽都是可变的,不过它们一定都是正方形。
格子里通常都会随机的放一些被切开的图片,我们以编号来表示,便得到了:
1
2
3
4
 
5
6
7
8
然后,手机一般会把原来的图片也给你,像:
1
2
3
4
 
7
6
8
5
当然,如果要赢得这个游戏,就必须通过移动这些被切开的图片使得它们跟手机上的原始图象是一样的。
而移动的规则是,任何一个与格子里的空格相邻(上、下、左、右)的格子都可以移动到空格的位置,而空格将会被移动到“占据”了它的位置的格子的位置上,也就是一次交换。
现在桐桐为了解开一个游戏里的最终关卡而日夜苦思(包括上课的时候),你能帮助他吗?
(题目来源:桐桐的手机游戏,Dai,经典问题改编)
首先由于方便,我们假设这个正方形是3*3的。按照普通的搜索方法,显然我们只能使用广搜,并且状态数目颇为巨大,时间效率比较低下。那么,是不是有什么更好的方法呢?
答案是肯定的。我们可以采用双向广度优先搜索(BI-BFS),从开始状态和终结状态一起扩展结点,并且先扩展较少的一边,相遇的时候即是最优解。理论上来说,这种方法比广搜少扩展一半的结点,时间效率提高一倍。但是,这种方法仍然不是解决这个问题的最佳方法。
下面我们将要说到一个更优的方法:A*启发式搜索。首先我们先想一想,假如我们自己玩这个游戏的话,我们会采用什么策略呢?当然是把离目标点较远的点往上移,这样整个局面显得整体较优。这启发我们,是不是可以让计算机也拥有同样的思想呢?
在A*算法中,估价函数就有着这么一个作用。通俗地说,估价函数就是计算机判断当前局面是不是值得去扩展的函数。设估计函数为g,则每次先扩展的结点必定是g(局面)的最小值。所以上面说的搜索本质一样,原因就在于广搜其实是A*算法的估价函数恒等于0的情况(即不分先后分别扩展)。
回到上面的题目。我们可以使用“相异点”来当作估价函数:一个局面的好坏取决于当前有多少个结点不在其原来的位置上。这个函数比较弱,不过速度的确相当快(我的电脑上30步的解好像是瞬间出解……)。我们还可以采用“每个点离原来的位置的距离”等函数来启发式搜索。方法很多,但是要注意一点:估价函数宁愿对于所有局面都是0,也不要对较优局面搞出比更优局面更大的函数值。这个是A*正确的前提,所以大部分搜索题其实都可以A*——不过你能找到一个完全正确而且效率快的函数么?此乃关键所在。
还有部分搜索题状态空间大得吓人(如推箱子,当然不是我在之前所讲的那个缩水版)的题目,这个时候可以采用时间换空间的方法,即IDA*,相关资料请大家自己在网上查阅。
写完了。感觉啥也没写嘛,囧……
posted @ 2008-12-22 11:18  jesonpeng  阅读(227)  评论(0编辑  收藏  举报