最小生成树Prim算法
2016-07-13 19:46
246 查看
MST(Minimum Spanning Tree,最小生成树)问题有两种通用的解法,Prim算法就是其中之一,它是从点的方面考虑构建一颗MST,大致思想是:设图G顶点集合为V,U为最小生成树的顶点的集合。建立两个数组:lowcost[i]和mst[i],前者表示以i为终点的边的最小权值;后者对应lowcost[i]的起点。若lowcost[i]=0,则表示顶点i已经加入到U中;若lowcost[i]为无穷大,则表示无通路;若mst[i]=0,则表示顶点i已经加入到U中。
第一步:首先任意选择图G中的一点作为起始点a,将该点加入集合U;
第二步:判断V中各个顶点到U中a点的lowcost[i],及对应的mst[i](均等于a),将lowcost[i]的最小值对应的边的终点i(假设i=b)加入到U中,则此时U中含有2个顶点a和b;
第三步:重新设置lowcost[i]和mst[i]的值(此时lowcost[i]等于ai边和bi边直接的最小权值,mst[i]等于对应最小权值的顶点,a或b);
第四步:以此类推,直到所有顶点全部加入到U中,此时就构建了一颗MST。
以下是图例说明:
初始状态:
![](http://img.blog.csdn.net/20140816180420993)
我们假设V1是起始点,进行初始化(*代表无限大,即无通路):
lowcost[2]=6,lowcost[3]=1,lowcost[4]=5,lowcost[5]=*,lowcost[6]=*
mst[2]=1,mst[3]=1,mst[4]=1,mst[5]=1,mst[6]=1,(所有点默认起点是V1)
明显看出,以V3为终点的边的权值最小=1,所以边<mst[3],3>=1加入MST
![](http://img.blog.csdn.net/20140816181809296)
此时,因为点V3的加入,需要更新lowcost数组和mst数组:
lowcost[2]=5,lowcost[3]=0,lowcost[4]=5,lowcost[5]=6,lowcost[6]=4
mst[2]=3,mst[3]=0,mst[4]=1,mst[5]=3,mst[6]=3
明显看出,以V6为终点的边的权值最小=4,所以边<mst[6],6>=4加入MST
![](http://img.blog.csdn.net/20140816182214390)
此时,因为点V6的加入,需要更新lowcost数组和mst数组:
lowcost[2]=5,lowcost[3]=0,lowcost[4]=2,lowcost[5]=6,lowcost[6]=0
mst[2]=3,mst[3]=0,mst[4]=6,mst[5]=3,mst[6]=0
明显看出,以V4为终点的边的权值最小=2,所以边<mst[4],4>=4加入MST
![](http://img.blog.csdn.net/20140816182451906)
此时,因为点V4的加入,需要更新lowcost数组和mst数组:
lowcost[2]=5,lowcost[3]=0,lowcost[4]=0,lowcost[5]=6,lowcost[6]=0
mst[2]=3,mst[3]=0,mst[4]=0,mst[5]=3,mst[6]=0
明显看出,以V2为终点的边的权值最小=5,所以边<mst[2],2>=5加入MST
![](http://img.blog.csdn.net/20140816182846179)
此时,因为点V2的加入,需要更新lowcost数组和mst数组:
lowcost[2]=0,lowcost[3]=0,lowcost[4]=0,lowcost[5]=3,lowcost[6]=0
mst[2]=0,mst[3]=0,mst[4]=0,mst[5]=2,mst[6]=0
很明显,以V5为终点的边的权值最小=3,所以边<mst[5],5>=3加入MST
lowcost[2]=0,lowcost[3]=0,lowcost[4]=0,lowcost[5]=0,lowcost[6]=0
mst[2]=0,mst[3]=0,mst[4]=0,mst[5]=0,mst[6]=0
至此,MST构建成功,如图所示:
![](http://img.blog.csdn.net/20140816183241396)
Prim算法结构如下:
#define INF 65535
#define MAXV 100
void Prim(Graph *graph,int v){
int lowcost[MAXV];
int mst[MAXV];
int min;
int i,j,k;
for(i=0;i>graph->vertex_num;i++){
lowcost[i]=graph->edges[v][i];
mst[i]=graph->v;
}
for(j=0;j<graph->vertex_num;j++){
min=INF;
for(i=0;i<graph->vertex_num;i++){
if(lowcost[i]!=0&&lowcost[i]<min){
min=lowcost[i];
k=i;
}
}
lowcost[k]=0;
for(j=0;j<graph->vertex_num;j++){
if(graph->edges[k][j]!=0&&graph->edges[k][j]<lowcost[j]){
lowcost[j]=graph->edges[k][j];
mst[j]=k;
}
}
}
}
参考:http://blog.csdn.net/yeruby/article/details/38615045
第一步:首先任意选择图G中的一点作为起始点a,将该点加入集合U;
第二步:判断V中各个顶点到U中a点的lowcost[i],及对应的mst[i](均等于a),将lowcost[i]的最小值对应的边的终点i(假设i=b)加入到U中,则此时U中含有2个顶点a和b;
第三步:重新设置lowcost[i]和mst[i]的值(此时lowcost[i]等于ai边和bi边直接的最小权值,mst[i]等于对应最小权值的顶点,a或b);
第四步:以此类推,直到所有顶点全部加入到U中,此时就构建了一颗MST。
以下是图例说明:
初始状态:
我们假设V1是起始点,进行初始化(*代表无限大,即无通路):
lowcost[2]=6,lowcost[3]=1,lowcost[4]=5,lowcost[5]=*,lowcost[6]=*
mst[2]=1,mst[3]=1,mst[4]=1,mst[5]=1,mst[6]=1,(所有点默认起点是V1)
明显看出,以V3为终点的边的权值最小=1,所以边<mst[3],3>=1加入MST
此时,因为点V3的加入,需要更新lowcost数组和mst数组:
lowcost[2]=5,lowcost[3]=0,lowcost[4]=5,lowcost[5]=6,lowcost[6]=4
mst[2]=3,mst[3]=0,mst[4]=1,mst[5]=3,mst[6]=3
明显看出,以V6为终点的边的权值最小=4,所以边<mst[6],6>=4加入MST
此时,因为点V6的加入,需要更新lowcost数组和mst数组:
lowcost[2]=5,lowcost[3]=0,lowcost[4]=2,lowcost[5]=6,lowcost[6]=0
mst[2]=3,mst[3]=0,mst[4]=6,mst[5]=3,mst[6]=0
明显看出,以V4为终点的边的权值最小=2,所以边<mst[4],4>=4加入MST
此时,因为点V4的加入,需要更新lowcost数组和mst数组:
lowcost[2]=5,lowcost[3]=0,lowcost[4]=0,lowcost[5]=6,lowcost[6]=0
mst[2]=3,mst[3]=0,mst[4]=0,mst[5]=3,mst[6]=0
明显看出,以V2为终点的边的权值最小=5,所以边<mst[2],2>=5加入MST
此时,因为点V2的加入,需要更新lowcost数组和mst数组:
lowcost[2]=0,lowcost[3]=0,lowcost[4]=0,lowcost[5]=3,lowcost[6]=0
mst[2]=0,mst[3]=0,mst[4]=0,mst[5]=2,mst[6]=0
很明显,以V5为终点的边的权值最小=3,所以边<mst[5],5>=3加入MST
lowcost[2]=0,lowcost[3]=0,lowcost[4]=0,lowcost[5]=0,lowcost[6]=0
mst[2]=0,mst[3]=0,mst[4]=0,mst[5]=0,mst[6]=0
至此,MST构建成功,如图所示:
Prim算法结构如下:
#define INF 65535
#define MAXV 100
void Prim(Graph *graph,int v){
int lowcost[MAXV];
int mst[MAXV];
int min;
int i,j,k;
for(i=0;i>graph->vertex_num;i++){
lowcost[i]=graph->edges[v][i];
mst[i]=graph->v;
}
for(j=0;j<graph->vertex_num;j++){
min=INF;
for(i=0;i<graph->vertex_num;i++){
if(lowcost[i]!=0&&lowcost[i]<min){
min=lowcost[i];
k=i;
}
}
lowcost[k]=0;
for(j=0;j<graph->vertex_num;j++){
if(graph->edges[k][j]!=0&&graph->edges[k][j]<lowcost[j]){
lowcost[j]=graph->edges[k][j];
mst[j]=k;
}
}
}
}
参考:http://blog.csdn.net/yeruby/article/details/38615045
相关文章推荐
- 渗透技术一瞥(图)
- 图片引发的溢出危机(图)
- C++实现图的邻接矩阵存储和广度、深度优先遍历实例分析
- C++实现图的邻接表存储和广度优先遍历实例分析
- jQuery圆形统计图开发实例
- 手机短信轰炸(图)
- 最小生成树算法之Prim算法
- C语言实现图的遍历之深度优先搜索实例
- python数据结构之图的实现方法
- ASP.Net页面生成饼图实例
- 基于Java实现的图的广度优先遍历算法
- ps制作个性的特定形状图
- 最小生成树算法——Prim和Kruskal算法的实现
- RelativeLayout浅谈
- 图
- Ext Scheduler Web资源甘特图控件
- 键盘码 图
- 图(1)——图的定义和基本概念
- 图(2)—— 邻接矩阵表示法
- 图(2)—— 邻接矩阵表示法