Floyd算法(三)之 Java详解

2023-10-26

前面分别通过C和C++实现了弗洛伊德算法,本文介绍弗洛伊德算法的Java实现。

目录 
1
弗洛伊德算法介绍 
2弗洛伊德算法图解 
3弗洛伊德算法的代码说明 
4弗洛伊德算法的源码

转载请注明出处:http://www.cnblogs.com/skywang12345/

更多内容:数据结构与算法系列 目录

弗洛伊德算法介绍

和Dijkstra算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的算法。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。


基本思想

     通过Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引入一个矩阵S,矩阵S中的元素a[i][j]表示顶点i(第i个顶点)到顶点j(第j个顶点)的距离。

     假设图G中顶点个数为N,则需要对矩阵S进行N次更新。初始时,矩阵S中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞。 接下来开始,对矩阵S进行N次更新。第1次更新时,如果"a[i][j]的距离" > "a[i][0]+a[0][j]"(a[i][0]+a[0][j]表示"i与j之间经过第1个顶点的距离"),则更新a[i][j]为"a[i][0]+a[0][j]"。 同理,第k次更新时,如果"a[i][j]的距离" > "a[i][k]+a[k][j]",则更新a[i][j]为"a[i][k]+a[k][j]"。更新N次之后,操作完成!

     单纯的看上面的理论可能比较难以理解,下面通过实例来对该算法进行说明。

弗洛伊德算法图解

以上图G4为例,来对弗洛伊德进行算法演示。

初始状态:S是记录各个顶点间最短路径的矩阵。 
第1步:初始化S。 
    矩阵S中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞。实际上,就是将图的原始矩阵复制到S中。 
    注:a[i][j]表示矩阵S中顶点i(第i个顶点)到顶点j(第j个顶点)的距离。

第2步:以顶点A(第1个顶点)为中介点,若a[i][j] > a[i][0]+a[0][j],则设置a[i][j]=a[i][0]+a[0][j]。 
    以顶点a[1]6,上一步操作之后,a[1][6]=∞;而将A作为中介点时,(B,A)=12,(A,G)=14,因此B和G之间的距离可以更新为26。

同理,依次将顶点B,C,D,E,F,G作为中介点,并更新a[i][j]的大小。

弗洛伊德算法的代码说明

以"邻接矩阵"为例对弗洛伊德算法进行说明,对于"邻接表"实现的图在后面会给出相应的源码。

1. 基本定义

public class MatrixUDG {

    private int mEdgNum;        // 边的数量
    private char[] mVexs;       // 顶点集合
    private int[][] mMatrix;    // 邻接矩阵
    private static final int INF = Integer.MAX_VALUE;   // 最大值

    ...
}

MatrixUDG是邻接矩阵对应的结构体。mVexs用于保存顶点,mEdgNum用于保存边数,mMatrix则是用于保存矩阵信息的二维数组。例如,mMatrix[i][j]=1,则表示"顶点i(即mVexs[i])"和"顶点j(即mVexs[j])"是邻接点;mMatrix[i][j]=0,则表示它们不是邻接点。

2. 弗洛伊德算法

/*
 * floyd最短路径。
 * 即,统计图中各个顶点间的最短路径。
 *
 * 参数说明:
 *     path -- 路径。path[i][j]=k表示,"顶点i"到"顶点j"的最短路径会经过顶点k。
 *     dist -- 长度数组。即,dist[i][j]=sum表示,"顶点i"到"顶点j"的最短路径的长度是sum。
 */
public void floyd(int[][] path, int[][] dist) {

    // 初始化
    for (int i = 0; i < mVexs.length; i++) {
        for (int j = 0; j < mVexs.length; j++) {
            dist[i][j] = mMatrix[i][j];    // "顶点i"到"顶点j"的路径长度为"i到j的权值"。
            path[i][j] = j;                // "顶点i"到"顶点j"的最短路径是经过顶点j。
        }
    }

    // 计算最短路径
    for (int k = 0; k < mVexs.length; k++) {
        for (int i = 0; i < mVexs.length; i++) {
            for (int j = 0; j < mVexs.length; j++) {

                // 如果经过下标为k顶点路径比原两点间路径更短,则更新dist[i][j]和path[i][j]
                int tmp = (dist[i][k]==INF || dist[k][j]==INF) ? INF : (dist[i][k] + dist[k][j]);
                if (dist[i][j] > tmp) {
                    // "i到j最短路径"对应的值设,为更小的一个(即经过k)
                    dist[i][j] = tmp;
                    // "i到j最短路径"对应的路径,经过k
                    path[i][j] = path[i][k];
                }
            }
        }
    }

    // 打印floyd最短路径的结果
    System.out.printf("floyd: \n");
    for (int i = 0; i < mVexs.length; i++) {
        for (int j = 0; j < mVexs.length; j++)
            System.out.printf("%2d  ", dist[i][j]);
        System.out.printf("\n");
    }
}

