Prim用Java查找最小生成树的算法
时间:2020-02-23 14:41:41 来源:igfitidea点击:
最小生成树又称最小权重生成树是连接的,边缘加权的无向图的边缘的子集。
该子集将所有顶点连接在一起,没有任何循环并且具有最小可能的总边权重。
一个图可以有多个以上的最小生成树。
但是,对于同一棵树的不同MST,总成本将是相同的。
Prim算法
Prim的算法是一种贪婪算法,可以找到加权无向图的MST。
该算法通过从任意起始顶点一次建立一个MST来进行。
在每个步骤中,它都是最经济高效的选择。
即,它局部优化以实现全局最优。
Prim算法的工作方式如下:
使用随机顶点(初始顶点)初始化最小生成树。
找到将树连接到新顶点的所有边,找到最小值,然后将其添加到树中(贪婪的选择)。
继续重复步骤2,直到得到最小的生成树(直到所有顶点都达到为止)。
我们可以看一个例子来了解Prim算法的工作原理。
令加权无向图如下:
我们选择0作为初始顶点。
下一步,我们从与MST连接的所有节点中选择最小值。
在随后的每个阶段,我们都找到将树连接到新顶点的最小成本边。
- 边缘:0-1
- 边缘:1-4
- 边缘:4-2
- 边缘:1-3
使用4条边线,我们已经连接了所有5个节点。
最小生成树的代价是所有边缘权重的总和。
在此示例中,它是:
4+1+6+2 = 13
Prim的算法Java代码
Java实现如下。
Graph类的代码:
package com.theitroad;
import java.util.*;
public class Graph
{
//Representation of the graph
private static int infinite = 9999999;
int[][] LinkCost; //graph matrix
int num_nodes; //number of nodes
//constructor takes in a matrix as its input
Graph(int[][] mat)
{
int i, j;
num_nodes = mat.length;
LinkCost = new int[num_nodes][num_nodes];
//copying the weights to LinkCost matrix
for ( i=0; i < num_nodes; i++)
{
for ( j=0; j < num_nodes; j++)
{
LinkCost[i][j] = mat[i][j];
if ( LinkCost[i][j] == 0 )
LinkCost[i][j] = infinite;
}
}
}
//function to get the nodes that are unreached
public int unReached(boolean[] r)
{
boolean done = true;
for ( int i = 0; i < r.length; i++ )
if ( r[i] == false )
return i;
return -1;
}
public void Prim( )
{
int i, j, k, x, y;
boolean[] Reached = new boolean[num_nodes]; //array to keep track of the reached nodes
int[] predNode = new int[num_nodes]; //array to maintain min cost edge
//starting vertex
Reached[0] = true;
//setting other vertices as unreached
for ( k = 1; k < num_nodes; k++ )
{
Reached[k] = false;
}
predNode[0] = 0; //No edge for node 0
printCoveredNodes( Reached );
//we iterate for n-1 nodes that haven't been reached yet
for (k = 1; k < num_nodes; k++)
{
x = y = 0;
for ( i = 0; i < num_nodes; i++ )
for ( j = 0; j < num_nodes; j++ )
{
//update the MST with the minimum cost Link
if ( Reached[i] && !Reached[j] &&
LinkCost[i][j] < LinkCost[x][y] )
{
x = i;
y = j;
}
}
System.out.println("Next selected edge: (" +
+ x + "," +
+ y + ")" +
" cost = " + LinkCost[x][y]);
predNode[y] = x; //add the min cost link to predNode
Reached[y] = true;
printCoveredNodes( Reached );
System.out.println();
}
printMinCostEdges( predNode );
}
//function to print the edges of spanning tree
void printMinCostEdges( int[] a )
{
System.out.println("Edges in MST: ");
for ( int i = 0; i < num_nodes; i++ )
System.out.println( a[i] + " --> " + i );
}
void printCoveredNodes(boolean[] Reached )
{
System.out.print("Covered Nodes = ");
for (int i = 0; i < Reached.length; i++ )
if ( Reached[i] )
System.out.print( i + " ");
System.out.println();
}
}
主类:
package com.theitroad;
public class Main {
public static void main(String[] args) {
int[][] conn = {{0, 4, 0, 0, 5},
{4, 0, 3, 6, 1},
{0, 3, 0, 6, 2},
{0, 6, 6, 0, 7},
{5, 1, 2, 7, 0},
};
Graph G = new Graph(conn);
G.Prim();
}
}

