40.弗洛伊德(Floyd)算法

news2024/11/24 20:35:07

概述

我们此前拆解过迪杰斯特拉(Dijkstra)算法,与它一样,弗洛伊德(Floyd)算法也是用于寻找给定的加权图中顶点间最短路径的算法。该算法是1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德及其团队发现的,以主要创始人 弗洛伊德 命名。
迪杰斯特拉算法通过选定的被访问顶点,求出从出发访问顶点到其他顶点的最短路径,而弗洛伊德算法中每一个顶点都是出发访问点,所以需要将每一个顶点看做被访问顶点,求出从每一个顶点到其他顶点的最短路径。

分析

设置顶点vi到顶点vk的最短路径已知为Lik,顶点vk到vj的最短路径已知为Lkj,顶点vi到vj的路径为Lij,则vi到vj的最短路径为: min((Lik+Lkj),Lij),vk的取值为无向图中所有顶点,则可获得vi到vj的最短路径。
至于vi到vk的最短路径Lik或者vk到vi的最短路径Lkj,是以同样的方式获得。

我们还是回到“郝乡长”的政绩工程——得胜乡的七村修路问题
在这里插入图片描述

首先是对于各个顶点之间举例的初始化
在这里插入图片描述
对于前驱关系也是我们在算法开始之前需要明晰的
在这里插入图片描述
在第一轮循环中,以A(下标:0)作为中间顶点,距离表和前驱关系会更新为:

在这里插入图片描述
以A为中间节点的可能性全部遍历,就会得到更新的距离表和前驱关系。

(无向图)将A作为中间节点情况有:

分析距离表的替换:

• C-A-G 距离 7+2 = 9; --------> CG (N) ------>CG(9)
• C-A-B 距离 7+5 = 12; --------> CB(N) ------>CB(12)
• G-A-B 距离 2+5 = 7; --------> GB(3) 因为7>3所以不做替换!

分析前驱关系表的替换:

• C通过A到G,故前驱关系表中,C行G列的前驱节点替换为A;
• G通过A到C,故前驱关系表中,G行C列的前驱节点替换为A;
• C通过A到B,故前驱关系表中,C行B列的前驱节点替换为A;
• B通过A到C,故前驱关系表中,B行C列的前驱节点替换为A;

如何将A作为中间节点的情况都考虑到?

中间顶点数组{A,B,C,D,E,F,G} 取A(k[0])—> …
出发顶点数组{A,B,C,D,E,F,G} 取A (i[0]) —>取B(i[1])
终点数组{A,B,C,D,E,F,G} 遍历 (j=1,2,3,…) —>(j=1,2,3,…)
时间复杂度: O(n3),较高

代码实现

public class FloydAlgorithm {

    public static void main(String[] args) {

        char[] vertex = {'A','B','C','D','E','F','G'};
        //创建邻接矩阵
        int [][] matrix = new int[vertex.length][vertex.length];
        final int N = 65535;
        matrix[0] = new int[]{0,5,7,N,N,N,2};
        matrix[1] = new int[]{5,0,N,9,N,N,3};
        matrix[2] = new int[]{7,N,0,N,8,N,N};
        matrix[3] = new int[]{N,9,N,0,N,4,N};
        matrix[4] = new int[]{N,N,8,N,0,5,4};
        matrix[5] = new int[]{N,N,N,4,5,0,6};
        matrix[6] = new int[]{2,3,N,N,4,6,0};

        //创建图
        Graph graph = new Graph(vertex.length, matrix, vertex);

        graph.floyd();

        graph.show();

    }
}

//图
class Graph{
    private char[] vertex;//存放顶点的数组
    private int [][] dis;//保存,从各个顶点出发到其它顶点的距离,最后的结果,也是保留在该数组
    private int [][] pre;//保存到达目标顶点的前驱顶点

    /**
     * @param length 大小
     * @param matrix 邻接矩阵
     * @param vertex 顶点数组
     */
    public Graph(int length,int [][] matrix,char[]vertex) {
        this.vertex = vertex;
        this.dis = matrix;
        this.pre = new int[length][length];
        //对pre进行初始化,注意存放的是前驱顶点的下标
        for (int i = 0; i < length; i++) {
            Arrays.fill(pre[i],i);
        }
    }

