最小生成树-Prim算法

Prim算法

1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:U = {x},其中x为集合V中的任一节点(起始点),E = {}为空;
3).重复下列操作,直到U = V:
a.在集合E中选取权值最小的边 <u, v>,其中u为集合U中的元 素,而v不在U集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合U中,将<u, v>边加入集合E中;
4).输出:使用集合U和E来描述所得到的最小生成树。

算法简单实现

/**
 * Created by 默默 on 2018/3/22.
 */

public class Graph {

    public static int INF = Integer.MAX_VALUE;

    /**
     *     (v0)-2-(v1)
     *    /  \     /  \
     *   4    1   3   10
     *  /      \ /     \
     * (v2)-2- (v3)-7- (v4)
     *  \      /  \     /
     *  5    8     4  6
     *   \  /      \ /
     *   (v5) -1- (v6)
     */

    @org.junit.Test
    public void testPrim() {
        int[][] adj = {
                {0, 2, 4, 1, INF, INF, INF},
                {2, 0, INF, 3, 10, INF, INF},
                {4, INF, 0, 2, INF, 5, INF},
                {1, 3, 2, 0, 7, 8, 4},
                {INF, 10, INF, 7, 0, INF, 6},
                {INF, INF, 5, 8, INF, 0, 1},
                {INF, INF, INF, 4, 6, 1, 0},
        };
        System.out.println("总长=" + prim(adj));

        /**     (v0)-2-(v1)
         *        \     
         *         1    
         *          \    
         * (v2)-2- (v3)    (v4)
         *            \    /
         *             4  6 
         *             \ /
         *   (v5) -1- (v6)    
         */
    }


    public int prim(int[][] adjMatrix) {
        //节点数
        int count = adjMatrix[0].length;
        //初始节点定为0
        int cur = 0;

        //dist[index]表示 节点index 到 集合U 的最小距离
        int[] dist = new int[count];

        //集合U初始化只包含初始节点
        for (int i = 0; i < count; i++) {
            dist[i] = adjMatrix[cur][i];
        }
        boolean[] visit = new boolean[count];
        visit[cur] = true;
        System.out.println("vertex->" + cur);
        int sum = 0;
        for (int i = 1; i < count; i++) {//找节点的次数
            int nearBy = 0;
            int dis = INF;
            //每次找距 集合U 距离最短的未访问节点
            for (int j = 0; j < count; j++) {
                if (!visit[j] && dist[j] < dis) {
                    nearBy = j;
                    dis = dist[j];
                }
            }
            sum += dis;
            visit[nearBy] = true;
            System.out.println("vertex->" + nearBy);
            //更新其他未访问节点到集合U的距离(集合U增加了nearBy节点)
            for (int j = 0; j < count; j++) {
                if (!visit[j] && dist[j] > adjMatrix[nearBy][j]) {
                    dist[j] = adjMatrix[nearBy][j];
                }
            }
        }
        return sum;
    }
}

猜你喜欢

转载自blog.csdn.net/momo_ibeike/article/details/79655965
今日推荐