弗洛伊德算法的源码

这里分别给出"邻接矩阵图"和"邻接表图"的弗洛伊德算法源码。

1邻接矩阵源码(MatrixUDG.java)

2邻接表源码(ListUDG.java)




https://www.cnblogs.com/skywang12345/p/3711532.html?utm_source=tuicool&utm_medium=referral

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Floyd算法(三)之 Java详解 的相关文章

  • 应用对数来导航树

    我曾经知道一种使用对数从树的一片叶子移动到树的下一个 有序 叶子的方法 我认为它涉及获取 当前 叶子的位置值 排名 并将其用作从根向下到新目标叶子的新遍历的种子 一直使用对数函数测试来确定是否沿着右或左节点向下到达叶子 我已经不记得如何运用
  • 使用到达时间差对信号进行三边测量

    我在寻找或实现寻找信号源的算法时遇到一些麻烦 我的工作目标是找到声音发射器的位置 为了实现这一点 我使用了三个麦克风 我正在使用的技术是多点定位这是基于到达时间差 The 到达时间差使用发现每个麦克风之间互相关接收到的信号 我已经实现了算法
  • 依赖解析算法

    我正在编写一个包管理器 为此我希望依赖项解析尽可能强大 每个包都有一个版本列表 每个版本包含以下信息 具有可比性的 ID 依赖关系 软件包列表以及每个软件包的一组可接受的版本 冲突 软件包列表以及每个软件包的一组与该版本一起导致问题的版本
  • 使用 A 星查找路径的启发式函数

    I am trying to find a optimal solution for the following problem 每个节点内表示的数字表示为 x y 一个节点的相邻节点总是有一个y值为 当前节点 y 值 1 更改的成本为 1
  • 贪心技术与穷举搜索有何不同?

    我正在为一些示例问题编写伪代码 并且我注意到贪婪技术和详尽搜索之间存在令人担忧的模式 Job 1 Job 2 Job 3 Job 4 Job 5 Person 1 9 2 7 8 Person 2 6 4 3 7 Person 3 5 8
  • 优化两个三位数乘积的最大回文数?

    我正在研究一个面试问题 我被问到这个问题 我应该编写一个程序 从两个三位数的乘积中找到最大的回文数 这里是question https projecteuler net problem 4 我想出了这种从底部开始的蛮力方法 public c
  • 布隆过滤器的使用

    我正在努力理解布隆过滤器的用处 我了解了它的底层逻辑 空间压缩 快速查找 误报等 我只是不能将这个概念应用到现实生活中 因为它是有益的 一种常见的应用是在 Web 缓存中使用布隆过滤器 我们使用布隆过滤器来确定给定的 URL 是否在缓存中
  • 2D形状识别与解析算法

    我正在寻找一种算法 用于从给定的一组 x y 点检测简单形状 如矩形 三角形 正方形和圆形 我还在寻找一种方法 一旦检测到 将路径转换为更干净的形状 我已经查遍了互联网 但没有找到任何 简单 的方法 几乎所有这些对于我的简单实现来说都是高级
  • 融合元组以查找等价类

    假设我们有一个包含 k 个元素的有限域 D d1 dk 我们认为 S 是 D n 的子集 即一组 形式的元组 其中 ai 在 D 中 我们希望使用 S 2 D n 的子集 即一组 形式的元组 其中 Ai 是 D 的子集 来 紧凑地 表示它
  • 基于 2 个输入的伪随机数生成器 [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我需要根据 2 个输入值 X 和 Y 生成一个伪随机数 给定相同的 X 和 Y 值 我需要得到相同的结果 结果应介于 0 和 1 之间 含
  • 将数字的各个数字部分相加/求和的最快方法

    不久前 我在数学论坛上看到一个问题 其中一个人正在讨论一遍又一遍地将数字中的数字相加 直到达到个位数 即 362 将变成 3 6 2 这将变成 11 然后 11 将变成 1 1 将变成 2 因此 362 将返回2 我写了一些很好的代码来得到
  • 字符串的渐进单词组合

    我需要获得字符串的渐进单词组合 例如 这是字符串 输出 这是字符串 这是 这个字符串 是字符串 这 是 细绳 你知道类似的算法吗 我需要php语言 谢谢 这是解决您问题的简单代码 我将每个字符串递归地连接到数组中的其余字符串 string
  • 最低共同祖先算法

    所以我一直在研究实现最低共同祖先算法 我研究了许多不同的算法 主要是 Trajan 解决方案的变体或 RMQ 的变体 我正在使用非二叉树 我的树经常会在查询之间发生变化 因此预处理不一定值得 树的节点数不应超过 50 75 个 我想知道的是
  • 如何确定字符串的最小公约数?

    我在面试时被问到以下问题 并被它难住了 我遇到的部分问题是要下定决心要解决什么问题 起初我并不认为这个问题在内部是一致的 但后来我意识到它要求你解决两个不同的问题 第一个任务是弄清楚一个字符串是否包含另一个字符串的倍数 但第二个任务是在两个
  • 算法 - 树中所有节点的最大距离

    所以 找到树中两个节点之间的最长路径相当容易 但我想要的是找到从节点出发的最长路径x到树中的另一个节点 对于所有x 这个问题也可以用以下方式表达 计算从给定的树中可以生成的所有有根树的高度 One way of course is to j
  • 计算总和等于 k ​​的子集数量

    给定一个数组 我们需要找出总和恰好等于给定整数 k 的子集的数量 请针对这个问题提出一个最佳算法 这里不需要实际的子集 只需计数即可 该数组由整数组成 可以是负数也可以是非负数 例子 数组 gt 1 4 1 10 5 绝对值总和 gt 9
  • n的渐近增长选择下限(n/2)

    如何找到 n select Floor n 2 的渐近增长 我试过 使用扩展并得到它等于 n n 1 floor n 2 1 n floor n 2 知道我该如何从那里去吗 感谢任何帮助 更喜欢提示而不是答案 我同意上面的答案 但想提供更多
  • 递归:n项级数之和

    需要递归函数 系列是 1 2 3 3 4 5 4 5 6 7 递归求 n 的级数之和 我无法想到应该在函数中传递哪些参数 我的方法 我认为我应该传递 n 要相乘的项数 但我无法想到的是我应该如何在同一个函数中 和 以及我的 return 语
  • RNG 技术的可移植性和可重复性

    我可以使用两种方法之一来创建一个伪随机数序列 该序列具有两个重要特征 1 它可以在不同的机器上重现 2 该序列永远不会重复范围内的数字 直到所有数字都被发出 我的问题是 这两种方法在可移植性 操作系统 Python 版本等 方面是否存在潜在
  • 为什么 n 按位和 -n 总是返回最右边的位(最后一位)

    这是Python代码片段 1 1 1 2 2 2 3 3 1 看来任何n n总是返回最右边 最后 位 我真的不知道为什么 有人可以帮助我理解这一点吗 这是由于负数以二进制表示的方式 称为二进制补码表示 创建某个数字 n 的补码 换句话说 创

随机推荐

  • LeetCode解析------218.天际线问题-树状数组

    题目 城市的天际线是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓 现在 假设您获得了城市风光照片 图A 上显示的所有建筑物的位置和高度 请编写一个程序以输出由这些建筑物形成的天际线 图B 每个建筑物的几何信息用三元组 Li Ri Hi
  • 由相位噪声曲线计算积分相噪和Jitter的方法

    先放一张忘了从哪扒下来的图 基本思路 分段求积分相噪 相加得整体的积分相噪 进而得到以弧度为单位的相位抖动 最终转换为以时间为单位的Jitter MATLAB代码 function ph2jt fc f ph ph2jt fc f ph f
  • Android 实现计时器功能

    最近有个项目要实现记录时间推进的功能 之前百度了下 发现了android自带控件 Chronometer 可以实现这个功能 详见之前写的博客 http blog csdn net qq 21793463 article details 49
  • Android 系统设置中显示设置之休眠和屏保设置篇

    1 休眠设置 首先我们来看一下休眠设置在界面中的定义 1
  • 32_杂项

    文章目录 TLS TLS 安全密码套件 证书 TLS通讯过程 open file cache TLS TLS 安全密码套件 密钥交换 ecdhe ECDH椭圆曲线交换 身份验证 RSA 对称加密 aes 128 gcm 摘要算法 sha25
  • SpringMVC-复杂参数处理

    1 实体类 package com hwy entity public class Role private Integer id private String name public Integer getId return id pub
  • 程序员必须知道的10个搜索技巧

    转载地址 http www cnblogs com shown p 6524342 html 1 准确搜索 在关键词上加上双引号 2 排除关键词 用减号 eg 在搜索 Joe Bloggs jeans 时 你所得到的结果反馈是不包含 jea
  • vue3项目装包报错 npm ERR! 404 Not Found - GET https://registry.npmjs.org/@vue%2fvue-loader-v15 - Not found

    npm ERR code E404 npm ERR 404 Not Found GET https registry npmjs org vue 2fvue loader v15 Not found npm ERR 404 npm ERR
  • VSCode+Idea 一个增删改查demo

    一个简单的增删改查demo 开发工具 Visual Studio Code Idea Navicat demo 前端 后台 开发工具 Visual Studio Code 一款前端开发工具 下载地址 https code visualstu
  • 微信小程序开发教程 #043 - 在小程序开发中使用 npm

    本文介绍了如何在微信小程序开发中使用 npm 中包的功能 大大提高微信小程序的开发效率 同时也是微信小程序系列教程的视频版更新 微信小程序在发布之初没有对 npm 的支持功能 这也是目前很多前端开发人员在熟悉了 npm 生态环境后 对微信小
  • 【腾讯云 Cloud Studio 实战训练营】丝滑体验:用 Cloud Studio 实现一个精确计时的时钟

    当今的云计算技术已经越来越成熟 基于云计算技术进行云端开发已经成为最新趋势 而 Cloud Studio 是一个基于云计算的 Web 端开发微服务平台 提供了代码编辑器 调试器 代码库 以及自动构建和部署工具等各种功能 帮助开发者在云端开发
  • druid 配置

    spring datasource druid连接池 type com alibaba druid pool DruidDataSource 数据库驱动 driver com mysql jdbc Driver 最大连接池数量 max ac
  • 开源协议详解

    开源在今天的软件业已经很普遍 但开源是否意味着使用者可以对开源后的代码为所欲为呢 答案是否定的 开源运动同样有自己的游戏规则和道德准则 不遵行这些规则不但损害开源运动的健康发展 也会对违规者造成名誉和市场上的损失 更可能陷入法律纠纷和赔偿
  • gitlab Undefined method `provider' for nil:nilclass 登陆提示处理

    使用管理员用户 在管理区域 用户管理里面 搜索对应用户 修改用户身份里面的LDAP身份为正确信息
  • 【基础】Unity:Application的常用方法

    Application的常用方法 static void LoadLevel int index static void LoadLevel string name static void CaptureScreenShot string
  • php使用区块链_PHP实现区块链

    作者 列旭松 来源 高可用架构 原文链接 http t cn RgjsJ1i 著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处 来自 Linux内核那些事 微信号 like linux 作者 列旭松 唯品会资深工程师 曾任
  • C++标准演绎(未完)

    作者 略游 q群 512 001 256 一 词汇定义 标准 standard C 语言标准 在代码世界里 我们假设与公理等价 结论 由标准推导出的事实 规定 便于讨论 我们设定的一些规则 类型 type 同一类型 它们在C 内存布局一致
  • 简谈拉电阻

    简谈拉电阻 前言 拉电阻 弱拉和强拉 上拉和下拉 前言 电路设计中经常设计到拉电阻的概念 与常用的GPIO口的配置也息息相关 网上也有很多的总结 不多累述 简单的总结拉电阻相关的一些概念 拉电阻 拉电阻分为上拉电阻 pull up 和下拉电
  • powerdesigner常用配置-修改外键设置

    文章目录 取消自动生成外键列 PowerDesigner给两个表添加reference 中间显示外键信息步骤 取消自动生成外键列 PowerDesigner给两个表添加reference 中间显示外键信息步骤
  • Floyd算法(三)之 Java详解

    前面分别通过C和C 实现了弗洛伊德算法 本文介绍弗洛伊德算法的Java实现 目录 1 弗洛伊德算法介绍 2 弗洛伊德算法图解 3 弗洛伊德算法的代码说明 4 弗洛伊德算法的源码 转载请注明出处 http www cnblogs com sk