日撸 Java 三百行day38

这篇具有很好参考价值的文章主要介绍了日撸 Java 三百行day38。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

说明

闵老师的文章链接: 日撸 Java 三百行(总述)_minfanphd的博客-CSDN博客
自己也把手敲的代码放在了github上维护:https://github.com/fulisha-ok/sampledata

day38

1.Dijkstra 算法思路分析

日撸 Java 三百行day38
假设以顶点0出发
(1)0到各个顶点距离为:<0,1> 6;<0,2> 2 ;<0,3> ∞;选取最小距离<0,2> 2

(2)加入<0,2>一条边,看0到剩余顶点距离:

    <0,1>: 原<0,1> 6,在加入<0,2>,则可以借助<0,2>,<0,2><2,1> 5;选取最小距离5

   <0,3>:原<0,3> ∞,在加入<0,2>,<0,2><2,3> 7;选取最小距离7 

比较5和7选取最小的距离5 0->1: 5

(3)加入<0,2><2,1>边,看0到剩余顶点的距离

   <0,3>:原<0,2><2,3> 7,在加入<2,1>,<0,2><2,1><1,3>7;  选取最小距离<0,2><2,3> 7

节点遍历完,找到0到各点最短距离 0->3: 7

在这个过程中进一步思考:

在实现这个过程中需要借助一些数组来存储数据:
开始顶点到每一个顶点的最短距离需要有一个数组来存储,并且在每循环一次都需要检查这个数组是否需要更新
开始顶点到某个顶点不一定是直连路径,则需要存储开始顶点到某个顶点的路径,则也需要一个数组来存储路径。
顶点是否已经确定为最短路径结点,需要一个数组来做一个标志。

2.Prim 算法思路分析

prim算法为最小生成树,过程:任意选一个顶点(如选0顶点)

从0顶点到与之相连的结点之间距离最短的顶点,图中为2

在0,2结点中选择距离最短的结点,则为 1 节点

在0,1,2结点中选择距离最短的结点,则为3节点

当结点树n = 边树n-1即构建成功
日撸 Java 三百行day38

3.对比

Dijkstra 算法是求单源最短路径,可以算出开始顶点到其他顶点的最短路径,但是如果权重有负数,则dijstra并不能计算出正确的结果。而prim算法是构建最小生成树的一种策略。

Dijkstra 求单源最短路径时,我们要给定一个顶点,去找到其他结点的最短路径,而最小生成树是任意选择一个顶点开始。

Dijkstra 算法适用于有向图,而Prim更适合无向图(我认为主要是有向图在两个节点来回可能权重不同)

4.代码

  • 在dijkstra中主要分为三个for循环,一个大的for循环:一次循环就可以确定从v0顶点到某个顶点的最短路径,在大循环中的第一个循环是找出v0结点到剩余未访问结点中的最短路径,第三个循环是:已经确定某个顶点是最短路径,去更新tempDistanceArray,tempParentArray这两个数组。
 public int[] dijikstra(int paraSource) {
        // Step 1. Initialize.
        int[] tempDistanceArray = new int[numNodes];
        for (int i = 0; i < numNodes; i++) {
            tempDistanceArray[i] = weightMatrix.getValue(paraSource, 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;

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

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

            tempVisitedArray[tempBestNode] = true;

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

                // This node cannot be reached.
                if (weightMatrix.getValue(tempBestNode, j) >= MAX_DISTANCE) {
                    continue;
                }

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

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

        // Step 3. 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;
    }
  • 在prim算法中,与dijkstra算法最大的区别在与第三个循环中,在更新tempDistanceArray是累加之前的边,而在prim算法中则不需要累加,只需要判断从这个已选结点出发到其他结点的距离是否需要更新
public int prim() {
        // Step 1. 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);
        }

        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;

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

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

            tempVisitedArray[tempBestNode] = true;

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

                // This node cannot be reached.
                if (weightMatrix.getValue(tempBestNode, j) >= MAX_DISTANCE) {
                    continue;
                }

                // Attention: the difference from the Dijkstra algorithm.
                if (tempDistanceArray[j] > weightMatrix.getValue(tempBestNode, j)) {
                    // Change the distance.
                    tempDistanceArray[j] = weightMatrix.getValue(tempBestNode, j);
                    // Change the parent.
                    tempParentArray[j] = tempBestNode;
                }
            }

            // 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));
        }

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

        // Step 3. 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;
    }
  • 单元测试
    日撸 Java 三百行day38

  • dijkstra算法(从顶点0出发)
    日撸 Java 三百行day38

  • prim算法
    日撸 Java 三百行day38文章来源地址https://www.toymoban.com/news/detail-463481.html

