载入中
自定义HTML载入中... loading
Heuristic Search 启发式搜索 [转贴 2008-06-05 17:10:51]  删除... 
字体变小 字体变大

Heuristic Search

启发式搜索

译 by 陈雪(QQ:53352894)

必要条件

  • 递归算法

主要概念

启发式搜索的主要目标是使用一个估价函数去判断所有状态的好坏,以提高搜索找到解的效率。

通常,估价函数表示成一个函数或是一个状态,这个函数叫做估价函数例如:

  • 迷宫寻找出路的时候,到出口的欧几里德距离

D=[(xI-xj)^2+(yI-yj)^2]1/2 式中,D是点i和点j之间的距离; xI xj是第i个点的坐标;yI yj是第j个点的坐标。(译者注)

  • 当尝试在一场跳棋比赛中获胜时,能吃掉对手的最多棋子子

设计估价函数

直观地看,估价函数越优秀,搜索就更好(快)。问题是:怎么评价估价函数的好坏呢?

估价函数的好坏,取决于它评估一个状态好坏的能力。例如,迷宫的例子,怎么计算到出口的距离?欧几里德距离也许非常的坏,甚至是非常小的迷宫,它也可能绕很多的路:

一般来说,估价函数越好,搜索就越快。一般来说,搜索时间和估价函数的准确性如下图:


注意!一个似乎很“傻”的估价函数可以大大地提高程序的效率!(如果它非常完美地被使用)

另一个重要概念是“可接受”,一个可接受的估价函数表示对于每个点都不存在“低估”的情况。例如,迷宫的欧几里德距离启发函数是“低估”的,刚才的图例很清楚地说明了这一点。

方法1:启发式剪枝

最简单也是最常用的启发式搜索是利用估价函数来剪枝。假设我们的问题是要求找最小总花费。对于一个可接受的估价函数,当前花费是A,启发函数返回了B,当前子问的最优解是A+B。如果找到的一个解一个花费是CC<A+B,这个状态就不必要搜索了。

这样编写和调试也比较简单(假设一个状态需要长时间而被剪掉……),且可以极大地提高程序效率。它对DFS尤其有效。

方法2:最佳优先搜索

这种方法好比就是贪心算法。

每次不扩展所有子结点,而是按“好坏程度”来扩展。与贪心不同的是,贪心只尝试“最优”路径,但是BFS首先扩展“希望大”的,再扩展“希望小”的,如果结合上述描述,搜索会得到很好的结果。

Idea #3: A* Search

方法3A*

A*法是类似贪心BFS的。

BFS一般扩展最小耗费的点。A*算法在另一方面,扩展最有希望的点(估价函数返回值最优)。

状态被保存在一个优先队列中,按照Cost*价值排列。每一次,程序处理最低优先的点,且把它的孩子按照适当顺序处理。

对于一个可容许的估价函数,第一个找到的状态保证是最优的。

例题

骑士覆盖[传统问题]

一个n*n的棋盘,问最少放多少骑士,使整个棋盘被攻击(骑士所在点不被攻击)

分析:可行的:启发函数总共被攻击的点/8(每个骑士最多攻击8个方各)这可以用上面任何方法实现,经管A*存在一点小问题。

8数码问题[传统问题]


大家熟悉的8数码~~~ 3*3的方格,有一个空格,可以把四个方向数移动到空格里,最后到目标状态~
5 _ 4    5 1 4
6 1 8    6 _ 8 
7 3 2    7 3 2

要求步数最少


1 2 3
4 5 6
7 8 _

启发函数:距离每个数字和最终状态位置。

分析:因为状态很小(一共只有3628800),A*会有很好效果,如果你确定没有点被扩展了两次。

分类: USACO 题解
所属版块: 科技
票数:
什么是“我顶”?
点击数:    评论数:
本文章引用通告地址(TrackBack Ping URL)为:
本文章尚未被引用。
发表评论
大 名:
(不填写则显示为匿名者)
网 址:
(您的网址,可以不填)
标 题:
内 容:
请根据下图中的字符输入验证码:
(您的评论将有可能审核后才能发表)
和讯个人门户 v1.0 | 和讯部落 | 客服中心