A*与IDA*

1. f = g + h f=g+h f=g+h

A* 与 IDA* 都是用来搜索路径的算法。它们分别是单纯的BFS和DFS的优化,其核心都在于对从现状态到目标状态的步数的估计。即下面这个等式:
f ′ = g ′ + h ′ \qquad \qquad \qquad \qquad f'=g'+h' f=g+h
其中 g ′ g' g为从初始状态到现状态需要的最少步数, h ′ h' h为从现状态到目标状态需要的最少步数。那么根据等式含义, f ′ f' f就是从初始状态到目标状态,一定要经过现状态时的最少步数。

很显然的是, f ′ , g ′ , h ′ f',g',h' f,g,h都太过理想,是我们不知道的。因此,我们用它们的估算的结果代替使用,即下面这个式子:
f = g + h \qquad \qquad \qquad \qquad f=g+h f=g+h
其中 g g g为从初始状态到现状态已经走过了多少步, h h h为从现状态到目标状态最少可能会走多少步。
由定义, g ≥ g ′ , f ≤ f ′ g \ge g',f \le f' ggff。(不好理解的话,仔细读定义体会一下。)

下面举个例子(不要纠结例子的合理性啦w):
f=g+h
图1
如图一所示,深绿色方块是起点,蓝色方块是终点,黑色是不能经过的部分,浅绿色是本次dfs(就当是dfs了)的路线,路线中的等式表示 f = g + h f=g+h f=g+h;两条绿色路线分别表示现状态的 g g g路线和一条 h h h路线,两条橙色路线分别表示现状态的一条 g ′ g' g路线和一条 h ′ h' h路线(之所以说“一条”,是因为路线不唯一)。可以看出,每次只能从本格子前往上下左右四个格子之一。
现状态: g = 9 g=9 g=9 h = 9 h=9 h=9 g ′ = 5 g'=5 g=5 h ′ = 13 h'=13 h=13

例子结束。

那么 f = g + h f=g+h f=g+h这个式子是怎么优化BFS和DFS的呢?请往下看。

2.A*

即优化了的BFS。
(安利一个讲得很好的博客:A*寻路算法。当然也可以只看我的,十分欢迎。)

BFS是一层一层扩展的,也就是我们有目前已经在第i步的所有状态,之后由它们拓展出所有第i+1步的状态。

很容易想到,当前的所有状态是有优劣之分的,也就是有的状态很可能是正解的必经状态,而有的状态则与正解差了十万八千里。如果我们优先拓展最优的状态,那么就会更快地接近目标。而状态优劣的判断标准显然可以是 f f f

BFS通常使用队列实现的。那么这时,我们就可以用优先队列进行优化,以 f f f的大小作为判断标准,优先拓展 f f f小的。

这,就是A*了。

3.IDA*

即优化了的DFS。

普通的DFS“不撞南墙不回头”,不限制的话,很可能沿着一个错误的方向一直递归下去。而IDA*主要有两点升级:

  • 枚举答案的步数。也就是从最小的可能的步数开始往大枚举,直到在这个步数时能从初始状态抵达目标状态。可以简单想一下,每次步数(或者叫深度)加1,那么增加的状态数是相当多的,因此可以忽略前面根本抵达不了终点的步数的耗时。
  • 利用 f = g + h f=g+h f=g+h预判是否可能在规定步数抵达终点。假设我们预先设置的步数为 x x x,可以知道现状态的 f f f,那么如果 f > x f>x f>x,则现状态到不了终点。

这两点优化都很容易理解,也比较好实现,只要在dfs外加一个循环,在dfs中加一个提前return的判断语句即可。

如果要输出具体路径的话,IDA*在适合不过了。(也不一定啊)
最起码回溯时路径就在那里摆着呢啊

这就是IDA*了。

4.总述

从A*和IDA*的原理上,我们可以看出它们的核心就是 f = g + h f=g+h f=g+h g g g是已知的步数,只有 h h h是我们需要思考如何求的。 h h h的计算方法就因题而异了,不过它一定有以下的性质:

  • h h h是从现状态到达目标状态的可能的最小步数,也就是说它不一定是真正的最小步数。真正的最小步数是 h ′ h' h,是存在,但我们很难求出来的。 h ≤ h ′ h \le h' hh h h h越接近 h ′ h' h越好。

正是 h h h让我们有了预判的能力。 h h h函数的定义对一道题有着决定性影响。令 h = 0 h=0 h=0,这就是普通的BFS和DFS了。
h真是一个神奇的字母,你h了吗

5.例题

没有经过细选,只是我遇到的几个例题:
Eight POJ - 1077(这题解法貌似有很多,我用的是IDA*)
The Rotation Game POJ - 2286(据说是IDA*入门题,TM我用BFS做了一天!!!这也是我开始接触IDA*的题)
[SCOI2005]骑士精神

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值