A*算法
作为路径搜索的一种典型算法,是在广度优先搜索(BFS)的基础上扩展的。
从A点到B点,BFS算法的思路属于路径穷举了:从A点开始,遍历相邻节点放入队列尾部,然后从队头拿出一个节点,搜寻其邻域放入队列尾部,直到找到B点
A*算法是在BFS的基础上,加入一个启发值,这个启发值又被称为代价函数:f(n)=g(n)+h(n)
代价函数有两个部分构成,g是当前位置n的代价值,h是到目标的预估代价值,当然这个预估代价很可能并不准,比如从绿色到红色两个点中间有一个蓝色障碍,而我们使用的预估代价可能就是假设没有障碍时的曼哈顿距离
如果只有预估代价,并不能找到A到B的最短距离,A到B的距离= A到n的距离 + B到n的距离,其中A到n的是已经探索过的路径,其距离是实际观察值,我们对于实际观测值必须需要做记录,而B到n的则是属于模型预测值,不一定真实,也不必做记录(记录的话只是为了加速计算)。我们每次都从队列中取出代价f(n)最小的点进行邻域扩展,将邻域点放入队列尾部,需要注意的是f(n)最小,不是从实际观测g(n)最小中找预估代价h(n)最小。
强化学习
这物体如果用q-learning来解决,其实问题也是类似,不过强化学习中对各个部分进行了严格的划分,并且强调了个体的概念
比如说假象有一个人在位置A上,通过按w键可以上移一格到达A+1的位置。在强化学习中,位置被抽象为了状态s,按w键被抽象为动作a,个体只有通过产生动作才能使得状态发生转移,比如通过动作w使得状态从A转为A+1。
在强化学习中,使用奖励r的概念替换了代价的概念,从字面意思我们也能知道他们其实是刚好相反的概念,正如一个是乐观主义一个是悲观主义。但这并不妨碍对本质问题的处理,代价最小化的等价问题也就是奖励最大化。
从A到B点,只有到达B点的时候我们才给予一个奖励。刚开始在A点的时候,我们找到当前状态下预估奖励Q(s,a)最大的动作,由于刚开始预估并不准确(也就是奖励最大的动作未必是离B更近的选择),所有相当于瞎走,直到在B-1的位置上,瞎猫碰到死耗子,找到B,被授予的激励r,B-1这个位置也随之受到B的传递,预估奖励更新为k*r,k是传递系数或者叫折扣系数,在[0,1]范围内。这样走很多次以后,A+1,A+2,…B-2,B-1的位置上,预估奖励会逐渐递增,比如: k n ∗ r k^n*r kn∗r, k n − 1 ∗ r k^{n-1}*r kn−1∗r,…, k ∗ r k*r k∗r。
我们可以看到,强化学习使用奖励以及奖励传递的概念,和路径搜索中的代价的区别,它默认了每个动作的代价是相同的,也默认了在不同状态下相同动作具有相同的代价
这里我们可以介绍一下奖励传递,遵循贝尔曼方程
Q ( s , a ) = ( 1 − α ) Q ( s , a ) + α [ r + k × Q ( s ′ , a ) ] Q(s,a) = (1- \alpha)Q(s,a) + \alpha[r + k\times Q(s',a)] Q(s,a)=(1−α)Q(s,a)+α[r+k×Q(s′,a)]
当然,只有到达终点才会获得r,其余位置获取的都是Q(s’,a),这是一个预估奖励,通常是遍历s’状态下的所有a,取Q最大值对应的a这时候我们会有疑问,凭什么qlearning直接用预估奖励就可以找到最短路径,而A* 需要使用当前状态的代价?这是因为A* 只搜索一次就能找到最短路径,而QLearning需要训练很多次,直到最短路径和预估最大奖励的路径重合,强化学习并不能一次就找到,但其优势在于可以学习到。
D*算法
当然,对于有个体概念的搜索,实际上用D* 算法来做比较更为恰当。D* 算法第一步便是:采用Dijkstra进行搜索,得到x到终点预估距离h(x)。
Dijkstra是从一个顶点到其余各顶点的最短路径算法,每个顶点有一个k值标识到起始顶点(D*中的终点)的距离(即k=h),其父节点为邻域中k值最小的那个。
然后在当前位置的邻域上找到h(x)最小的位置y,作为下一个移动的位置。
小结
从形式上我们可以感受到,使用奖励的概念就像在目标节点处施加激励,使得激励沿着路径传递,离目标的路径越短,则激励所散发的清香越浓厚,所以只要沿着激励最大的路径前进便能得到最短路径,更像是纵向的考虑。而使用代价的概念考虑,则是从所有目标路径中找到一个代价最小的,更像是货比三家的横向考虑。