最小生成树算法-Prim算法

来源:互联网 发布:amx m4 mle.54数据 编辑:程序博客网 时间:2024/06/16 04:43

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

0 0
原创粉丝点击