    //显示pre数组和dis数组
    public void show(){
        char[] vetex = {'A','B','C','D','E','F','G'};
        for (int k = 0; k < dis.length; k++) {
            //先将pre数组输出的一行
            for (int i = 0; i < dis.length; i++) {
                System.out.print(vetex[pre[k][i]] + " ");
            }
            System.out.println();
            //输出dis数组的一行数据
            for (int i = 0; i < dis.length; i++) {
                System.out.print("("+vertex[k]+"到"+vertex[i]+"的最短路径"+dis[k][i]+") ");
            }
            System.out.println();
            System.out.println();
            
        }
        
    }

    //弗洛伊德算法
    public void floyd(){
        int len = 0 ;//变量保存
        //对中间顶点的遍历, k 就是中间顶点的下标
        for (int k = 0; k < dis.length; k++) {
            //从i顶点开始出发 [ A,B,C,D,E,F,G ]
            for (int i = 0; i < dis.length; i++) {
                //到达j顶点  [ A,B,C,D,E,F,G ]
                for (int j = 0; j < dis.length; j++) {
                    len = dis[i][k]+dis[k][j];//求出i顶点出发,经过k中间顶点,到达j顶点距离
                    if (len<dis[i][j]){//如果len < 两点的直连距离
                        dis[i][j] = len;//更新距离
                        pre[i][j] =pre[k][j];//更新前驱节点
                    }
                }
            }
        }
    }
}


关注我,共同进步,每周至少一更。——Wayne

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1147468.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】centos安装配置及远程连接工具的使用

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《微信小程序开发实战》。&#x1f3af;&#x1f3a…

私有云:【12】使用connention托管虚拟桌面

私有云&#xff1a;【12】使用connention托管虚拟桌面 1、使用connention托管虚拟桌面 1、使用connention托管虚拟桌面 使用cloudadmin用户登录connection服务器 登录connection客户端 创建桌面池 选择手动桌面池 选择vcenter虚拟机 选择vcenter.test.com 按如下选择下一步 设…

贝锐蒲公英旁路模式异地组网,不改动网络实现企业分部与总部互通

Micheal是一家快递公司的IT运维人员&#xff0c;因公司业务发展迅速&#xff0c;新增网点的速度非常快&#xff0c;各网点需将每天的数据都上传到总部服务器&#xff0c;及平时需要向总部服务器查询一些数据&#xff0c;总部的主路由是一台带有防火墙功能的企业路由&#xff0c…

共用体/联合体 的引入

概念 由一系列具有相同数据类型或者不同数据类型的数据组成的集合&#xff0c;数据互斥关系&#xff0c;共用体所有的成员共同使用一份内存空间&#xff0c;其中空间的大小是按照共用体成员中所占的最大的内存空间的成员的空间进行分配&#xff0c;即同一个内存空间存放类型不…

【PyQt学习篇 · ⑤】:QWidget - 鼠标操作

文章目录 鼠标形状设置常用鼠标形状设置自定义鼠标形状 重置形状获取鼠标鼠标跟踪鼠标跟踪案例 鼠标形状设置 常用鼠标形状设置 在PyQt中&#xff0c;QWidget类提供了设置鼠标形状的功能。可以使用setCursor()方法来更改QWidget及其子类的鼠标形状。该方法接受一个Qt.CursorS…

idea的设置

1.设置搜索encoding,所有编码都给换为utf-8 安装插件 eval-reset插件 https://www.yuque.com/huanlema-pjnah/okuh3c/lvaoxt#m1pdA 设置活动模板,idea有两种方式集成tomcat,一种是右上角config配置本地tomcat,一种是插件,如果使用插件集成,则在maven,pom.xml里面加上tomcat…

【uniapp】uniapp实现input输入显示数字键盘:

文章目录 一、官网文档&#xff1a;二、文档&#xff1a;三、效果&#xff1a;【1】number&#xff1a;iPhone原生数字键盘不显示小数点【2】digit&#xff1a;【3】digit和inputmode&#xff1a; 一、官网文档&#xff1a; input | uni-app官网 二、文档&#xff1a; 三、效果…

