图算法 - 最小生成树

149 阅读2分钟

将一个图中的所有的节点以最小的代价(权值)都连接在一起。

prim算法 从0节点开始,每次都选择代价最小的那一条路,直到结束。

public class GraphMain {
    public static void main(String[] args) {
        int vertexSize = 9;

        int[] vertexes = new int[9];
        for (int i = 0; i < vertexSize; i++) {
            vertexes[i] = i;
        }
        int[][] matrix = new int[vertexSize][vertexSize];
      
        // v0
        matrix[0][0] = 0;
        matrix[0][1] = 1;
        matrix[0][2] = 5;
        matrix[0][3] = MAX_WEIGHT;
        matrix[0][4] = MAX_WEIGHT;
        matrix[0][5] = MAX_WEIGHT;
        matrix[0][6] = MAX_WEIGHT;
        matrix[0][7] = MAX_WEIGHT;
        matrix[0][8] = MAX_WEIGHT;

        // v1
        matrix[1][0] = 1;
        matrix[1][1] = 0;
        matrix[1][2] = 3;
        matrix[1][3] = 7;
        matrix[1][4] = 5;
        matrix[1][5] = MAX_WEIGHT;
        matrix[1][6] = MAX_WEIGHT;
        matrix[1][7] = MAX_WEIGHT;
        matrix[1][8] = MAX_WEIGHT;

        // v2
        matrix[2][0] = 5;
        matrix[2][1] = 3;
        matrix[2][2] = 0;
        matrix[2][3] = MAX_WEIGHT;
        matrix[2][4] = 1;
        matrix[2][5] = 7;
        matrix[2][6] = MAX_WEIGHT;
        matrix[2][7] = MAX_WEIGHT;
        matrix[2][8] = MAX_WEIGHT;

        // v3
        matrix[3][0] = MAX_WEIGHT;
        matrix[3][1] = 7;
        matrix[3][2] = MAX_WEIGHT;
        matrix[3][3] = 0;
        matrix[3][4] = 2;
        matrix[3][5] = MAX_WEIGHT;
        matrix[3][6] = 1;
        matrix[3][7] = MAX_WEIGHT;
        matrix[3][8] = MAX_WEIGHT;

        // v4
        matrix[4][0] = MAX_WEIGHT;
        matrix[4][1] = 5;
        matrix[4][2] = 1;
        matrix[4][3] = 2;
        matrix[4][4] = 0;
        matrix[4][5] = 3;
        matrix[4][6] = 6;
        matrix[4][7] = 9;
        matrix[4][8] = MAX_WEIGHT;

        // v5
        matrix[5][0] = MAX_WEIGHT;
        matrix[5][1] = MAX_WEIGHT;
        matrix[5][2] = 7;
        matrix[5][3] = MAX_WEIGHT;
        matrix[5][4] = 3;
        matrix[5][5] = 0;
        matrix[5][6] = MAX_WEIGHT;
        matrix[5][7] = 5;
        matrix[5][8] = MAX_WEIGHT;

        // v6
        matrix[6][0] = MAX_WEIGHT;
        matrix[6][1] = MAX_WEIGHT;
        matrix[6][2] = MAX_WEIGHT;
        matrix[6][3] = 3;
        matrix[6][4] = 6;
        matrix[6][5] = MAX_WEIGHT;
        matrix[6][6] = 0;
        matrix[6][7] = 2;
        matrix[6][8] = 7;

        // v7
        matrix[7][0] = MAX_WEIGHT;
        matrix[7][1] = MAX_WEIGHT;
        matrix[7][2] = MAX_WEIGHT;
        matrix[7][3] = MAX_WEIGHT;
        matrix[7][4] = 9;
        matrix[7][5] = 5;
        matrix[7][6] = 2;
        matrix[7][7] = 0;
        matrix[7][8] = 4;

        // v8
        matrix[8][0] = MAX_WEIGHT;
        matrix[8][1] = MAX_WEIGHT;
        matrix[8][2] = MAX_WEIGHT;
        matrix[8][3] = MAX_WEIGHT;
        matrix[8][4] = MAX_WEIGHT;
        matrix[8][5] = MAX_WEIGHT;
        matrix[8][6] = 7;
        matrix[8][7] = 4;
        matrix[8][8] = 0;

        Graph graph = new Graph(vertexSize, vertexes, matrix);
        graph.prim2();
    }
}


    public void prim2() {
        // 用户保存当前节点的所有的路径
        int[] lowRow = new int[vertexSize];  
        // 从第一个节点开始,把第一个节点的所有的路径拷贝到lowRow中
        for (int i = 0; i < vertexSize; i++) { 
            lowRow[i] = matrix[0][i];
        }
        for (int i = 0; i < vertexSize; i++) {
            int lowId = 0;
            int low = MAX_WEIGHT;
            // 遍历当前节点的中的最小的带权路径的值,和走向的节点。
            for (int j = 1; j < vertexSize; j++) {
                if (lowRow[j] < low && lowRow[j] > 0) {
                    low = lowRow[j];
                    lowId = j;
                }
            }
            System.out.println(" 节点是: " + lowId + "   路径是:" +lowRow[lowId]);
            // 已经抵达该节点,那么就将这个节点值改为0 。也可以不操作。下方也会进行修改
            lowRow[lowId] = 0;
            // 遍历抵达的节点的所有路径,找到小于上个节点通往所有路径的值,进行覆盖。
            for (int j = 0; j < vertexSize; j++) {
                if (matrix[lowId][j] < lowRow[j] && lowRow[j] > 0) {
                    lowRow[j] = matrix[lowId][j];
                }
            }
        }
    }