三、【图算法】PFS应用-最小支撑树(Prim算法)

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

最小支撑树:对于一个带权网络G,若G的某一无环连通子图能覆盖G中所有的顶点,且其各边的权重总和最低,则称此树为图G的最小支撑树。

事实上,在实际生活中的网络架构设计,VLSI布线设计等诸多问题都可以转换为最小支撑树问题,在这些问题中,边的权重往往等效于可量化的成本,因此作为此类优化问题的基本模型,最小支撑树的价值不言而喻。

Prim算法的理论依据:最小支撑树总是会采用联接每一割的最短跨越边。

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

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

template<typename V, typename E> struct PrimPU
{
	void operator()(graph<V, E>* g, int uk, int v)
	{
		if (g->status(v) == UNDISCOVERED)   //若顶点v尚未被发现
			if ((g->weight(uk, v)) < (g->priority(v)))  //比较当前边的权重和之前遍历时设置的优先级数
			{
				g->priority(v) = g->weight(uk, v);   //根据权重设置优先级数
				g->parent(v) = uk;   //更新父节点
				cout << "寻找顶点(uk,v)" << "(" << uk << "," << v << ")" <<"----w---"<<g->weight(uk,v)<< endl;
			}
	}
};

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

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值