Premium Manaus (prim) algorithm for building minimal spanning tree
The concept of the minimal spanning tree (Minimum cost Spanning tree):
? Suppose you want to build a highway between N cities, then connecting N cities requires only a n-1 line. At this point, nature will consider how to set up the road network under the most cost-saving premise.
? Each of the 2 cities can be set up a highway, corresponding to pay a certain economic cost. Between n cities, you can set up n (n-1)/2 lines, so how do you choose n-1 bars in these possible lines to minimize the overall cost?
Premium Manaus (Prim) algorithm of the general idea:
? The general idea is: Set the G vertex set to u, the first arbitrary select a point in Figure G as the starting point A, the point is added to the Set V, and then found from the collection u-v another point B to the point B to V at any point of the minimum weight, then the B point is also added to the set V; Then find another point from the collection u-v C to minimize the weight at any point in C to V, at which point C is added to the set V until all vertices are added to V, and an MST is constructed. Because there are n vertices, the MST has a N-1 edge, and each time a point is added to the set V, it means that an edge of the MST is found.
With illustrations and code descriptions:
Initial state:
Set up 2 data structures:
Lowcost[i]: Represents the minimum weight of an edge at the end of I, when lowcost[i]=0 describes the minimum weight of an edge at the end of i = 0, which means that I-point is added to the MST
Mst[i]: Indicates the beginning of the corresponding lowcost[i], that is, the Edge <mst[i],i> is an edge of the MST, when mst[i]=0 represents the beginning I join MST
We assume that V1 is the starting point for initialization (* represents infinity, i.e. no path):
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, (a bit of the default starting point is V1)
It is apparent that the weight of the edge at the end of the V3 is minimized = 1, so the edge <mst[3],3>=1 joins the MST
At this point, the lowcost array and the MST array need to be updated because of the addition of the dot V3:
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
It is apparent that the weight of the edge at the end of the V6 is minimized = 4, so the edge <mst[6],6>=4 joins the MST
At this point, the lowcost array and the MST array need to be updated because of the addition of the dot V6:
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
It is apparent that the weight of the edge at the end of the V4 is minimized = 2, so the edge <mst[4],4>=4 joins the MST
At this point, the lowcost array and the MST array need to be updated because of the addition of the dot V4:
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
It is apparent that the weight of the edge at the end of the V2 is minimized = 5, so the edge <mst[2],2>=5 joins the MST
At this point, the lowcost array and the MST array need to be updated because of the addition of the dot V2:
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
Obviously, the weight of the edge at the end of the V5 is minimum = 3, so the edge <mst[5],5>=3 joins the 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
At this point, the MST builds successfully:
MixSpanTree.h
#ifndef __mixspantree__#define __mixspantree__#include <stdio.h> #include <malloc.h> #include < assert.h> #include <memory.h> #define Default_vertex_size 20#define T char//dai biao ding dian de lei xing#define E Int#define max_cost 0x7ffffffftypedef struct graphmtx{int maxvertices;//zui da ding dian Shu Liang] int numvertices;// Shi Ji ding dian shu liang int numedges;//bian de shu lian t* verticeslist;//ding dian list int** Edge;//bian de Lian J Ie Xin XI, bu shi 0 jiu shi 1}graphmtx;//chu shi hua tuvoid init_graph (graphmtx* gm);//Print two-dimensional array void Show_graph (graphmtx* gm) ;//insert vertex void Insert_vertex (graphmtx* gm, T v);//Add a line between vertices insert_edge (graphmtx* gm, T v1, T v2, E cost);//delete vertex void remove _vertex (graphmtx* GM, T v);//delete the line between vertices of void Remove_edge (graphmtx* gm, T v1, T v2);//Destroy diagram void Destroy_graph (graphmtx* gm);//Get The first vertex of the line with the v Vertex int Getneighbor (graphmtx* gm, T v);//Gets the first vertex after the V2 vertex with the V1 vertex, v1 vertex int Getnextneighbor (graphmtx* gm, T V1, T v2);//using prim algorithm to make the minimum tree void MINSPANTREE_PRIm (graphmtx* gm, T v);//Gets the weight between 2 vertices e getweight (graphmtx* g, int i1, int i2); #endif
mixspantree.c
#include "mixSpanTree.h" void Init_graph (graphmtx* gm) {gm->maxvertices = default_vertex_size; gm->numedges = gm->numvertices = 0; Kai Pi ding dian de nei cun kong Jian gm->verticeslist = (t*) malloc (sizeof (T) * (gm->maxvertices)); ASSERT (NULL! = gm->verticeslist); Create a two-dimensional array//give an int a level two pointer to an array with 8 int first-level pointers//open up a memory space that can hold gm->maxvertices int-level pointers Gm->edge = (int**) malloc ( sizeof (int*) * (gm->maxvertices)); ASSERT (NULL! = Gm->edge); Open Gm->maxvertices Group, can hold gm->maxvertices int's memory space for (int i = 0; i < gm->maxvertices; ++i) {Gm->edge[i] = (int*) malloc (sizeof (int) * gm->maxvertices); }//Initialize a two-dimensional array//Let the relationship between each vertex be unconnected for (int i = 0; i < gm->maxvertices; ++i) {for (int j = 0; J < Gm->maxver Tices; ++J) {if (i = = j) Gm->edge[i][j] = 0; else gm->edge[i][j] = max_cost; }}}//prints a two-dimensional array of void Show_graph (graphmtx* gm) {printf (""); for (int i = 0; i < gm->numvertices; ++i) {printf ("%c", Gm-> Verticeslist[i]); } printf ("\ n"); for (int i = 0; i < gm->numvertices; ++i) {//At the beginning of the line, print out the name of the vertex printf ("%c:", Gm->verticeslist[i]); for (int j = 0; J < gm->numvertices; ++j) {if (gm->edge[i][j] = = max_cost) {printf ("%c", ' * '); } else{printf ("%d", gm->edge[i][j]); }} printf ("\ n"); } printf ("\ n");} Insert vertex void Insert_vertex (graphmtx* gm, T v) {//Vertex space is full, no more vertices can be inserted if (gm->numvertices >= gm->maxvertices) {retur N } gm->verticeslist[gm->numvertices++] = V;} int Getvertexindex (graphmtx* gm, T v) {for (int i = 0; i < gm->numvertices; ++i) {if (gm->verticeslist[i] = = v) return i; } return-1;} Add line void Insert_edge between vertices (graphmtx* gm, T v1, T v2, E cost) {if (V1 = = v2) return; find subscript Int J = Getvertexindex (GM, v1) of 2 vertices; int k = Getvertexindex (GM, V2); The description finds vertices, and there is no line between the dots if (j! =-1 && k! =-1) {//because there is no direction, so update 2 values gm->edge[j][k] = gm->edge[k][j] = Cost; Number of sides plus a GM->NUMEDGes++; }}//Delete the line void between vertices remove_edge (graphmtx* gm, T v1, t v2) {if (V1 = = v2) return; find subscript Int J = Getvertexindex (GM, v1) of 2 vertices; int k = Getvertexindex (GM, V2); The description finds vertices and the points are also wired if (j! =-1 && k! =-1 && gm->edge[j][k] = = 1) {//because there is no direction, so update 2 values Gm->edge[j ][K] = Gm->edge[k][j] = 0; Reduce the number of edges by one gm->numedges--; }}//delete vertex void Remove_vertex (graphmtx* gm, T v) {int k = Getvertexindex (GM, v); if ( -1 = = k) return; Calculates and decreases the number of edges associated with the node to be deleted. for (int i = 0; i < gm->numvertices; ++i) {if (gm->edge[k][i] = = 1) {gm->numedges--; }}//If the vertex you want to delete is not the last vertex if (k! = gm->numvertices-1) {//move each column to the left one column for (int i = 0; I < gm->numvertices; + +) i) {//Move the contents of the back memory to the front and set the last element to 0 memmove (& (Gm->edge[i][k]), & (Gm->edge[i][k+1]), sizeof (int) * (g M->NUMVERTICES-1-K)); GM->EDGE[I][GM->NUMVERTICES-1] = 0; }//move each line up one line up for (int i = k; i < gm->numvertices-1; ++i) {memmove (gm->edge[i], gm->edge[i+1], sizeof (int) * (gm->numvertices-1)); } memset (Gm->edge[gm->numvertices-1], 0, sizeof (int) * (gm->numvertices-1)); Memmove (& (Gm->edge[k]), & (Gm->edge[k+1]), sizeof (int*) * (gm->numvertices-1-k)); memset (Gm->edge[gm->numvertices-1], 0, sizeof (int) * (gm->numvertices-1)); Delete Point Memmove (& (Gm->verticeslist[k]), & (Gm->verticeslist[k+1]), sizeof (T) * (gm->numvertices-1-k)) ; }//If the vertex to be deleted is the last vertex else{for (int i = 0; i < gm->numvertices; ++i) {gm->edge[i][k] = Gm->edge[k][i] = 0; }}//Number of nodes minus 1 gm->numvertices--;} Destroy diagram void Destroy_graph (graphmtx* gm) {free (gm->verticeslist); for (int i = 0; i < gm->numvertices; ++i) {free (gm->edge[i]); } free (Gm->edge); Gm->edge = NULL; Gm->verticeslist = NULL; gm->maxvertices = gm->numvertices = Gm->numedges = 0;} Gets the first vertex with a connection to a vertex int Getneighbor (graphmtx* gm, T v) {int p = Getvertexindex (gM, v); if ( -1 = = p) return-1; for (int i = 0; i < gm->numvertices; ++i) {if (gm->edge[p][i] = = 1) return i; } return-1;} Gets the first vertex of the line after the V2 vertex with the V1 vertex, v1 vertex int Getnextneighbor (graphmtx* gm, T v1, t v2) {if (V1 = = v2) return-1; int p1 = Getvertexindex (gm, v1); int P2 = Getvertexindex (GM, V2); if (P1 = =-1 | | p2 = =-1) return-1; for (int i = p2 + 1; i < gm->numvertices; ++i) {if (gm->edge[p1][i] = = 1) return i; } return-1;} Gets the weight between 2 vertices e getweight (graphmtx* g, int i1, int i2) {if (I1 = =-1 | | i2 =-1) return max_cost; else return G->EDGE[I1][I2];} Using the prim algorithm to make the minimum tree void Minspantree_prim (graphmtx* g, T v) {int n = g->numvertices; e* lowcost = (e*) malloc (sizeof (E) * n); int* mst = (int*) malloc (sizeof (int) * n); ASSERT (Lowcost! = NULL && MST! = null); int k = Getvertexindex (g, v); for (int i = 0; i < n; ++i) {if (i! = k) {Lowcost[i] = Getweight (g, k, i); Mst[i] = k; } else{Lowcost[i] = 0; }} int min, Min_index; int begin, END; E cost; for (int i = 0; i < n-1; ++i) {min = Max_cost; Min_index =-1; for (int j = 0; J < N; ++j) {if (lowcost[j]! = 0 && lowcost[j] < min) {min = lowcost[j]; Min_index = j; }} begin = Mst[min_index]; end = Min_index; printf ("%c->%c:%d\n", g->verticeslist[begin],g->verticeslist[end],min); Lowcost[min_index] = 0; for (int j = 0; J < N; ++j) {cost = Getweight (g, Min_index, J); if (Cost < Lowcost[j]) {lowcost[j] = cost; MST[J] = Min_index; } } }}
Mixspantreemain.c
#include "mixSpanTree.h"int main(){ GraphMtx gm; //初始化图 init_graph(&gm); //插入顶点 insert_vertex(&gm, ‘A‘); insert_vertex(&gm, ‘B‘); insert_vertex(&gm, ‘C‘); insert_vertex(&gm, ‘D‘); insert_vertex(&gm, ‘E‘); insert_vertex(&gm, ‘F‘); //添加连线 insert_edge(&gm, ‘A‘, ‘B‘, 6); insert_edge(&gm, ‘A‘, ‘D‘, 5); insert_edge(&gm, ‘A‘, ‘C‘, 1); insert_edge(&gm, ‘B‘, ‘E‘, 3); insert_edge(&gm, ‘B‘, ‘C‘, 5); insert_edge(&gm, ‘C‘, ‘E‘, 6); insert_edge(&gm, ‘C‘, ‘D‘, 5); insert_edge(&gm, ‘C‘, ‘F‘, 4); insert_edge(&gm, ‘F‘, ‘E‘, 6); insert_edge(&gm, ‘D‘, ‘F‘, 2); //打印图 show_graph(&gm); //prim minSpanTree_prim(&gm, ‘E‘); //摧毁图 destroy_graph(&gm);}
Full code
Compilation method: Gcc-g mixspantree.c mixspantreemain.c
Premium Manaus (prim) algorithm for building minimal spanning tree