搜索_BFS(广度优先搜索)_算法分析

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

    为方便讨论BFS算法, 考虑对图的每个结点设置属性color表示结点的颜色, color可取WHITE, GRAY, BLACK, 设置属性d表示对应结点到源结点的最短路径长度, 设置属性p, 其中v.p表示存在一条从源结点到结点v的最短路径且v的前驱为v.p, 下面先给出BFS算法然后对其进行分析:

//以v为源点, 对图G进行广度优先遍历 
BFS(G, s)
	for G中除s外每个结点v
		v.color = WHITE	
	s.color = GRAY
	s.d = 0
	s.p = NIL 
	建立初始仅包含结点s的队列Q 
	while !Q.empty()
		u = Q.top()
		Q.pop()
		for 所有以u为起点的边的终点v
			if v.color == WHITE
				v.color = GRAY
				v.d = u.d + 1
				Q.push(v)
		u.color = BLACK;	 

    结论1: G中从结点s可达的每个结点入队列Q一次且出队列Q一次

    证明: 根据每个节点入队列Q之前为白色, 进入队列后立即被设置为黑色可知每个结点至多入队列一次和出队列一次, 接下来证明G中从结点s可达每个结点均入队列一次, 假设存在从结点s可达的结点a在算法BFS执行的整个过程中未进入队列Q, 记s到a的一条最短路径为c_{1}...c_{k}, c_{1}=s, c_{k}=a, 那么c_{k - 1}也应不进入队列Q, 进而c_{k - 2}...c_{1}均不应进入队列Q, 这显然与第8行s进入队列Q矛盾, 因此假设不成立, 故G中从结点s可达每个结点均入队列一次.

    结论2: Q中始终包含G中所有被设置为灰色的结点, 设Q从队头到队尾包含的元素为q_{1}...q_{n}, 那么q_{i - 1}.d <= q_{i}.d(1 <= 2 <= n), 且q_{n}.d <= q_{1}.d + 1

    证明: 考虑根据Q在各个时刻的状态将时间分为若干个闭区间, 第i(i >= 0)个区间的起点对应Q的起始状态为Q中只包含到源结点的最短路径长度为i的结点且第i个区间终点对应Q中仅包含一个到源结点的最短路径长度为i的结点, 使用数学归纳法较易证明结论2在每个时间区间均成立, 进而结论2是正确的, 此处不再赘述具体的证明过程.

    结论3: 算法BFS执行完毕后, 设有向图G{}'的结点集合为所有从源结点s可达的结点(包括源结点s), 其边集为{<u, v> | v.p = v}, 那么G{}'为一棵以s为根有向树, 且G{}'中任意结点u满足: u.d等于s到u的最短路径的距离, u.p对应该有向树中u的父结点, 亦为某条从s到u的最短路径上u的前驱结点.

    证明: 使用结论2证明过程中将时间分为多个区间的方法, 较易证明结论3的正确性, 此处不再赘述证明过程. 

    结论4: 算法BFS的时间复杂度为O(v + e), 次数v为从结点s可达的结点个数, e为从结点s发出的所有路径中不同边的个数

    证明: 依据结论1和每个结点出队列Q时第12行的for循环头检测将探索所有以u为起点的边即可证明之.

猜你喜欢

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