Primアルゴリズム
G =(V、E)がn個の頂点を持つ接続ネットワークであり、T =(U、TE)がGの最小スパニングツリーであるとします。ここで、UはTの頂点セット、TEはT、UおよびTEのエッジセットです。最初は空です。アルゴリズムプロセス:
- 最初にVから頂点を取り出し(v 1と仮定)、Uに組み込み、次にU = {v 1 }
- 次に、UがVの真のサブセット(つまりU⊂V)である限り、一方の端点がすでにTにあり、もう一方の端点がまだTの外側にあるすべてのエッジから、最短(つまり、最小の重み)エッジを見つけます。 (V I、V J V)、I ∈U、V J ∈VU、エッジ(V I、V J)と頂点V Jが別々に、それほど進行TE及びTエッジセットU頂点集合が組み込まれています、頂点とエッジがスパニングツリーにマージされるたびに、n-1回まで、すべてのn個の頂点がスパニングツリーTの頂点セットにマージされ、次にU = V、TEにはn-1個のエッジが含まれます。 、Tは最終的に取得される最小全域木です。
primアルゴリズムのステップ:
1.頂点セットを2つの部分-U(選択された部分)、V(選択されていない部分)に分割します。
2.毎回2つのパーツから最小の重みを持つエッジを見つける
3.頂点をUに接続します
4.すべての頂点がUに描画されるまで、1を繰り返します。
アルゴリズムの実装を容易にするために、補助配列minedge [vtxptr]をアタッチして、UからVUまでのコストが最小のエッジ(つまり、重みが最小のエッジ)を記録します。頂点v∈VUごとに、補助配列に最小エッジ[v]コンポーネントがあります。各コンポーネントには2つのフィールドが含まれています。verフィールドはUのエッジに接続された頂点を格納し、lowcostフィールドはエッジの重みを格納します。
具体的なアルゴリズムは次のとおりです。
#include <stdio.h>
// 最大顶点数
#define MaxVertexNum 50
typedef char VertexType;
typedef int Adjmatrix;
// 邻接矩阵
typedef struct {
VertexType vex[MaxVertexNum];// 顶点数组,类型假定为char
Adjmatrix arcs[MaxVertexNum][MaxVertexNum];// 邻接矩阵,类型假定为int
}MGraph;
typedef int VRType;
typedef struct{
VertexType ver;
VRType lowcost;
}MinEdge[MaxVertexNum];
MinEdge minedge;// 从顶点集U到V-U的代价最小的边的辅助数组
// 返回顶点u在MGraph的vex数组中的下标,以此作为顶点u在辅助数组中的下标
// 若G中存在顶点u,则返回该顶点在图中的位置;否则返回-1
int vtxNum(MGraph G,int u,int n){
// u是顶点,n是图G的顶点总数
int k;
for(k = 0;k < MaxVertexNum;k++){
if(G.vex[k] == u){
return k;
}
}
return -1;
}
int min(MGraph G,MinEdge MINI,int n){
int i=0,j,k,min;
while(!MINI[i].lowcost){
i++;
}
min = MINI[i].lowcost;// 第一个不为0的值
k=i;
for(j = i+1;j < n;j++){
if(MINI[j].lowcost > 0 && MINI[j].lowcost<min){
min = MINI[j].lowcost;
k=j;
}
}
return k;// 返回最小值在辅助数组中的序号
}
void prim(MGraph G,VertexType u,int n){
// G是采用邻接矩阵存储结构表示的图,u是顶点,n是顶点个数,以u作为出发点
int k,v,j;
k=vtxNum(G,u,n);// 取顶点u在辅助数组中的下标
for(v = 0;v<n;v++){// 辅助数组初始化,v是每个顶点,此处是初始顶点u与顶点v的关系
if(v!=k){
minedge[v].ver = u;//顶点域全部赋值为u点
minedge[v].lowcost = G.arcs[k][v];//距离域全部赋值为u到其他点的距离
}
}
// 初始化,U={u}
minedge[k].lowcost = 0;
for(j = 0;j < n;j++){
k=min(G,minedge,n);//k为辅助数组中值最小的点对应的序号
printf("edge:%d-%d",minedge[k].ver,G.vex[k]);// 输出生成树的边
minedge[k].lowcost = 0;// 第k顶点并入U集合
for(v=0;v<n;v++){
if(G.arcs[k][v] < minedge[v].lowcost){
// 新顶点并入U集合后,重新选择最小边
minedge[v].ver=G.vex[k];
minedge[v].lowcost=G.arcs[k][v];
}
}
}
}
ビデオを見ることをお勧めします:https : //b23.tv/BV19J411n76b