Java-Prim最小生成树算法
Prim算法是一种用于寻找加权无向连通图的最小生成树的算法。该算法从图的任意一个顶点开始,每次选择与当前生成树距离最短的顶点加入生成树,直到所有顶点都加入生成树为止。
最小生成树的前提是该图是一个无环图和连通图
算法介绍
Prim算法的基本思想是分治策略,即将一个大的问题拆分成几个小问题来解决。在寻找最小生成树的过程中,Prim算法会维护两个集合:一个是已经加入生成树的顶点集合(设为U
),另一个是还未加入生成树的顶点集合(设为V-U
)。算法开始时,任选一个顶点加入U
,然后不断从V-U
中选择与U
中顶点相连且权重最小的边,将该边的另一个顶点加入U
,直到U
包含所有顶点为止。
代码
public class Graph {
/**
* 结点集合
*/
private List<String> node;
/**
* true 有向图
* false 无向图
*/
private boolean isDigraph;
/**
* 邻接矩阵
*/
private final int[][] matrix;
/**
* 最小生成树
* @param x 从编号为x的结点开始
* @return 最小生成树的邻接矩阵
*/
public int[][] primSpanningTree(int x) {
// 最小生成树矩阵
int[][] matrixT = new int[node.size()][node.size()];
// 集合 U
List<Integer> feasibleNodeList = new ArrayList<>(Collections.singletonList(x - 1));
// 集合 V
List<FeasibleEdge> feasibleEdgeList = new ArrayList<>();
for (int i = 0; i < matrix[x - 1].length; i++) {
if (matrix[x - 1][i] != 0) {
feasibleEdgeList.add(new FeasibleEdge(x - 1, i, matrix[x - 1][i]));
}
}
int count = 0;
while (feasibleNodeList.size() != node.size()) {
feasibleEdgeList.sort((o1, o2) -> o1.weight - o2.weight);
// 最小边
FeasibleEdge minEdge = feasibleEdgeList.get(0);
matrixT[minEdge.stat][minEdge.end] = minEdge.weight;
matrixT[minEdge.end][minEdge.stat] = minEdge.weight;
count += minEdge.weight;
// 将终点结点收入结点集合U中
feasibleNodeList.add(minEdge.end);
// 删除V集合中 end编号在U集合中出现的结点
feasibleEdgeList.removeIf(feasibleEdge -> feasibleNodeList.contains(feasibleEdge.end));
// 寻找可能的边
for (int i = 0; i < feasibleNodeList.size(); i++) {
// 当前节点的编号
Integer currentNodeSno = feasibleNodeList.get(i);
for (int j = 0; j < matrix[currentNodeSno].length; j++) {
FeasibleEdge newEdge =
new FeasibleEdge(currentNodeSno, j, matrix[currentNodeSno][j]);
if (matrix[currentNodeSno][j] != 0 && !feasibleEdgeList.contains(newEdge)) {
// 可行的边 且这个终点没有到达过
if (!feasibleNodeList.contains(j)) {
feasibleEdgeList.add(newEdge);
}
}
}
}
}
System.out.println("该最小生成树的权重为: " + count);
System.out.println("以下为该最小生成树的连接表:");
return matrixT;
}
}
## 结果
该最小生成树的权重为: 16
以下为该最小生成树的连接表:
[0, 2, 0, 1, 0, 0, 0]
[2, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 2, 0, 0, 0]
[1, 0, 2, 0, 0, 0, 4]
[0, 0, 0, 0, 0, 0, 6]
[0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 4, 6, 1, 0]