搜索_优先队列BFS_A*_算法分析

版权声明:本文为博主原创作品, 转载请注明出处! https://blog.csdn.net/solider98/article/details/84465926

1, 优先队列BFS

    下面是优先队列BFS伪代码:

//在解空间G上以s为源结点执行优先队列BFS
Priority_BFS(G, s) 
	建立初始仅包含结点s且以s的权重(代价)s.w为关键字的最小堆Q
	while Q非空
		结点u = Q.top()
		Q.pop()
		for(解空间G中所有未入过队列的u的邻接结点v) 
			Q.push(v) 

    结论1: 在算法Priority_BFS每次执行第5行时, 如果接下来的第7行if条件成立, 那么Q的堆顶也即结点u对应状态g的代价最小, 注意: 对于任意从源结点s出发, 且终点为e的路径L, 如果e具有其对应状态的最小代价, 那么L上所有结点都具有其对应状态的最小代价.

    证明: 设执行第5时接下来的第7行if条件成立, 满足Q的堆顶结点u对应的状态为a, 代价为w, 设解空间G中从源结点s达到状态a的最小代价为w{}', 并取解空间中任意一个对应状态a且代价为w{}'的结点为b. 且a到b的一条包含节点数最少的路径为R = c_{1}c_{2}...c_{n}(c_{i - 1}c_{i}的前驱结点, c_{1}=s, c_{n}=b).

    设状态a_{0}为所有满足w > w{}'且R包含结点数最少的a类型状态, 也即当a取a_{0}时路径R中除终点a_{0}外的所有结点对应的状态均满足结论1,  那么R中任意结点的代价(Q中对应关键字)均小于w, 根据结点u为状态a第一次出队列Q, 那么必有在u出队列之前, 结点b未入队列Q, 对于R上b的前驱结点c_{n-1}亦不能入队列Q, 因为如果c_{n-1}之前入队列Q, 那么在u出队列之前c_{n-1}已经出队列, 在c_{n-1}出队列对应的第8至9行的循环中将把结点b入队列Q, 则结点b将在结点u之前出队, 与u为所有对应状态a_{0}的结点中第一个出队矛盾, 因此c_{n-1}不应在u出队列之前入队, 使用数学归纳法易推出在路径R上如果c_{j}(j >= 2)不能在u出队之前入队, 那么c_{j - 1}亦不能再u出队之前之前入队, 也即R上所有结点均不能在u出队之前入队, 则R的起点s也不应在u出队之前入队, 这显然是不可能的.因此不存在满足w > w{}'的状态, 结论1得证.

2, A*

    A*算法为每个结点u对应的状态a设立一个估价函数f, 满足f(a)不大于从从状态a转移至目标状态T的最小代价, 下面是A*算法的伪代码:

//在解空间G上以s为源结点, T为目标状态执行A*_BFS, 返回目标状态T的最小代价 
A*_BFS(G, s, T) 
	建立初始仅包含结点s且以s的权重(代价)s.w与s的估价函数s.f之和为关键字的最小堆Q
	while Q非空
		结点u = Q.top()
		if u对应状态为T
			return u.w 
		Q.pop()
		for(解空间G中所有满足未入过队列Q的u的邻接结点v) 
				Q.push(v) 

    结论2: 算法A*_BFS(G, s, T)返回解空间G中从源结点s到目标状态T的最小代价, 注意: 解空间中所有以s为起点的路径满足路径上所有b的前驱结点a使得a.w <= b.w(w对应结点的当前代价, 通常解空间树中第i层结点的w属性值为i)成立

     证明: 假设算法A*_BFS(G, s, T)返回的并非解空间G中从源结点s到目标状态T的最小代价, 设非解空间G中从源结点s到目标状态T的最小代价为g, 设G中结点e满足: e对应状态为T且e.w = g, 则e.f = 0, 设R为从源结点s到e的一条路径, 则R所有结点对应的当前代价和估价函数值之和均不超过e.w, 设最后一次执行第5行时对应Q的堆顶结点u为k, 显然在k成为堆顶之前, 结点e不能入队列Q, 否则在e成为堆顶之前k不能成为堆顶, 这与k为所有对应状态T的结点中第一个成为堆顶矛盾, 类似于结论1的证明过程, 使用数学归纳法易推出, 在k成为堆顶之前R上的所有结点均不能入队列Q, 则源结点s在k成为堆顶之前不能入队列Q, 这显然是不可能的, 因此假设不成立, 结论2得证.

猜你喜欢

转载自blog.csdn.net/solider98/article/details/84465926