最小生成树(prime算法)
来源:互联网 发布:linux 光纤网卡 编辑:程序博客网 时间:2024/06/10 03:10
Prim算法
1.概览
普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克发现;并在1957年由美国计算机科学家罗伯特·普里姆独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法。
2.算法简单描述
1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;
3).重复下列操作,直到Vnew = V:
a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;
4).输出:使用集合Vnew和Enew来描述所得到的最小生成树。
下面对算法的图例描述
3.简单证明prim算法
反证法:假设prim生成的不是最小生成树
1).设prim生成的树为G0
2).假设存在Gmin使得cost(Gmin)<cost(G0) 则在Gmin中存在<u,v>不属于G0
3).将<u,v>加入G0中可得一个环,且<u,v>不是该环的最长边(这是因为<u,v>∈Gmin)
4).这与prim每次生成最短边矛盾
5).故假设不成立,命题得证
下面附上数据结构严蔚敏版书上的代码:
void miniSpanTree_prim(MGraph G,VertexType u){ k=LocateVex(G,u); for(j=0; j<G.vexnum; ++j) if(j!=k) closedge[j]= {u,G.arcs[k][j].adj}; closedge[k].lowcost=0; for(i=1; i<G.vexnum; ++i) { k=minimum(closedge); printf(closedge[k].adjvex,G.vexs[k]); closedge[k].lowcost=0; for(j=0; j<G.vexnum; ++j) if(G.arcs[k][j].adj<closedge[j].lowcost) closedge[j]= {G.vexs[k],G.arcs[k][j].adj}; }}完整代码:
#include <stdio.h>#include <stdlib.h>#include <iostream.h>#define INFINITY 88 #define MAX_VERTEX_NUM 10 typedef int VRType;typedef char VertexType;/////////////////////////////////////////////////////typedef struct ArcCell{ VRType adj; //图的权值}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct{ VertexType vexs[MAX_VERTEX_NUM]; //顶点向量 AdjMatrix arcs;//邻接矩阵 int vexnum, arcnum; //顶点数,弧数}MGraph;///////////////////////////////typedef struct{ VertexType adjvex;//顶点向量 VRType lowcost;//边长}closedge[MAX_VERTEX_NUM];//////////////////////////////////////////////void CreateGraph(MGraph &G);//创建矩阵存储void Print(MGraph G);//输出创建矩阵void MiniSpanTree_PRIM(MGraph G, VertexType u);//prime算法int LocateVex(MGraph G, VertexType u);//求结点u的位置int minimum(closedge close);//求结点的下一个顶点//////////////////////////////////////////////void CreateGraph(MGraph &G){//采用数组表示法,构造无向图G int i,j,k; printf("请输入无向图的顶点数:/n"); scanf("%d",&G.vexnum); printf("请输入无向图的弧数:/n"); scanf("%d",&G.arcnum); printf("请输入各个顶点符号:/n"); for(i=0;i<G.vexnum;++i)//构造顶点向量 cin>>G.vexs[i]; for(i=0;i<G.vexnum;++i)//初始化邻接矩阵 for(j=0;j<G.vexnum;++j) G.arcs[i][j].adj=INFINITY; char v1,v2;//顶点 int w;//<v1,v2>的权值 for(k=1;k<=G.arcnum;++k){ cout<<"请输入第:"<<k<<"条边依附的俩个顶点以及权值:/n"; cin>>v1>>v2>>w; i=LocateVex( G, v1); j=LocateVex( G, v2); G.arcs[i][j].adj=w; G.arcs[j][i].adj=G.arcs[i][j].adj; } }void MiniSpanTree_PRIM(MGraph G,VertexType u){ int i, j, k = 0; closedge close; k = LocateVex ( G, u ); for ( j = 0; j < G.vexnum; j++ ) { if (j != k) { close[j].adjvex = u; close[j].lowcost = G.arcs[k][j].adj; } } cout<<j<<" fiusduasdfhul"; close[j].lowcost = INFINITY; close[j].adjvex = '/0';//为了在minimum(close)中保证while循环的结束条件 close[k].lowcost = 0; for (i = 1; i < G.vexnum; i++) { k = minimum(close); cout<<close[k].adjvex<<"---->"<<G.vexs[k]<<" "<<close[k].lowcost<<endl; close[k].lowcost = 0; for (j=0; j<G.vexnum; j++) { if (G.arcs[k][j].adj < close[j].lowcost) { close[j].adjvex = G.vexs[k]; close[j].lowcost = G.arcs[k][j].adj; } } }}int LocateVex(MGraph G,char v){//确定v在G中的位置 int i=-1; for(i=0;i<G.vexnum;++i) { if(G.vexs[i]==v) break; else continue; } return i;}void Print(MGraph G){ int i,j; for(i=0;i<4;i++){ cout<<G.vexs[i]<<endl; } for(i=0;i<4;i++) { for(j=0;j<4;j++) cout<<G.arcs[i][j].adj<<"/t"; cout<<endl; }}int minimum(closedge close){ int i=0, client = INFINITY, j; while(close[i].adjvex != '/0') { if (client > close[i].lowcost && close[i].lowcost != 0) { client = close[i].lowcost; j = i; } i++; } return j;} int main(int argc, char* argv[]){ MGraph G; CreateGraph(G); Print(G); MiniSpanTree_PRIM(G,'a'); return 0;}
- 最小生成树(prime算法)
- 最小生成树算法[Prime/(Kruskal)]
- prime算法(最小生成树模板)
- 最小生成树(prime算法)
- 最小生成树算法[prime]
- 最小生成树-prime算法
- 最小生成树 prime算法
- 最小生成树 prime算法
- 最小生成树Prime算法
- 最小生成树--Prime算法
- 最小生成树 Prime算法
- 最小生成树 prime 算法
- 最小生成树-prime算法
- Prime算法求最小生成树 (最小堆优化)
- 最小生成树(kruskal算法)和 (Prime算法)
- prime算法-最小生成树算法
- 最小生成树(prime)
- 最小生成树(prime)
- hdu 1016
- AngularJs获取时间
- 「组合计数」CodeForces
- 计算并输出每行字符串的字母值
- 每天一个linux命令(8):free 命令
- 最小生成树(prime算法)
- 为什么要初始化 CSS 样式
- KMP算法代码
- Visualizing and Understanding Convolutional Networks笔记2
- thinkphp微信支付-JSAPI
- Centos python36 安装tensorflow记录
- AngularJs购物车删除和计算总金额
- 【论文阅读】Superpixel-based Tracking-by-Segmentation using Markov Chains
- HBase最佳实践-HBase中的写性能优化策略