Greedy algorithm to construct minimum spanning tree: kruskal algorithm, prim algorithm

1. Definition:
inConnected undirected graphG(V,E)Find an Eacyclic subset of edges in T, so that it can connect all nodes and have the smallest weight.
a)Since T is acyclic, it can be regarded as a tree
b)Since it is generated by graph G, it is called (graph G) spanning tree
c)Since T has the smallest weight, it is called the minimum spanning tree.
Since T is acyclic, V vertices must have V-1 edges.

2. Greedy strategy:
each time an edge of the minimum spanning tree is grown, V-1 cycles are performed to complete the tree building. The growing edges must be lightweight edges (minimum weight) and do not form a ring.
Method: kruskal (Kruskal) algorithm or prim (prime) algorithm

3. Prim (prime) algorithm:
This algorithm can be called the point addition method . Each iteration selects the point corresponding to the edge with the least cost and adds it to the minimum spanning tree. The algorithm starts from any vertex s and gradually grows to cover all vertices of the entire connected graph.

3.1. Algorithm flow and graph:
Input: graph G(V,E)and any node uas the starting point; output: edge set P

  1. The node ujoins the node collection U;
  2. Select the Uleast cost edge connected to the nodes in the set to join the set P(such as edges <u,v>), and vjoin the connected nodes (such as ) to the set U;
    (if there are multiple edges with the same weight, you can choose one of them at will);
  3. Repeat step 2 until all nodes join the set U.

Insert picture description here
3.2. C++ code:

#include <queue>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct edge {
    
     // 边的定义
	int start;
	int end;
	int weight;
	edge(int x, int y, int z) :start(x), end(y), weight(z) {
    
    }
	bool operator< (const edge& tmp) const {
    
     //用于优先队列的比较函数
		return weight > tmp.weight;
	}
};

const int NUM = 6;
int G[NUM][NUM]; //假设图已经定义好了,如G[0][2] = 5; 5为权重
void MiniSpanTree_prim(int(*G)[NUM], int root)
{
    
    
	vector<int> V; //记录MST已经包含的点;
	V.push_back(root);
	priority_queue<edge> edge_all; // 放入权重边,自动排序
	for (int i = 0; i < NUM; i++) {
    
     // 放入与起点连接的边
		if (G[root][i] != 0) {
    
     // 0 代表没有路
			edge tmp(root, i, G[root][i]);
			edge_all.push(tmp);
		}
	}
	cout << "Prim :" << endl;
	for (int i = 0; i < NUM - 1; i++) {
    
     //共N-1条边
		edge curr = edge_all.top(); //取得代价最小边
		edge_all.pop();
		while (find(V.begin(), V.end(), curr.end) != V.end()) {
    
     //边终点若已包含,则丢弃后换一条边
			curr = edge_all.top();
			edge_all.pop();
		}
		V.push_back(curr.end); //放入这条边的终点v
		cout << curr.start << " --> " << curr.end << " " << curr.weight << endl; // 输出MST的边
		for (int j = 0; j < NUM; j++) {
    
     // 加入终点v连接的边
			if (G[curr.end][j] != 0 && find(V.begin(), V.end(), j) == V.end()) {
    
    
				edge tmp(curr.end, j, G[curr.end][j]);
				edge_all.push(tmp);
			}
		}
	}
}

4. Kruskal (Kruskal) algorithm:
This algorithm can be called the additive edge method . The initial minimum spanning tree edge number is 0. Each iteration selects a minimum cost edge that satisfies the condition and adds it to the edge set of the minimum spanning tree in.

4.1. Algorithm flow and diagram:
input: graph G(V,E); output: edge set P.

  1. Sort all edges in the graph from smallest to largest cost;
  2. Consider the n vertices in the graph as a forest of independent n trees;
  3. Select edges from smallest to largest weight, u,vIf the two vertices of the selected edge belong to two different trees, they become an edge of the minimum spanning tree, and the two trees are merged into one tree at the same time. Otherwise, take the edge with the smallest weight and try again.
  4. Repeat (3) until all vertices are in a tree or there are n-1 edges.

Insert picture description here

4.2. C++ code:

#include <queue>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct edge {
    
     // 边的定义
	int start;
	int end;
	int weight;
	edge(int x, int y, int z) :start(x), end(y), weight(z) {
    
    }
	bool operator< (const edge& tmp) const {
    
     //用于优先队列的比较函数
		return weight > tmp.weight;
	}
};

const int NUM = 6;
int G[NUM][NUM]; //假设图已经定义好了,如G[0][2] = 5; 5为权重
void MiniSpanTree_kruskal(int(*G)[NUM])
{
    
    
	int node_coll[NUM] = {
    
     0 }; //判断节点是否属于一棵树
	int count = 1; // 用于不同树的标记
	priority_queue<edge> edge_all; // 放入权重边,自动排序
	for (int i = 0; i<NUM; i++) {
    
     //放入所有边,并自动排序
		for (int j = 0; j<NUM; j++) {
    
    
			if (G[i][j] != 0) {
    
    
				edge tmp(i, j, G[i][j]);
				edge_all.push(tmp);
			}
		}
	}
	for (int i = 0; i<NUM - 1; i++) {
    
     //共N-1条边
		edge tmp = edge_all.top(); // 取代价最小边
		edge_all.pop();
		while (node_coll[tmp.start] == node_coll[tmp.end] && node_coll[tmp.start] != 0 && node_coll[tmp.end] != 0) {
    
     // 找到属于不同树的边
			tmp = edge_all.top();
			edge_all.pop();
		}
		cout << tmp.start << " --> " << tmp.end << " " << tmp.weight << endl; // 输出MST的边
		if (node_coll[tmp.start] == 0 && node_coll[tmp.end] == 0) {
    
     //不同树的边的情况1
			node_coll[tmp.start] = count;
			node_coll[tmp.end] = count;
			count++;
		}
		else if (node_coll[tmp.start] == 0 && node_coll[tmp.end] != 0) {
    
     //不同树的边的情况2
			node_coll[tmp.start] = count;
			node_coll[tmp.start] = node_coll[tmp.end];
		}
		else if (node_coll[tmp.start] != 0 && node_coll[tmp.end] == 0) {
    
     //不同树的边的情况3
			node_coll[tmp.start] = count;
			node_coll[tmp.end] = node_coll[tmp.start];
		}
		else if (node_coll[tmp.start] != 0 && node_coll[tmp.end] != 0) {
    
     //不同树的边的情况4
			node_coll[tmp.start] = count;
			for (int i = 0; i<NUM; i++) {
    
    
				if (node_coll[i] = node_coll[tmp.end]) {
    
    
					node_coll[i] = node_coll[tmp.start];
				}
			}
		}
	}
}

Reference material: Two methods of minimum spanning tree (Kruskal algorithm and Prim algorithm)
Introduction to algorithm 23.2 Kruskal algorithm and Prim algorithm

to sum up:

1. The kruskal algorithm is the addition method, the prim algorithm is the addition method, and the memory algorithm idea is good.

Guess you like

Origin blog.csdn.net/qq_33726635/article/details/106024969