We have said in the definition of graph that the graph with the right value is the net structure. The spanning tree of a connected graph is a very small connected sub-graph, which contains all the vertices in the graph, but only enough to form the n-1 edge of a tree. The so-called minimum cost, which is n vertices, connects a connected graph with a n-1 edge and minimizes the weights. Combining these two concepts, we can conclude that the minimal cost spanning tree, the smallest spanning tree, is constructed for the connected network (Minimum costs Spanning trees).
To find the minimum spanning tree of connected graphs, there are two classical algorithms, the Primm algorithm and the Kruskal algorithm, the PRIMM algorithm is introduced here.
In order to be able to understand this algorithm, we first construct the adjacency matrix of the network graph, as shown in the right image of 7-6-3.
In other words, now we have a storage structure of mgraph mg (see "adjacency matrix creation Diagram "). MG has 9 vertices, its two-dimensional array is shown on the right, and in the array we use 65535 to represent infinity.
Here we look at the program and the diagram of each step of the cycle:
Algorithm code: (adapted from "Big Talk data Structure")
C + + Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21st 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
|
/* Prim algorithm generates minimum spanning tree */ void Minispantree_prim (Mgraph MG) { int min, I, J, K; int Adjvex[maxvex];/* Save the relevant vertex subscript */ int Lowcost[maxvex];/* Save weights for edges between related vertices */ lowcost[0] =0;/* Initialize the first weighted value to 0, that is, V0 joins the spanning tree */ /* The value of lowcost is 0, where the vertex of this subscript has been added to the spanning tree */ adjvex[0] =0;/* Initialize the first vertex subscript 0 */ cout <<"The edge of the minimum spanning tree is:" << Endl; for (i =1; i < mg.numvertexes; i++) { Lowcost[i] = mg.arc[0][i];/* Deposit The weights of the v0 vertices with their edges in the array */ Adjvex[i] =0;/* Initialization is v0 subscript */ }
for (i =1; i < mg.numvertexes; i++) { min = INFINITY;/* Initialize the minimum weight to ∞, */
j =1; K =0;
while (J < mg.numvertexes)/* loop all vertices */ { if (lowcost[j]! =0 && Lowcost[j] < min)/* If the weight value is not 0 and the weight is less than min */ { min = Lowcost[j];/* Let the current weight be the minimum */ K = J;/* Deposit The subscript of the current minimum value in K */ }
j + +; }
cout <<"(" << adjvex[k) <<"," << K <<")" <<" ";/* Print the edge of the lowest weight in the edge of the current vertex */ LOWCOST[K] =0;/* Sets the weight of the current vertex to 0, indicating that the vertex has completed the task */
for (j =1; J < Mg.numvertexes; J + +)/* loop all vertices */ { /* If the subscript is a k vertex each edge weight value is less than the previous vertices are not added to the spanning tree weights */ if (lowcost[j]! = 0 && mg.arc[k][j] < lowcost[j]) { LOWCOST[J] = Mg.arc[k][j]; / * Store smaller weights in lowcost location */ ADJVEX[J] = k; / * Deposit the vertex labeled K into Adjvex */ } } } cout << Endl; } |
1, the program 1~16 line is the initialization operation, where the 7th to 8th line adjvex[0] = 0 meaning is now starting from the vertex v0 (in fact, from that point of no matter, assuming that starting from V0), lowcost[0]= 0 means that V0 has been included in the minimum spanning tree, After all, the values in the Lowcost array are set to 0 to indicate that the vertices of this subscript are included in the minimum spanning tree.
2. Line 11th to 15th reads the first row of data for the adjacency matrix, so the lowcost array is {0, 10, 65535, 65535, 65535, 11, 65535, 65535, 65535}, and the Adjvex array is all 0. The initialization is complete.
3, the 17th to 49th line has a total cycle of 8 times, I from 11 to 8, the entire cycle is the process of constructing the minimum spanning tree.
4, the 24th to 33rd Line, after the cycle min = ten, k = 1. Note If the 26 line is judged lowcost[j]! = 0 indicates that the vertex that is already a spanning tree does not participate in the lookup of the minimum weight.
5, the 35th line, because k = 1, adjvex[1] = 0, so the print result is (0, 1), representing the V0 to V1 edge for the smallest spanning tree first edge, such as the first small figure.
6, the 36th line, because k = 1 will lowcost[k] = 0 that is, vertex v1 into the smallest spanning tree, at this time the Lowcost array is {0, 0, 65535, 65535, 65535, 11, 65535, 65535, 65535}
7, the 38th to 47th line, J Loop from 1 to 8, because k = 1, find the adjacency matrix of the V1 row of the various weights, and lowcost array corresponding values, if smaller then modify the Lowcost value, and the K value in the Adjvex array. So the final lowcost = {0, 0, 18, 65535, 65535, 11, 16, 65535, 12}. The values of the Adjvex array are {0, 0, 1, 0, 0, 0, 1, 0, 1}. The If judgment here also shows that V0 and v1 are already the vertices of the spanning tree that do not participate in the minimum weights.
Described above as the first cycle, corresponding to the first small figure of i = 1, due to the text to describe clearly the entire process is cumbersome, the following gives I for a different value after the cycle of the generation tree diagram, so-called a graph value thousand words, everyone to the diagram of their own simulation to cycle 8 times can understand the idea of Primm algorithm.
The edges of the smallest spanning tree are: (0, 1), (0, 5), (1, 8), (8, 2), (1, 6), (6, 7), (7, 4), (7, 3)
Finally, let's summarize the definition of the PRIMM algorithm:
Suppose n = (v{e}) is a connected network, TE is the collection of the smallest spanning tree on N. The algorithm starts with the U = {u0} (UO V), TE = {}. Repeat the following: at all
The Edge (U, V) E of the uu,v v-u is searched for a least-cost edge (u0, V0) into the set TE, while V0 is incorporated into u until U = v. At this point there must be a n-1 edge in TE, and T = (V,{te}) is the smallest spanning tree of N.
by looping nesting in the algorithm code, it is known that the time complexity of this algorithm is O (n^2).
Comparing the Primm and Kruskal algorithms, the Kruskal algorithm is mainly aimed at the edge, and the number of edges is relatively high, so there is a great advantage for sparse graphs, and the Primm algorithm is better for dense graphs, that is, when the number of sides is very large.
Primm Prim algorithm-plot minimum spanning tree