Basic algorithm that programmers must know 6-Prim algorithm (Prim algorithm)

Minimum spanning tree problem

Primm algorithm is to solve the minimum spanning tree problem (MinimumCostSpanningTree), referred to as MST.
Given a weighted undirected connected graph, how to choose a spanning tree so that the sum of weights on all edges in the tree is the smallest. This is called the minimum spanning
tree. The characteristics of the minimum spanning tree:
1) N vertices must have N -1 edge
2) contains all vertices

Primm Algorithm

Prim algorithm finds the minimum spanning tree, that is, in a connected graph containing n vertices,
find a connected subgraph with only (n-1) edges containing all n vertices, which is the so-called minimum Connected subgraph

Problem example

There are seven villages (A, B, C, D , E, F, G), now need to 7 village road communication
distance villages represented by the edge (right), such as A-B 5 km
Revising The road ensures that all villages can be connected, and the total length of the road is the shortest?
Insert picture description here

solve

The prim algorithm starts with any node in the same graph. No matter which node it starts from, the weight of the final generated minimum spanning tree is the same, so now start processing from A. The
first step is
to mark that A node has been visited. After visited=[A]
and then look at the nodes connected to A that have not been visited, then there are now
AC(7), AG(2), AB(5), where 2 is the smallest, just connect to AG,
Then mark that G has been visited, visited=[A,G] The
second step
is now that A and G have been visited. Regarding AG as a whole, it is also to find nodes connected to AG that have not been visited, then Now there are
AC(7), GE(4), GF(6), GB(3), AB(5), of which 3 is the smallest, connect to GB
and mark B has been visited, visited=(A,G, B)
Then
keep looping like this until you find n-1 edges, that is, find 6 edges

Code

package basic;

import java.util.Arrays;

public class Prim
{
    
    
	public static int [][]weight=new int[][]{
    
    
        {
    
    10000,5,7,10000,10000,10000,2},
        {
    
    5,10000,10000,9,10000,10000,3},
        {
    
    7,10000,10000,10000,8,10000,10000},
        {
    
    10000,9,10000,10000,10000,4,10000},
        {
    
    10000,10000,8,10000,10000,5,4},
        {
    
    10000,10000,10000,4,5,10000,6},
        {
    
    2,3,10000,10000,4,6,10000},};
    
    public static char[] nodes=new char[] {
    
    'A','B','C','D','E','F','G'};
    public static int number=nodes.length;
    public static Graph graph=new Graph(number);
    
	public static void main(String[] args)
	{
    
    
		CreateGraph(graph, number, nodes, weight);
		show(graph);
		prim(graph, 0);
	}
	/*
	 * 普利姆算法的核心,传入的参数分别是图graph和从哪一个节点开始index
	 * 首先创建一个标记节点是否被访问过的数组visited
	 * 然后将传进来的index节点标记为已经被访问过,还要定义一个数值很大的MinWeight
	 * 用来寻找图中小的权值的边
	 * 然后是for循环,我们需要生成graph.number-1条边
	 * 所以第一重for循环只是循环需要生成的边
	 * 然后再是两层的for循环,用来遍历整个图的,寻找最小的还没访问的边
	 */
	public static void prim(Graph graph,int index)
	{
    
    
		boolean[] visited=new boolean[graph.number];
		visited[index]=true;
		int MinWeight=Integer.MAX_VALUE;
		int x1=0,x2=0;
		
		for(int x=0;x<graph.number-1;x++)
		{
    
    
			for(int i=0;i<graph.number;i++)
			{
    
    
				for(int j=0;j<graph.number;j++)
				{
    
    
					if(visited[i]&&!visited[j]&&graph.weight[i][j]<MinWeight)
					{
    
    
						MinWeight=graph.weight[i][j];
						x1=i;
						x2=j;
					}
				}
			}
			System.out.println("边:" + graph.nodes[x1] + "-" + graph.nodes[x2] + ",权值:" + MinWeight);
			visited[x2]=true;
			MinWeight=Integer.MAX_VALUE;
		}
	}
	
	/**
	 * 这是初始化对应的图对象,创建好对应的邻接矩阵
	 * @param graph 图对象
	 * @param number 节点数
	 * @param nodes  保存节点的数组
	 * @param weight  保存权重的邻接矩阵
	 */
	public static void CreateGraph(Graph graph,int number,char[] nodes,int[][] weight)
	{
    
    
		for(int x=0;x<number;x++)
		{
    
    
			graph.nodes[x]=nodes[x];
			for(int y=0;y<number;y++)
			{
    
    
				graph.weight[x][y]=weight[x][y];
			}
		}
	}
	public static void show(Graph graph)
	{
    
    
		for(int[] temp:graph.weight)
		{
    
    
			System.out.println(Arrays.toString(temp));
		}
	}
}
/*
 * 首先创建图对象,包含图的节点个数的number
 * 保存每一个节点的数组nodes,保存边的权重的邻接矩阵weight
 */
class Graph
{
    
    
	int number;
	char[] nodes;
	int[][] weight;
	public Graph(int number)
	{
    
    
		this.number = number;
		this.nodes=new char[number];
		this.weight=new int[number][number];
	}
	
}

Guess you like

Origin blog.csdn.net/qq_43416157/article/details/108740222