• 弗洛伊德算法(Java)


    第8章弗洛伊德算法

    8.1算法介绍

    弗洛伊德(Floyd)算法

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

    2)弗洛伊德(Floyd)算法计算图中各顶点之间的最短路径

    3)迪杰斯特拉算法用于计算图中某一顶点到其他顶点的最短路径

    4)弗洛伊德算法与迪杰斯特拉算法的区别:迪杰斯特拉算法通过选定的被访问顶点,求出发访问顶点到其他顶点的最短路径,而弗洛伊德算法中每一个顶点都是出发访问顶点,所以需要将每一个顶点看作被访问顶点,求出从每一个顶点到其他顶点的最短路径

    8.2 算法图解

    1)设置顶点vi到顶点vk的最短路径已知为Lik,顶点vk到vj的最短路径已知为Lkj,顶点vi到vj的路径为Lij,则vi带vj的最短路径为:min{ Lij, Lik+Lkj},vk的取值为图中所有顶点,则可以获取到vi到vj的最短路径

    2)至于vi到vk的最短路径Lik或者vk到vj的最短路径Lkj,是以同样的方式获得

    3)图解
    在这里插入图片描述

    在这里插入图片描述

    弗洛伊德算法的步骤
    第一轮循环中,以A(下标为0作为中间顶点【即把A作为中间顶点的全部情况都进行遍历 ,就会得到新的距离表和前驱关系】,在这里插入图片描述

    找A相连的顶点,因为只有与A相连,A才能做中间顶点。明显与A相连的顶点有CBG
    在这里插入图片描述

    三层for循环思想
    在这里插入图片描述

    8.3 应用场景

    在这里插入图片描述

    8.4 代码实现

    在这里插入图片描述

    实现步骤:1、创建图  char[]存放顶点数组  int[][] dis 从各个顶点出发到其他顶点的距离  int[][] pre 保存到达目标顶点的前驱顶点   构造器 (int length,int[][] matrix, char[] vertex) //对pre数组初始化,存放的是前驱顶点的下标     显示pre数组和dis数组2、在图类中使用弗洛伊德算法public void floyd(){        int len = 0; //临时变量保存两点的最短距离        //k 是中间顶点,对k遍历        for (int k = 0; k < dis.length; k++) {            //i是出发顶点,对i遍历            for (int i = 0; i < dis.length; i++) {                //j是目的顶点,对j遍历                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]                        dis[i][j] = len;  //更新距离                        pre[i][j] = pre[k][j]; //更新前驱顶点                    }                }            }        }    }   
    
    • 1
    package com.ldm.floyd;
    
    import java.util.Arrays;
    
    /**
     * @author 梁东明
     * 2022/9/15
     * 人生建议:看不懂的方法或者类记得CTRL + 点击 看看源码或者注解
     * 点击setting在Editor 的File and Code Templates 修改
     */
    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 graph = new Graph(vertex.length, matrix, vertex);
            graph.floyd();
            graph.show();
        }
    }
    
    class Graph{
        private char[] data; //存放顶点数组
        private int[][] dis;  //各个顶点到其他顶点的距离
        private int[][] pre;  //保存到达目的顶点的前驱顶点
    
        public Graph(int length, int[][] matrix, char[] vertex) {
            this.data = 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[] vertex = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
            
            System.out.println("各个顶点到其他顶点的最短距离");
            for (int i = 0; i < dis.length; i++) {
                for (int j = 0; j < dis.length; j++) {
                    System.out.print(dis[i][j] + "\t");
                }
                System.out.println();
            }
            System.out.println("各个顶点到达目的顶点的前驱顶点");
            for (int i = 0; i < pre.length; i++) {
                for (int j = 0; j < pre.length; j++) {
                    System.out.print(vertex[pre[i][j]] + "\t");
                }
                System.out.println();
            }
        }
    
        /**
         * 弗洛伊德算法实现
         */
        public void floyd(){
            int len = 0; //临时变量保存两点的最短距离
            //k 是中间顶点,对k遍历
            for (int k = 0; k < dis.length; k++) {
                //i是出发顶点,对i遍历
                for (int i = 0; i < dis.length; i++) {
                    //j是目的顶点,对j遍历
                    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]
                            dis[i][j] = len;  //更新距离
                            pre[i][j] = pre[k][j]; //更新前驱顶点
                        }
                    }
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    本次弗洛伊德算法算法 的教程出自韩顺平的数据结构与算法

    数据结构和算法教程,哔哩哔哩详细教程
    在 185-188p.

    最后,认识一下,我是小白。努力成为一名合格的程序员。期待与你的下次相遇

  • 相关阅读:
    青少年护眼台灯哪个牌子好?国家认可的护眼台灯品牌
    1.python简介
    全网超细,自动化测试-数据管理/实施落地问题,跟着直接上高速...
    VS2019编译安装GDAL(C++)程序库
    tkmybatis通用mapper实现在使用Example进行查询的几种方式
    Parsing R-CNN(CVPR2019)-人体实例分析论文解读
    R语言ggplot2可视化地图并使用scale_fill_gradient函数自定义设置地图颜色刻度为灰色梯度刻度(grey gradient scales)
    第6章 Kafka面试题
    单片机之瑞萨RL78 串口通信的例子
    R语言——taxize(第三部分)
  • 原文地址:https://blog.csdn.net/weixin_48544279/article/details/126868249