三、【图算法】PFS应用-最短路径(Dijkstra算法)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_18108083/article/details/84876261

优先级搜索是个通用的框架,其可以把广度优先搜索和深度优先搜索都包含在内,只需改变优先级的更新策略即可把PFS应用到一个具体的问题中,这里介绍PFS的一个典型的应用--图的最小支撑树生成问题。

若以带权图来表示真实的通讯,交通,物流或者社交网络,则各边的权重可能代表信道成本,交通费用或交往程度,对于这样的对象,往往需要解决的问题是节点A到节点B的最短通路有多长,以及由哪些边构成。

策略:基本思想是从无到有生成最短路径树,首先任选一个顶点A作为初始的子树,然后A及其顶点补集即形成一割,这时更新和A有关连边的所有顶点的优先级为关连边的权重,在这次迭代中遍历所有顶点,选择最小的作为新的点,加入遍历树并形成一个新的割(顶点A,B组成的集合及其补集),然后紧接着进行下一次遍历,依次检查和新拉入的顶点B有关联边的所有顶点,根据“其与B的关连边的权重与顶点B的优先级数之和”“其自身当前的优先级”取最低并以该最小值更新该顶点的优先级,在这次迭代中遍历所有顶点,选择优先级数最低的点拉入遍历树,按照这一规律,将所有顶点都拉入遍历树,最小支撑树生成完毕。

实现:根据此思路构造函数对象DijkstraPU作为优先级更新策略,带入优先级搜索框架中对整个图进行遍历。

template<typename V, typename E> struct DijkstraPU
{
	void operator()(graph<V, E>* g, int uk, int v)
	{
		if (g->status(v) == UNDISCOVERED)   //如果发现顶点v尚未被发现
		{
			if ((g->weight(uk, v) + g->priority(uk)) < (g->priority(v)))
			{
				g->priority(v) = g->weight(uk, v) + g->priority(uk);   //更新优先级数
				g->parent(v) = uk;
			}
		}
	}
};

template<typename Tv, typename Te> void graph<Tv,Te>::dijkstra(int s)
{
	DijkstraPU<Tv, Te> prioUpdater;
	pfs(s, prioUpdater);
}

效率:若图G=(V,E)中共有n个顶点和e条边,则tSort仅需O(n^2)时间。

猜你喜欢

转载自blog.csdn.net/qq_18108083/article/details/84876261