您的位置:首页 > 其它

最小生成树算法-Prim算法

2016-04-23 17:43 330 查看
MST(Minimum Spanning Tree,最小生成树)问题有两种通用的解法,Prim算法就是其中之一,它是从点的方面考虑构建一颗MST,大致思想是:设图G顶点集合为U,首先任意选择图G中的一点作为起始点a,将该点加入集合V,再从集合U-V中找到另一点b使得点b到V中任意一点的权值最小,此时将b点也加入集合V;以此类推,现在的集合V={a,b},再从集合U-V中找到另一点c使得点c到V中任意一点的权值最小,此时将c点加入集合V,直至所有顶点全部被加入V,此时就构建出了一颗MST。因为有N个顶点,所以该MST就有N-1条边,每一次向集合V中加入一个点,就意味着找到一条MST的边。



package com.gloomy.graph;

import java.util.ArrayList;
import java.util.List;

/**
* 最小生成树算法
* 与Dijkstra算法思路几乎完全一致
*
* @author 过路的守望
*
*/
public class PrimAlgorithm {

public static void main(String[] args) {

Vertex A = new Vertex("A");
Vertex B = new Vertex("B");
Vertex C = new Vertex("C");
Vertex D = new Vertex("D");
Vertex E = new Vertex("E");
Vertex F = new Vertex("F");
Vertex G = new Vertex("G");
A.getAdjacentList().add(B);
A.getAdjacentList().add(D);
A.getAdjacentList().add(C);
A.getAdjacentEdgesMap().put(B, 2);
A.getAdjacentEdgesMap().put(C, 4);
A.getAdjacentEdgesMap().put(D, 1);
B.getAdjacentList().add(E);
B.getAdjacentList().add(D);
B.getAdjacentList().add(A);
B.getAdjacentEdgesMap().put(A, 2);
B.getAdjacentEdgesMap().put(D, 3);
B.getAdjacentEdgesMap().put(E, 10);
C.getAdjacentList().add(A);
C.getAdjacentList().add(D);
C.getAdjacentList().add(F);
C.getAdjacentEdgesMap().put(A, 4);
C.getAdjacentEdgesMap().put(D, 2);
C.getAdjacentEdgesMap().put(F, 5);
D.getAdjacentList().add(A);
D.getAdjacentList().add(B);
D.getAdjacentList().add(C);
D.getAdjacentList().add(E);
D.getAdjacentList().add(F);
D.getAdjacentList().add(G);
D.getAdjacentEdgesMap().put(A, 1);
D.getAdjacentEdgesMap().put(B, 3);
D.getAdjacentEdgesMap().put(C, 2);
D.getAdjacentEdgesMap().put(E, 7);
D.getAdjacentEdgesMap().put(F, 8);
D.getAdjacentEdgesMap().put(G, 4);
E.getAdjacentList().add(B);
E.getAdjacentList().add(D);
E.getAdjacentList().add(G);
E.getAdjacentEdgesMap().put(B, 10);
E.getAdjacentEdgesMap().put(D, 7);
E.getAdjacentEdgesMap().put(G, 6);
F.getAdjacentList().add(C);
F.getAdjacentList().add(D);
F.getAdjacentList().add(G);
F.getAdjacentEdgesMap().put(C, 5);
F.getAdjacentEdgesMap().put(D, 8);
F.getAdjacentEdgesMap().put(G, 1);
G.getAdjacentList().add(F);
G.getAdjacentList().add(D);
G.getAdjacentList().add(E);
G.getAdjacentEdgesMap().put(F, 1);
G.getAdjacentEdgesMap().put(E, 6);
G.getAdjacentEdgesMap().put(D, 4);
List<Vertex> vertexs = new ArrayList<Vertex>();
vertexs.add(A);
vertexs.add(B);
vertexs.add(C);
vertexs.add(D);
vertexs.add(E);
vertexs.add(F);
vertexs.add(G);
PrimAlgorithm prim = new PrimAlgorithm();
prim.primTree(A, vertexs);
}

/**
*
* @param vertex
*            指定的根
* @param vertexs
*            顶点的集合
*/
public void primTree(Vertex vertex, List<Vertex> vertexs) {
Vertex curVertex = vertex;
vertex.setDist(0);
while (true) {
/*
* 已经处理完所有顶点
*/
if (curVertex == null) {
break;
}
curVertex.setVisited(true);
for (Vertex adjaVertex : curVertex.getAdjacentList()) {
/*
* 若adjacent顶点未处理
* 且d[w]=min(d[w],C(w,v))变小
* 更新此顶点
*/
if (!adjaVertex.isVisited()) {
if (adjaVertex.getDist() > curVertex.getAdjacentEdgesMap()
.get(adjaVertex)) {
adjaVertex.setDist(curVertex.getAdjacentEdgesMap().get(
adjaVertex));
adjaVertex.setPreVertex(curVertex);
}
}

}
/*
* 从未访问顶点中寻找下一个顶点
*/
curVertex = getShortestVertex(vertexs);

}
int length = 0;
for (Vertex vertex2 : vertexs) {
length += vertex2.getDist();
}
System.out.println("权值和:"+length);
}

/**
* 从未访问顶点中寻找最短边
* 可用二叉堆优化
* @param vertexs
* @return
*/
public Vertex getShortestVertex(List<Vertex> vertexs) {
int min = Integer.MAX_VALUE;
/*
* 最短边
*/
Vertex minVertex = null;
for (Vertex vertex : vertexs) {
if (!vertex.isVisited()) {
if (vertex.getDist() < min) {
min = vertex.getDist();
minVertex = vertex;
}
}
}
return minVertex;
}

}


权值和:16
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: