启发式搜索算法进阶
继续来学启发式搜索
多的其实没啥好讲了的,因为概念问题在前一篇博文已经讲的很清楚了。主要就是训练寻找估值函数,多点题目练习能应对不通场景下的启发式搜索。
例题
洛谷上的p2324骑士精神
题目描述
主要就是说有个空格,然后所有马都走日,没有马脚,只能跳到空格里面去,然后问你是否能在15步以内达到。如果可以则输出最短步数,否则输出-1,因为空格只有一个我们不考虑跳马,考虑跳空格。
递归最大深度15层能确定了,但是任意一个状态可以延伸出最少2中最多八种情况。15作为指数时间上还是遭不住,考虑启发式搜索。那么估值函数需要怎么写呢?
估值函数
这里再补充点估值函数的知识。
f(n)=g(n)+h(n)
估值函数一般表达式如上,g(n)为当前状态,h(n)为未来最优状态产生的花费,或者是其它。估值函数为两者和,由于当前状态我们很容易获取,所以算出未来最优状态即可等于获得了估值函数。可能前面讲的有点小问题,但是还是不妨碍的,因为我们平时写也基本是
1 | if(f(n)+value>ans){ |
所以问题不大。
题目分析
在本题中,我们的估值函数应该是算能到达目的状态的最小步数。那么这个怎么去考虑呢,其实可以拿当前状态与目标状态相比较,如果有两个点不符合目标状态,那么它们最优能达成目标状态一定是1,这里的最优指的是所有的这个情况下能达成目的状态的最小值。因为如果两个不符合的点不形成“日”字的关系,那么它们可能就不止需要1步了,但是估值并不是真的去计算真正的实际情况,估值函数需要尽可能的方便计算,这点很重要。
那么如果我们有三个点不一样那情况如何呢?那考虑最好的情况那还得是2步解决。所以我们很容易可以发现,假如当前状态与目标状态有n个点不一样,那么它最少需要n-1步来完成。
所以我们很容易可以写出估值函数
1 | int f(){ |
当估值函数返回-1的时候说明当前已经符合目标状态了,那么这个将作为搜索终止条件,并更新最优解。
剩下的就是终归中距的dfs了。
标程
1 |
|
好像不开氧气优化会被卡掉,我只能%氧气优化了,因为我实在不知道咋优化了。