Prim算法求解最小生成树的Java实现

来源:互联网 发布:如何当网络写手 编辑:程序博客网 时间:2024/06/14 23:36

上一篇既然提到了Krusal算法,这里就不得不说Prim算法了,这两个算法都是求解最小生成树的经典的贪婪算法。与Krusal算法不同的是,Prim算法在求解过程中始终保持临时结果是一颗联通的树。该算法的伪代码如下

//假设网络中至少有一个个顶点设T为所选边的集合,初始化T为空设 TV为已在树中的顶点的集合,置TV={1}令E为网络中的边的集合while(E不为空,并且T 中的边数不等于n-1){//这里n指原图中顶点个数令(u,v)为最小代价的边,其中u属于TV,v不属于TVif(没有这种边)breakE=E-{(u,v)}在T中加入边(u,v) }if(|T|==n-1)T是一颗最小生成树else没有最小生成树


下图是有一个Prim 算法求解最小生成树的过程的一个例子



以下是用Java代码点的实现

package Prim;/** * 边 * @author sdu20 * */public class Edge {private int v1;private int v2;private int weight;/** * 为查找最小边专门所设 * @param weight */public Edge(int weight){this.v1 = -1;this.v2 = -1;this.weight = weight;}public Edge(int v1,int v2,int weight){this.v1 = v1;this.v2 = v2;this.weight = weight;}public int getV1(){return v1;}public int getV2(){return v2;}public int getWeight(){return weight;}public String toString(){String str = "[ "+v1+" , "+v2+" , "+weight+" ]";return str;}public boolean equals(Edge edge){boolean equal = this.v1==edge.getV1() && this.v2==edge.getV2() && this.weight==edge.getWeight()|| this.v1==edge.getV2() && this.v2==edge.getV1() && this.weight==edge.getWeight();return equal;}}


package Prim;import java.util.*;public class Graph {private int vNum;private int edgeNum;private LinkedList<Edge>[] edgeLinks;private LinkedList<Integer> TV;//已在树中的顶点集private LinkedList<Edge> T;//入选的边集public Graph(int vNum){this.vNum = vNum;this.edgeNum = 0;edgeLinks = new LinkedList[vNum];for(int i = 0;i<vNum;i++){edgeLinks[i] = new LinkedList<>();}}public void insertEdge(Edge edge){int v1 = edge.getV1();int v2 = edge.getV2();edgeLinks[v1].add(edge);Edge edge2 = new Edge(v2,v1,edge.getWeight());edgeLinks[v2].add(edge2);edgeNum++;}public void deleteEdge(Edge edge){int v1 = edge.getV1();int v2 = edge.getV2();Edge edge2 = new Edge(v2,v1,edge.getWeight());edgeLinks[v1].remove(edge);edgeLinks[v2].remove(edge2);edgeNum--;}public void bianli(){System.out.println("共有 "+vNum+" 个顶点, "+edgeNum+" 条边。");for(int i = 0;i<vNum;i++){LinkedList<Edge> list = (LinkedList<Edge>) edgeLinks[i].clone();System.out.print(i+" : [");while(!list.isEmpty()){Edge edge = list.pop();System.out.print(edge.getV2()+"("+edge.getWeight()+")"+"  ");}System.out.println("]");}}/** * Prim算法实现 */public void Prim(){TV = new LinkedList<>();T = new LinkedList<>();TV.add(0);while(edgeNum>0 && T.size()!=vNum-1){Edge edge = getMinEdge(TV);if(edge==null)break;this.deleteEdge(edge);T.add(edge);TV.add(edge.getV2());}if(T.size()==vNum-1){System.out.println("求最小生成树成功");LinkedList<Edge> list = (LinkedList<Edge>) T.clone();int sumWeight = 0;while(!list.isEmpty()){Edge edge = list.pop();sumWeight += edge.getWeight();System.out.println(edge.toString());}System.out.println("总的权重为: "+sumWeight);}else{System.out.println("无最小生成树");}}public Edge getMinEdge(LinkedList<Integer> t){Edge minEdge = new Edge(10000);LinkedList<Integer> tt = (LinkedList<Integer>) t.clone();while(!tt.isEmpty()){int i = tt.pop();LinkedList<Edge> list = (LinkedList<Edge>) edgeLinks[i].clone();while(!list.isEmpty()){Edge edge = list.pop();if(minEdge.getWeight()>edge.getWeight() && !t.contains(edge.getV2())){minEdge = edge;}}}if(minEdge.getWeight()==10000)return null;return minEdge;}}


package Prim;public class Main {public static void main(String[] args) {// TODO Auto-generated method stubbookGraph();//randomGraph();}public static void bookGraph(){Graph graph = new Graph(9);Edge[] edges = new Edge[14];edges[0] = new Edge(0,1,4);edges[1] = new Edge(0,7,8);edges[2] = new Edge(1,2,8);edges[3] = new Edge(1,7,11);edges[4] = new Edge(2,3,7);edges[5] = new Edge(2,5,4);edges[6] = new Edge(2,8,2);edges[7] = new Edge(3,4,9);edges[8] = new Edge(3,5,14);edges[9] = new Edge(4,5,10);edges[10] = new Edge(5,6,2);edges[11] = new Edge(6,7,1);edges[12] = new Edge(6,8,6);edges[13] = new Edge(7,8,7);for(int i = 0;i<14;i++){graph.insertEdge(edges[i]);}graph.bianli();graph.Prim();}/** * 100个点,1000条边,权重为1~100的随机数 */public static void randomGraph(){Graph graph = new Graph(100);for(int i = 0;i<1000;){int preV = (int)(Math.random()*100);            int folV = (int)(Math.random()*100);            int weight = (int)(Math.random()*100+1);            if(preV != folV){            Edge edge = new Edge(preV,folV,weight);            try{            graph.insertEdge(edge);            i++;            }catch(Exception e){            continue;            }            }}graph.bianli();graph.Prim();}}


运行截图如下所示


阅读全文
1 0
原创粉丝点击