Java学习第38天:Dijkstra 算法与 Prim 算法

prim算法是最小生成树算法,它运用的是贪心原理,设置两个点集合,一个集合为要求的生成树的点集合A,另一个集合为未加入生成树的点B。

它的具体实现过程是:

 (1):所有的点都在集合B中,A集合为空。

 (2):任意以一个点为开始,把这个初始点加入集合A中,从集合B中减去这个点。寻找与它相邻的点中路径最短的点,如后把这个点也加入集合A中,从集合B中减去这个点。

 (3):更新未被访问的节点的dist[]值。

 (4):重复上述过程。一直到所有的点都在A集合中结束。
Dijkstra是计算最短路径的算法

(1)初始时,S只包含源点v,即S=v。U包含除v外的其他顶点,U中顶点u距离为边上的权(若v与u有边)或(若u不是v的出边邻接点)。

(2)从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。

(3)以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u(u U)的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。

(4)重复步骤(2)和(3)直到所有顶点都包含在S中
代码如下:

package day38;
import java.util.Arrays;

import day31.IntMatrix;
public class Net {
	//最大距离
    public static final int MAX_DISTANCE = 10000;

    //节点数量
    int numNodes;

    IntMatrix weightMatrix;

    /**
     * @Description: 构造函数
     * @Param: [paraNumNodes]
     * @return:
     */
    public Net(int paraNumNodes) {
        numNodes = paraNumNodes;
        weightMatrix = new IntMatrix(numNodes, numNodes);
        for (int i = 0; i < numNodes; i++) {
            //将所有权值先设为最大距离
            Arrays.fill(weightMatrix.getData()[i], MAX_DISTANCE);
        }
    }

    /**
     * @Description: 构造函数
     * @Param: [paraMatrix]
     * @return:
     */
    public Net(int[][] paraMatrix) {
        weightMatrix = new IntMatrix(paraMatrix);
        numNodes = weightMatrix.getRows();
    }

    @Override
    public String toString() {
        String resultString = "This is the weight matrix of the graph.\r\n" + weightMatrix;
        return resultString;
    }

    /**
     * @Description: 单源最短路径
     * @Param: [paraSource(目标节点到每个节点的最短路径)]
     * @return: int[]
     */
    public int[] shortestPath(int paraSource) {
        //初始化
        int[] tpDistanceArray = new int[numNodes];
        for (int i = 0; i < numNodes; i++) {
            tpDistanceArray[i] = weightMatrix.getValue(paraSource, i);
        }

        int[] tpParentArray = new int[numNodes];
        Arrays.fill(tpParentArray, paraSource);
        // -1 视为无父节点
        tpParentArray[paraSource] = -1;

        //已被访问的节点
        boolean[] tpVistedArray = new boolean[numNodes];
        //表示自己直接跳过
        tpVistedArray[paraSource] = true;

        //循环找
        int tpMinDistance;
        int tpBestNode = -1;
        for (int i = 0; i < numNodes - 1; i++) {
            //找到最优的下一节点
            tpMinDistance = Integer.MAX_VALUE;
            for (int j = 0; j < numNodes; j++) {
                if (tpVistedArray[j]) {
                    continue;
                }

                //与每个节点作比较找到最优节点
                if (tpMinDistance > tpDistanceArray[j]) {
                    tpMinDistance = tpDistanceArray[j];
                    tpBestNode = j;
                }
            }

            tpVistedArray[tpBestNode] = true;

            for (int j = 0; j < numNodes; j++) {
                if (tpVistedArray[j]) {
                    continue;
                }

                //该情况为当前节点未连接到另一节点
                if (weightMatrix.getValue(tpBestNode, j) >= MAX_DISTANCE) {
                    continue;
                }

                if (tpDistanceArray[j] > tpDistanceArray[tpBestNode]
                        + weightMatrix.getValue(tpBestNode, j)) {
                    tpDistanceArray[j] = tpDistanceArray[tpBestNode]
                            + weightMatrix.getValue(tpBestNode, j);
                    //改变父节点
                    tpParentArray[j] = tpBestNode;
                }
            }

            //仅作测试
            System.out.println("The distance to each node: " + Arrays.toString(tpDistanceArray));
            System.out.println("The parent of each node: " + Arrays.toString(tpParentArray));

        }

        //输出
        System.out.println("Finally");
        System.out.println("The distance to each node: " + Arrays.toString(tpDistanceArray));
        System.out.println("The parent of each node: " + Arrays.toString(tpParentArray));
        return tpDistanceArray;
    }