深度学习中Transformer的简单理解

Transformer 网络结构 Transformer也是由编码器和解码器组成的。 每一层Encoder编码器都由很多层构成的&#xff0c;编码器内又是self-attention和前馈网络构成的。Self-attention是用来做加权平均&#xff0c;前馈网络用来组合。 但是decoder有点不同&#xff0c;多了一层En…

Vue 3 响应式对象:ref 和 reactive 的使用和区别

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是尘缘&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f449;点击这里&#xff0c;就可以查看我的主页啦&#xff01;&#x1f447;&#x…

私有云:【11】win10安装Agent客户端组件

私有云&#xff1a;【11】win10安装Agent客户端组件 1、配置IP及加入域2、安装Agent客户端组件3、生成win10快照 1、配置IP及加入域 配置ip及dns 修改计算机名且加入域 进行验证 加入成功 将cloudadmin用户加入管理员组 输入cloudadmin户名密码验证 2、安装Agent客户端组件 …

第八周实验记录

10月20日-10月22日工作&#xff1a; 复现S-NeRF代码&#xff0c;按照github的步骤进行&#xff0c;首先使用一个RTX3090显卡&#xff0c; 在下图步骤中&#xff1a;运行最后一步 python scripts/run.py 出现问题 继续使用两张RTX3090显卡尝试&#xff0c;依旧在这一步出现问…

如何防范AI等技术带来的诈骗风险?从技术、法律、教育等多方面入手

文章目录 前言什么是AI诈骗案例案例一案例二 AI诈骗的特点如何预防和应对AI诈骗建议后记 前言 互联网是一把双刃剑&#xff0c;这是我们常说的一个问题。 随着人工智能技术的快速发展&#xff0c;AI诈骗成为当今社会面临的新兴威胁。不法分子利用人工智能技术&#xff0c;以更…

趣互联app一分购地推网推拉新上线平台啦,简单流程

趣互联一手渠道 “聚量推客” 上架趣互联啦&#xff0c;适合地推和网推进行推广&#xff0c;社群私域也可以推广&#xff0c;比较简单。 如果你在做拉新推广 地推或者网推都可以通过“聚量推客”获取最大收益

SDXL简介

SDXL是一个文生图模型。相比旧版的stable diffusion&#xff0c;SDXL主要的不同有三点&#xff1a; 有一个refinement model&#xff0c;通过image-to-image的方式来提高视觉保真度。使用了两个text encoder&#xff0c;OpenCLIP ViT-bigG和CLIP ViT-L。增加了图片大小和长宽比…

解决:getReader() has already been called for this request

问题现场&#xff1a; 原因: HttpServletRequest 的 getInputStream() 和 getReader() 都只能读取一次。 因为 我们使用RequestBody 注解&#xff0c;读取body参数&#xff1b;而 又 写了拦截器&#xff0c;也需要将post请求&#xff0c;body数据拿出来。 由于RequestBody 也是…

JVM第二十三讲:Java动态调试技术原理

Java动态调试技术原理 本文是JVM第二十三讲&#xff0c;Java动态调试技术原理。转载自 美团技术团队胡健的Java 动态调试技术原理及实践&#xff0c;通过学习java agent方式进行动态调试&#xff0c;了解目前很多大厂开源的一些基于此的调试工具 (例如来自阿里开源的Arthas)。 …

工作组与域

目录 内网环境 内网环境分类 工作组 域 域的组成 域中的信任关系 父域与子域 域的结构 林中信任关系特点 域中的域名 活动目录&#xff08;AD&#xff09; 域中活动目录下的账号登录域中计算机过程 组织单位&#xff08;OU&#xff09; 组策略&#xff08;GPO&am…

【C++】priority_queue模拟实现+仿函数+反向迭代器

priority_queue模拟实现仿函数反向迭代器 1.priority_quyue1.1priority_queue的使用1.2priority_queue模拟实现1.2.1无参构造一段区间构造1.2.2push1.2.3pop1.2.4empty1.2.5size1.2.6top 2.仿函数2.1什么是仿函数2.2增加仿函数的priority_queue模拟实现完整代码 3.反向迭代器3.…