A ∗ A^*A∗算法,又叫做A − s t a r A-starA−star算法,是一种静态路网中求解最短路径最有效的直接搜索方法。
思想
我们首先来回忆一下B F S BFSBFS算法,我们的B F S BFSBFS算法每次都是从堆顶取出当前代价最小的状态进行扩展。那最先扩展到的就是最优的。
但我们B F S BFSBFS算法这种贪心思想是不完善的:我们虽然当前的代价小,但不能保证后来的代价也小(正所谓目光短浅)。这样就会使搜索量增大。
我们的A ∗ A^*A∗算法就是加上一个估价函数:不断从堆中取出“当前代价+预估代价”最小的进行扩展。
但我们的预估函数有一个基本准则。
基本准则
设从当前状态到目标状态所估计的代价值为f ff。
设未来的搜索中,实际求出的从当前状态到目标状态的实际最小代价为g gg。
则对于任意的状态:f ⩽ g f\leqslant gf⩽g
否则我们的搜索会出现很大的问题:最优解路径上的状态会被错误的估大,然后被压在堆底出不来。
但大家可能会有疑问了:那我们的非最优解路径不就可能先被扩展吗?
这个确实可能发生。
我们如果估值不准确,非最优解路径上的状态s ss就会先被扩展,但是随着“当前代价”的不断累加,在目标状态被取出之前的某个时候:
1.根据s ss并非最优,s ss的“当前代价”就会大于从起始状态到目标状态的最小代价。
2.对于最优解搜索路径上的状态t tt,因为f ( t ) ⩽ g ( t ) f(t)\leqslant g(t)f(t)⩽g(t),所以t tt的“当前代价”加上f ( t ) f(t)f(t)一定小于等于t tt的“当前代价”加上g ( t ) g(t)g(t)。
所以,可知道**t tt的当前代价加上f ( t ) f(t)f(t)小于s ss的当前代价**。因此,t tt就会被从堆中取出来进行扩展。
我们的估价函数越准确,我们的速度就会越快。 所以,设计一个优秀的估价函数十分重要。
I D A ∗ IDA^*IDA∗算法
也就是迭代加深的A ∗ A^*A∗算法。
所谓迭代加深就是每次限制搜索深度, 这样可以在整个搜索树深度很大而答案深度又很小的情况下大大提高效率。
使k kk从1 11开始不断加深枚举, 作为最大步数进行迭代加深搜索判断,而对于不用移动的情况可以一开始直接特判。