A connected graph may have multiple spanning trees, and the minimum spanning tree is a spanning tree with the least weight in a connected weighted undirected graph, which can be derived from the prim algorithm and the Kruskal algorithm, which are solved from the point and edge angle respectively. Prim Algorithm
Input: A weighted connected graph in which the vertex set is V and the edge set is E;
Initialize: Vn = {x}, where x is any node in the Set V (starting point), enew = {};
Repeat the following until VN = V: (Select the edge with the smallest weight in the set E (U). V), where u is the element in the set VN, and V is the vertex in V that is not added to the VN (if there is a plurality of edges that satisfy the preceding conditions that have the same weights, one may be chosen arbitrarily);
Adding V to the Set vn, adding (U, v) into the set en;
Output: Uses the set vn and en to describe the resulting minimum spanning tree.
The following diagram as an example, the table vertex, kown, cost, path, respectively, to indicate vertex information, whether access, weight, to reach the path;
We randomly select vertex 0 as the starting point, and the following steps are:
Steps |
Select a node |
Vertex 0 as the starting point |
0 |
Select 6 according to the scheme (6, 7, 8) |
1 |
Select 0 from the weights that can be reached by vertex 1 (7, 4, 3) and Vertex 7 (8, 3) |
5 |
Select 4 in terms of the weights (8) that can be reached by vertex 5 and the weights (7, 0) and Vertex 7 that can be reached according to Vertex 1 (8, 4) |
6 |
Select 7 in terms of the weights (6, 7) that can be reached by vertex 6 and the weight (6) that can be reached by vertex 0 |
2 |
Select 7 in terms of the weights (7) that can be reached by vertex 0 and the weights (7) that can be reached by vertex 6 |
4 |
According to Vertex 6 can reach the weight (7) Select 7 |
7 |
According to Vertex 7 can reach the weight (2) Select 2 |
3 |
All nodes have been visited and exited. |
|
Finally, the following result is obtained, in which 1 of path represents its starting point;
The prim algorithm is implemented according to the previous picture, as follows:
Class MST (object): Def __init__ (self, graph): self.graph = Graph self. N = Len (self.graph) pass Def Prim (self, start): index = Start cost, PATH = [0] * self. N, [0] * self. N # initialization start known = [x for x in map (lambda x:true if x = = Start else False) [x for X in range (self. N)]] path[start] =-1 for i in range (self. N): cost[i] = self.graph[start][i] # traverse the remaining nodes for I in range (1, self. N): mi = 1e9 # Find the node for the relative minimum weight for the J in range (self.
N): If not known[j] and Mi > cost[j]: mi, index = cost[j], J # Calculate Path value For j in range (self.
N): if self.graph[j][index] = = Mi:path[index] = J Known[index] = True # Updates the weights for the index connected to other nodes for the J in range (self.
N): If not known[j] and cost[j] > Self.graph[index][j]:COST[J] = self.graph[index][j] Print (path) # Diagram represents the MST with a pro matrix ([[1e9, 6, 8, 1e9, 7, 1e9, 1e9, 1e9], [6, 1E9, 7 , 1e9, 1e9, 3, 4, 1e9], [8, 7, 1e9, 1e9, 1e9, 1e9, 6, 1e9], [1e9, 1e9, 1e9, 1e9, 1e9, 1e9, 1e9, 2], [7, 1E9, 1 E9, 1e9, 1e9, 1e9, 1e9, 1e9], [1e9, 3, 1e9, 1e9, 1e9, 1e9, 1e9, 9], [1e9, 4, 6, 1e9, 1e9, 1e9, 1e9, 7], [1e9, 1e9, 1e9, 2, 1e9, 9, 7, 1e9],]. Prim (0)
Path results are: [-1, 0, 6, 7, 0, 1, 1, 6]
Kruskal AlgorithmConstructs a child graph that contains only n vertices, and the edges set is empty, if each vertex in the child graph is regarded as the root node of each tree, then it is a forest containing n trees. After that, select one of the smallest weights from the edge of the diagram, and if the two vertices of the edge belong to different trees, it is added to the child graph, where the two vertices are in a tree; Conversely, if the edge of the two vertex has fallen on the same tree, it is not advisable, but should take down a weight of the smallest edge to try again. By analogy, the forest has only one tree. The Kruskal algorithm can be quickly implemented on the basis of the search and collection.
As an example of the following diagram, the table on the left is a collection of nodes that can be connected. We first have to sort each edge based on the weights, and then we start working on each side.
Finally, the following results are obtained:
Kruskal Algorithm ImplementationBecause we're dealing with edges, we need to build the data structure of the edges and get the data for each edge from the given graph.
Class Edge (object):
def __init__ (self, start, end, weight):
Self.start = start
self.end =
End Self.weight = Weight
def getedges (self):
edges = []
for I in Range (Self.vertex):
for J in range (i+1, self. Vertex):
if SELF.GRAPH[I][J]!= 1e9:
edge = Edge (I, J, Self.graph[i][j])
edges.append (Edge)
return Edges
The next step is the Kruskal function:
def Kruskal (self):
union = Dict.fromkeys ([I for I in Range (Self.vertex)],-1) # Auxiliary array, to determine whether two nodes are connected
self.edges = Self.getedges ()
self.edges.sort (Key=lambda x:x.weight)
res = []
def getend (start): While
union[ Start] >= 0:
start = Union[start] Return to
start
for the edge in Self.edges:
# Find the last node of the connected line
n1 = Gete nd (edge.start)
n2 = Getend (edge.end)
# If a common endpoint does not process if
N1!=:
print (' {}-----n2} '. Format (>{ , N2))
(n1, N2) = (N2, N1) if UNION[N1] < UNION[N2] Else (N1, N2)
union[n2] + = Union[n1]
union[n1] = n2< C19/>res.append (Edge)
print (Union.values ())
Where the union prints out the results and the graphs are consistent, for [3, 3, 5, 6, 6, 6,-8, 3].