到了这里,关于日撸 Java 三百行day38的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • day38打卡

    day38打卡 509. 斐波那契数 状态表示: ​ 第i个数的斐波那契数是dp[i] 状态转移方程 ​ 见题目: dp[i] = dp[i-1] + dp[i-2] 初始化 ​ 见题目, dp[0] = 0,dp[1] = 1 ,本题用两个变量代替即可。 填表顺序 ​ 从左到右 返回值 ​ dp[i] 70. 爬楼梯 状态表示: ​ 爬到第i层,一共用dp[i]种方法

    2024年02月22日
    浏览(30)
  • 算法记录 | Day38 动态规划

    对于动态规划问题,将拆解为如下五步曲 确定dp数组(dp table)以及下标的含义 确定递推公式 dp数组如何初始化 确定遍历顺序 举例推导dp数组 思路: 确定dp数组(dp table)以及下标的含义:dp[i]的定义为:第i个数的斐波那契数值是dp[i] 确定递推公式:状态转移方程 dp[i] = dp

    2023年04月22日
    浏览(44)
  • kettle开发篇-更新-Day38

    目录 前言: 一、更新组件介绍 1.1界面 1.2废话介绍 1.3重点解释 二、应用案例 2.1转换效果 2.2转换简介 三、总结         前面我们通过oracle的索引来处理单表超1亿的数据量表的查询问题,通过针对主键,展示的维度做多套索引,来提高查询和展现速度。通过在数据源增加索

    2024年02月04日
    浏览(34)
  • day38|动态规划-爬楼梯问题

    动态规划比较重要的是找到前后两个状态之间的联系,在向后遍历的过程中注意遍历的顺序和初始化操作。 动归基础类问题 背包问题 打家劫舍 股票问题 子序列问题 动态规划类的问题代码都是比较简洁的,按照dp打印逻辑观察打印出来的数值。 dp数组以及下标的含义dp[i][j

    2024年02月07日
    浏览(44)
  • 【linux】:老师问什么是爱情,我说了句:软硬链接和动静态库

        文章目录 前言 一、软硬链接 二、动态库和静态库 总结   上一篇文章的最后我们讲解了文件的inode,那么文件名和inode有什么区别呢?区别就在于linux系统只认inode号,文件的inode属性中,并不存在文件名,而文件名其实是给用户用的。我们以前讲过linux文件目录,那么目

    2023年04月19日
    浏览(132)
  • java黑马头条 day5自媒体文章审核 敏感词过滤算法DFA 集成RabbitMQ实现自动审核

      做为内容类产品,内容安全非常重要,所以需要进行对自媒体用户发布的文章进行审核以后才能到app端展示给用户。2 WmNews 中 status 代表自媒体文章的状态 status字段:0 草稿 1 待审核 2 审核失败 3 人工审核 4 人工审核通过   8 审核通过(待发布) 9 已发布 当自媒体用户提交

    2024年02月06日
    浏览(41)
  • 算法练习 Day38 | LeetCode509,70,746

    先导知识: 1、动态规划常见题型 动态规划基础问题 背包问题 打家劫舍 股票问题 子序列问题 2、动态规划五部曲 (1)确定dp数组的定义及下标的含义 (2)确定递推公式 (3)dp数组如何初始化 (4)遍历顺序 (5)打印dp数组 LeetCode509:509. 斐波那契数 题目描述: 斐波那契

    2024年02月21日
    浏览(41)
  • 【算法日志】动态规划刷题:01背包问题,多重背包问题(day37,day38)

    目录 前言 目标和(01背包) 一和零(01背包) 零钱兑换(多重背包) 排列总和(多重背包) 这两天都是背包问题,其中的01背包的一些应用问题需要一定的数学建模能力,需要i将实际问题简化成我们熟悉的背包问题;而这两天的多重背包问题还算比较基础,但也要我明白了

    2024年02月11日
    浏览(56)
  • kettle开发-Day38-其实chatGPT一直在身边

    最近chatGPT火出圈,其实不是chatGPT多智能,只是它用了一种新的交互方式来组织我们现有的知识,然后通过“高智商”的表达来使我们惊艳。但是目前或者未来的人工智能缺少创造力,他们只会整合信息目的是提高我们的效率。现在好多人不是说,ChatGPT可以写小说吗?至少可

    2023年04月17日
    浏览(44)
  • 跟着pink老师前端入门教程-day03

    6.1 表格的主要作用 主要用于 显示、展示数据 ,可以让数据显示的规整,可读性非常好,特别是后台展示数据时,能够熟练运用表格就显得很重要。 6.2 基本语法 6.3 表头单元格标签 一般表头单元格位于表格的 第一行或第一列 ,表头单元格里面的 文本内容加粗居中显示 ,突

    2024年01月18日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包