最小生成树(Prim)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

最小生成树(Prim)
1、问题的提出
假设要在n个城市之间建立通信联络网,则连通n个城市只需要n-1条线路,如何选择这n-1条线路,使这个建设费用最低。

在每个城市之间都可以建立设置一条线路,相应地都要付出一定的经济代价。

n个城市之间,最多可能设置n(n-1)/2条线路,那么,如何选择这些可能的线路中n-1条,使总的耗费最少呢?
可以用连通网来表示n个城市以及n个城市之间可能设置的通信线路,其中网的顶点表示城市,边表示两个城市之间的线路,赋于边的权值表示相应的代价。

对于n个顶点的连通网可以建立许多不同的生成树,每一棵生成树都可以是一个通信网。

现在,我们要选择这样的一棵生成树,也就是使总的耗费最少。

这个问题就是构成连通网的最小代价生成树(简称最小生成树)。

2、最小生成树原理
构造最小生成树可以有多种算法。

其中多数算法都利用了最小生成树的下列一种简称为MST的性质。

MST:假设N=(V,{E})是一个连通网,U是顶点集V的一个非空子集。

若(u,v)是一条具有最小权值(代价)的边,其中,
∈∈-,则必存在一棵包含边(u,v)的最小
u U v V U
生成树。

u v。

设T是连通网上的一棵最小生反证法:假设网N的任一棵最小生成树都不包含(,)
成树,当将(u,v)加入到T中时,由生成树的定义,T中必存在一条包含(u,v)的回路。

另一方面,由于T是生成树,则在T上必存在另一条边''
u v('u和u不一定是同一个点,
(,)
'
v和v也不一定是同一个点),其中''
∈∈-,且u和'u,v和'v之间均有路径相
u U v V U
,
通。

删去边''
u v,便可消除上述回路,同时得到另一棵生成树'T。

因为(,)
(,)
u v的代价不高于''
u v的代价,则'T的代价不高于T的代价,'T是包含(,)
(,)
u v的一棵最小生成树。

由此和假设矛盾。

3、Prim 算法
假设(,{})N V E =是连通网,TE 是N 上的最小生成树中边的集合。

算法从00{|},{}U u u V TE =∈=开始,重复执行下述操作:在所有,u U v V U ∈∈-的边
(,)u v E ∈中找一条代价最小的边00(,)u v 并入集合TE ,同时0v 并入U ,直到U V =为止。

此时TE 必有n-1条边,则(,{})T V TE =为N 的最小生成树。

4、Prim 算法C 代码
为了实现这个算法需附设一个辅助数组closedge ,记录从U 到V U -具有最小代价的边。

对每个顶点i v V U ∈-,在辅助数组中存在一个相应分量closedge[i-1](表示V U -中
的点),它包括两个域,其中adjvex 域存储该边依附的在U 中的顶点。

Lowcost 存储该边上的权值,显然:
[1].cos {cos (,)|}i closedge i low t M in t u v u U -=∈
void minispantree (mgraph g ,vertextype u )
{
int i ,j ,k ,m ;
struct {
vertextype adjvex ;
vrtype lowcost ;
}closedge [MAX_VERTEX_NUM ];
k =locatevex (g ,u );
for (j =0;j <g .vexnum ;j ++)//辅助数组初始化
if (j !=k )
{
closedge [j ].adjvex =u ;
closedge [j ].lowcost =g .arcs [k ][j ].adj ;
closedge [k ].lowcost =0;//初始,U={u}
}
for (i =1;i <g .vexnum ;i ++)//选择其余G.vexnum-1个顶点
{
//下列两个for 循环求出T 的下一个节点,第k 个节点
for (m =0;m <g .vexnum ;m ++) if (closedge [m ].lowcost !=0) k =m ;
for(m=0;m<g.vexnum;m++)
if(closedge[m].lowcost!=0&&closedge[k].lowcost>closedge[m].lowcost)
k=m;
cout<<closedge[k].adjvex<<g.vexs[k]<<endl;
closedge[k].lowcost=0;//第k个顶点如U集合
for(j=0;j<g.vexnum;j++)
if(g.arcs[k][j].adj<closedge[j].lowcost)
{
//新顶点并入U后重新计算各边的最小值
closedge[j].adjvex=g.vexs[k];
closedge[j].lowcost=g.arcs[k][j].adj;
}
}
}。

相关文档
最新文档