日撸java_day38

文章展示了如何在Java中实现Dijkstra算法用于找到图中源节点到所有节点的最短路径,以及Prim算法来构建最小生成树。代码包括图的权重矩阵初始化、两个主要算法的步骤以及调试输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第 38 天: Dijkstra 算法与 Prim 算法

这两个图的算法当初学数据结构时候感觉遥不可及,现在自己跑一遍发现好像也还行,能写

package datastructures.graph;

import matrix.IntMatrix;

import java.util.Arrays;

/**
 * ClassName: Net
 * Package: datastructures.graph
 * Description: Weighted graphs are called nets.
 *
 * @Author: luv_x_c
 * @Create: 2023/5/29 9:28
 */
public class Net {
    /**
     * The maximal distance.
     */
    public static final int MAX_DISTANCE = 10000;

    /**
     * The number of nodes.
     */
    int numNodes;

    /**
     * The weight matrix.
     */
    IntMatrix weightMatrix;

    /**
     * The first constructor.
     *
     * @param paraNumNodes The number of nodes in the graph.
     */
    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);
        }// Of for i
    }//Of the first constructor

    /**
     * The second constructor
     *
     * @param paraMatrix The data matrix.
     */
    public Net(int[][] paraMatrix) {
        weightMatrix = new IntMatrix(paraMatrix);
        numNodes = weightMatrix.gerRows();
    }// Of the second constructor

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

    /**
     * Dijkstra algorithm: shortest path from the source to all nodes.
     *
     * @param paraSource The source node.
     * @return The distance array.
     */
    public int[] dijkstra(int paraSource) {
        // Step1. Initialize.
        int[] tempDistanceArray = new int[numNodes];
        for (int i = 0; i < numNodes; i++) {
            tempDistanceArray[i] = weightMatrix.getData()[paraSource][i];
        }// Of for i

        int[] tempParentArray = new int[numNodes];
        Arrays.fill(tempParentArray, paraSource);
        // -1 for no parent
        tempParentArray[paraSource] = -1;

        // Visited nodes will not be considered further.
        boolean[] tempVisitedArray = new boolean[numNodes];
        tempVisitedArray[paraSource] = true;

        // Step2. Main loops.
        int tempMinDistance;
        int tempBestNode = -1;
        for (int i = 0; i < numNodes - 1; i++) {
            // Step2.1 find the best next node.
            tempMinDistance = Integer.MAX_VALUE;
            for (int j = 0; j < numNodes; j++) {
                //This node is visited.
                if (tempVisitedArray[j]) {
                    continue;
                }// Of if

                if (tempMinDistance > tempDistanceArray[j]) {
                    tempMinDistance = tempDistanceArray[j];
                    tempBestNode = j;
                }// Of if
            }// Of for j

            tempVisitedArray[tempBestNode] = true;

            // Step2.2 Prepare for the next round.
            for (int j = 0; j < numNodes; j++) {
                // This node is visited.
                if (tempVisitedArray[j]) {
                    continue;
                }// Of if

                // This node cannot reach.
                if (weightMatrix.getData()[tempBestNode][j] >= MAX_DISTANCE) {
                    continue;
                }// Of if

                if (tempDistanceArray[j] > tempDistanceArray[tempBestNode] + weightMatrix.getData()[tempBestNode][j]) {
                    // Change distance.
                    tempDistanceArray[j] = tempDistanceArray[tempBestNode] + weightMatrix.getValue(tempBestNode, j);

                    // Change parent.
                    tempParentArray[j] = tempBestNode;
                }// Of if
            }// Of for j

            // For test
            System.out.println("The distance to each node :" + Arrays.toString(tempDistanceArray));
            System.out.println("The parent of each node :" + Arrays.toString(tempParentArray));
        }//Of for i

        // Step3. Output for debug.
        System.out.println("Finally");
        System.out.println("The distance to each node :" + Arrays.toString(tempDistanceArray));
        System.out.println("The parent of each node :" + Arrays.toString(tempParentArray));
        return tempDistanceArray;
    }// Of dijkstra

    /**
     * The minimal spanning tree.
     *
     * @return The total cost of the tree.
     */
    public int prim() {
        // Step1. Initialize.
        // Any node can be the source.
        int tempSource = 0;
        int[] tempDistanceArray = new int[numNodes];
        for (int i = 0; i < numNodes; i++) {
            tempDistanceArray[i] = weightMatrix.getValue(tempSource, i);
        }// Of for i

        int[] tempParentArray = new int[numNodes];
        Arrays.fill(tempParentArray, tempSource);
        //-1 for no parent.
        tempParentArray[tempSource] = -1;

        // Visited nodes will not be considered further.
        boolean[] tempVisitedArray = new boolean[numNodes];
        tempVisitedArray[tempSource] = true;

        //Step2. Main loops.
        int tempMinDistance;
        int tempBestNode = -1;
        for (int i = 0; i < numNodes - 1; i++) {
            // Step2.1 find the best next node.
            tempMinDistance = Integer.MAX_VALUE;
            for (int j = 0; j < numNodes; j++) {
                //This node is visited.
                if (tempVisitedArray[j]) {
                    continue;
                }// Of if

                if (tempMinDistance > tempDistanceArray[j]) {
                    tempMinDistance = tempDistanceArray[j];
                    tempBestNode = j;
                }// Of if
            }// Of for j

            tempVisitedArray[tempBestNode] = true;

            // Step2.2 Prepare for the next round.
            for (int j = 0; j < numNodes; j++) {
                // This node is visited.
                if (tempVisitedArray[j]) {
                    continue;
                }// Of if

                // This node cannot reach.
                if (weightMatrix.getData()[tempBestNode][j] >= MAX_DISTANCE) {
                    continue;
                }// Of if

                if (tempDistanceArray[j] > weightMatrix.getData()[tempBestNode][j]) {
                    // Change distance.
                    tempDistanceArray[j] = weightMatrix.getValue(tempBestNode, j);

                    // Change parent.
                    tempParentArray[j] = tempBestNode;
                }// Of if
            }// Of for j

            // For test
            System.out.println("The selected distance for each node: " + Arrays.toString(tempDistanceArray));
            System.out.println("The parent of each node: " + Arrays.toString(tempParentArray));
        }//Of for i

        int resultCost = 0;
        for (int i = 0; i < numNodes; i++) {
            resultCost += tempDistanceArray[i];
        }// Of for i

        // Step3. Output for debug.
        System.out.println("Finally");
        System.out.println("The parent of each node :" + Arrays.toString(tempParentArray));
        System.out.println("The total cost :" + resultCost);

        return resultCost;
    }// Of prim

    /**
     * The entrance of the program.
     *
     * @param args Not used now.
     */
    public static void main(String[] args) {
        Net tempNet0 = new Net(3);
        System.out.println(tempNet0);

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

        // Dijkstra
        tempNet1.dijkstra(0);

        // An undirected net is required.
        int[][] tempMatrix2 = {{0, 7, MAX_DISTANCE, 5, MAX_DISTANCE}, {7, 0, 8, 9, 7},
                {MAX_DISTANCE, 8, 0, MAX_DISTANCE, 5}, {5, 9, MAX_DISTANCE, 0, 15},
                {MAX_DISTANCE, 7, 5, 15, 0}};
        Net tempNet2 = new Net(tempMatrix2);
        tempNet2.prim();
    }// Of main
}// Of class Net

 第一遍初始化最小路径的中间变量时候赋值成了MIN_VALUE,prim里面粘贴也是这个,直接异常中断了,还是得细心点,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值