    /**
     * @Description: 普利姆算法
     * @Param: []
     * @return: int
     */
    public int prim() {
        //初始化
        //任何节点都可以作为起始节点
        int tpSource = 0;
        int[] tpDistanceArray = new int[numNodes];
        for (int i = 0; i < numNodes; i++) {
            tpDistanceArray[i] = weightMatrix.getValue(tpSource, i);
        }

        int[] tpParentArray = new int[numNodes];
        Arrays.fill(tpParentArray, tpSource);

        tpParentArray[tpSource] = -1;

        boolean[] tpVisitedArray = new boolean[numNodes];
        tpVisitedArray[tpSource] = true;

        int tpMinDistance;
        int tpBestNode = -1;
        for (int i = 0; i < numNodes - 1; i++) {
            tpMinDistance = Integer.MAX_VALUE;
            for (int j = 0; j < numNodes; j++) {
                if (tpVisitedArray[j]) {
                    continue;
                }

                if (tpMinDistance > tpDistanceArray[j]) {
                    tpMinDistance = tpDistanceArray[j];
                    tpBestNode = j;
                }
            }

            tpVisitedArray[tpBestNode] = true;

            for (int j = 0; j < numNodes; j++) {
                if (tpVisitedArray[j]) {
                    continue;
                }

                //该情况为当前节点未连接到另一节点
                if (weightMatrix.getValue(tpBestNode, j) >= MAX_DISTANCE) {
                    continue;
                }

                if (tpDistanceArray[j] > weightMatrix.getValue(tpBestNode, j)) {
                    tpDistanceArray[j] = weightMatrix.getValue(tpBestNode, j);
                    //改变父节点
                    tpParentArray[j] = tpBestNode;
                }
            }
            System.out.println(
                    "The selected distance for each node: " + Arrays.toString(tpDistanceArray));
            System.out.println("The parent of each node: " + Arrays.toString(tpParentArray));
        }

        int resCost = 0;
        for (int i = 0; i < numNodes; i++) {
            resCost += tpDistanceArray[i];
        }

        System.out.println("Finally");
        System.out.println("The parent of each node: " + Arrays.toString(tpParentArray));
        System.out.println("The total cost: " + resCost);

        return resCost;
    }

    public static void main(String[] args) {
        Net tempNet = new Net(3);
        System.out.println(tempNet);

        int[][] tempMatrix = { { 0, 9, 3, 6 }, { 5, 0, 2, 4 }, { 3, 2, 0, 1 }, { 2, 8, 7, 0 } };
        tempNet = new Net(tempMatrix);
        System.out.println(tempNet);

        tempNet.shortestPath(1);

        tempNet.prim();
    }
}

运行结果:

This is the weight matrix of the graph.
[[10000, 10000, 10000], [10000, 10000, 10000], [10000, 10000, 10000]]
This is the weight matrix of the graph.
[[0, 9, 3, 6], [5, 0, 2, 4], [3, 2, 0, 1], [2, 8, 7, 0]]
The distance to each node: [5, 0, 2, 3]
The parent of each node: [1, -1, 1, 2]
The distance to each node: [5, 0, 2, 3]
The parent of each node: [1, -1, 1, 2]
The distance to each node: [5, 0, 2, 3]
The parent of each node: [1, -1, 1, 2]
Finally
The distance to each node: [5, 0, 2, 3]
The parent of each node: [1, -1, 1, 2]
The selected distance for each node: [0, 2, 3, 1]
The parent of each node: [-1, 2, 0, 2]
The selected distance for each node: [0, 2, 3, 1]
The parent of each node: [-1, 2, 0, 2]
The selected distance for each node: [0, 2, 3, 1]
The parent of each node: [-1, 2, 0, 2]
Finally
The parent of each node: [-1, 2, 0, 2]
The total cost: 6

注: 

1.Prim是计算最小生成树的算法,比如为N个村庄修路,怎么修花销最少。

 Dijkstra是计算最短路径的算法,比如从a村庄走到其他任意村庄的距离。

2:Prim算法中有一个统计总len的变量,每次都要把到下一点的距离加到len中;

    Dijkstra算法中却没有,只需要把到下一点的距离加到dist[]数组中即可;

3:Prim算法的更新操作更新的dist[]是已访问集合到未访问集合中各点的距离;

    Dijkstra算法的更新操作更新的dist[]是源点到未访问集合中各点的距离;
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值