九.弗洛伊德(Floyd)算法

文章目录

弗洛伊德算法

佛洛依德(Floyd)算法介绍

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

2)弗洛伊德算法(Floyd)计算图中各个顶点之间的最短路径,比如以A顶点为出发顶点到其他六个顶点的最短路径是多少,紧接着又会以B这个顶点为出发顶点,求出从B这个顶点到其他六个顶点的最短路径,依此类推

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

4)弗洛伊德算法VS迪杰斯特拉算法:迪杰斯特拉算法是选一个顶点,求出这个顶点到其他顶点的最短路径;而弗洛伊德算法是把每个顶点都看作出发顶点(比如有七个顶点,七个顶点都会依次作为出发顶点),求出每个顶点到其他顶点的最短路径

弗洛伊德(Floyd)算法图解分析

1)设置顶点vi到顶点vk的最短路径已知为Lik (L表示Length, i表示i顶点, k表示k顶点), 顶点vk到vj的最短路径已知为Lkj , 顶点vi到vj的路径为Lij ,则vi到vj的最短路径为:

min((Lik+Lkj),Lij),vk的取值为图中所有顶点,则可获得vi到vj的最短路径。

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

i------k------j (i这个顶点通过k这个顶点到达j这个顶点) Lik+Lkj=Lij

i------j (也有可能i和j是直接可以连通) Lij

通过比较才能知道i到j的最短路径是哪个,如果Lij小,则最短路径是Lij,如果Lik+Lkj小(也就是通过这个中间顶点到达的距离更小,就把这个和记为最短路径),则最短路径为Lik+Lkj

3)弗洛伊德(Floyd)算法图解分析---举例说明

自己跟自己相连距离为0,N代表不可直连

初始顶点前驱关系:

第一轮循环中,以A(下标为0)作为中间顶点

即把A作为中间顶点的所有情况都进行遍历,在遍历的过程中更新距离表和前驱关系表

将A作为中间顶点情况有

  1. C---A---G [距离9]
  2. C---A---B [距离12]
  3. G---A---B [距离7]

距离表和前驱关系表更新为

第二轮循环中,以B(下标为:1)作为中间节点

第三轮循环中,以C(下标为:2)作为中间节点,依此类推

中间顶点 [A,B,C,D,E,F,G] k=0, 1, 2, 3, 4, 5, 6

出发顶点 [A,B,C,D,E,F,G] i=0, 1, 2, 3, 4, 5, 6

终点 [A,B,C,D,E,F,G] j=0, 1, 2, 3, 4, 5, 6

这里用到了三层for循环,最后得到每一个顶点到其他顶点的最短距离,最后的结果在距离表里面

弗洛伊德(Floyd)算法最佳应用---最短路径

1)胜利乡有7个村庄(A, B, C, D, E, F, G)

  1. 各个村庄的距离用边线表示(权),比如A---B距离5公里

3)问:如何计算出各村庄到其他各村庄的最短距离?

代码实现
c# 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Floyd
{
    class FloydAlgorithm
    {
        static void Main(string[] args)
        {
            //测试图是否创建成功
            char[] vertex = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };  //  顶点数组
            
            //创建邻接矩阵
            int[,] matrix = new int[vertex.Length, vertex.Length];
            int N = 65535;  //表示不可直连
            matrix = new int[,]
            {
                {0,5,7,N,N,N,2 },
                {5,0,N,9,N,N,3 },
                {7,N,0,N,8,N,N },
                {N,9,N,0,N,4,N },
                {N,N,8,N,0,5,4 },
                {N,N,N,4,5,0,6 },
                {2,3,N,N,4,6,0 },

            };

            //创建图对象
            Grap grap = new Grap(vertex.Length, matrix, vertex);
            //调用弗洛伊德算法
            grap.floyd();
            grap.show();
       
        }
    }

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

        //构造器
        /// <summary>
        /// 
        /// </summary>
        /// <param name="length">顶点的个数</param>
        /// <param name="matrix">邻接矩阵</param>
        /// <param name="vertex">顶点数组</param>
        public Grap(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++)
            {
                for (int j = 0; j < length; j++)
                {
                    pre[i, j] = i;
                }
            }

        }

        //显示pre数组和dis数组
        public void show()
        {
            //先将pre数组输出
            for (int i = 0; i < vertex.Length; i++)
            {
                
                for (int j = 0; j < vertex.Length; j++)
                {
                    Console.Write(vertex[pre[i,j]]+"  ");
                }
                Console.WriteLine();
                
                //将dis数组输出
                for (int j = 0; j < vertex.Length; j++)
                {
                    Console.Write("("+vertex[i]+"到"+vertex[j]+"的最短距离为"+dis[i,j]+")");
                }
                Console.WriteLine();
                Console.WriteLine();

            }
 
        }


        //弗洛伊德算法,比较容易理解,而且容易实现
        public void floyd()
        {
            int len;  //变量保存距离

            // 对中间顶点遍历,k就是中间顶点的下标 [A,B,C,D,E,F,G]
            for (int k = 0; k < vertex.Length; k++)   
            {
                //从i顶点开始出发[A,B,C,D,E,F,G]
                for (int i = 0; i < vertex.Length; i++)
                {

                    //从i顶点出发,经过k中间顶点,到达j顶点,j是这次的终点[A,B,C,D,E,F,G]
                    for (int j = 0; j < vertex.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];   //更新前驱顶点
                        }
                        //如果len>dis[i,j],我就不动
                        
                    }
                }
            }
        }

    }
}

代码运行结果

A A A F G G A

(A到A的最短距离为0)(A到B的最短距离为5)(A到C的最短距离为7)(A到D的最短距离为12)(A到E的最短距离为6)(A到F的最短距离为8)(A到G的最短距离为2)

B B A B G G B

(B到A的最短距离为5)(B到B的最短距离为0)(B到C的最短距离为12)(B到D的最短距离为9)(B到E的最短距离为7)(B到F的最短距离为9)(B到G的最短距离为3)

C A C F C E A

(C到A的最短距离为7)(C到B的最短距离为12)(C到C的最短距离为0)(C到D的最短距离为17)(C到E的最短距离为8)(C到F的最短距离为13)(C到G的最短距离为9)

G D E D F D F

(D到A的最短距离为12)(D到B的最短距离为9)(D到C的最短距离为17)(D到D的最短距离为0)(D到E的最短距离为9)(D到F的最短距离为4)(D到G的最短距离为10)

G G E F E E E

(E到A的最短距离为6)(E到B的最短距离为7)(E到C的最短距离为8)(E到D的最短距离为9)(E到E的最短距离为0)(E到F的最短距离为5)(E到G的最短距离为4)

G G E F F F F

(F到A的最短距离为8)(F到B的最短距离为9)(F到C的最短距离为13)(F到D的最短距离为4)(F到E的最短距离为5)(F到F的最短距离为0)(F到G的最短距离为6)

G G A F G G G

)(D到G的最短距离为10)

G G E F E E E

(E到A的最短距离为6)(E到B的最短距离为7)(E到C的最短距离为8)(E到D的最短距离为9)(E到E的最短距离为0)(E到F的最短距离为5)(E到G的最短距离为4)

G G E F F F F

(F到A的最短距离为8)(F到B的最短距离为9)(F到C的最短距离为13)(F到D的最短距离为4)(F到E的最短距离为5)(F到F的最短距离为0)(F到G的最短距离为6)

G G A F G G G

(G到A的最短距离为2)(G到B的最短距离为3)(G到C的最短距离为9)(G到D的最短距离为10)(G到E的最短距离为4)(G到F的最短距离为6)(G到G的最短距离为0)

相关推荐
MicroTech20252 分钟前
微算法科技(NASDAQ :MLGO)抗量子区块链技术:筑牢量子时代的数字安全防线
科技·算法·区块链
Ivanqhz4 分钟前
图着色寄存器分配算法(Graph Coloring)
开发语言·javascript·python·算法·蓝桥杯·rust
Elsa️7466 分钟前
洛谷p5718 复习下快速排序和堆排序
数据结构·算法·排序算法
Frostnova丶9 分钟前
LeetCode 3567.子矩阵的最小绝对差
算法·leetcode·矩阵
夏日听雨眠10 分钟前
文件学习9
数据结构·学习·算法
华农DrLai10 分钟前
什么是自动Prompt优化?为什么需要算法来寻找最佳提示词?
人工智能·算法·llm·nlp·prompt·llama
黎阳之光11 分钟前
十五五智赋新程 黎阳之光以AI硬核技术筑造产业数智底座
大数据·人工智能·算法·安全·数字孪生
2401_8914821713 分钟前
C++中的原型模式
开发语言·c++·算法
皙然13 分钟前
深度解析三色标记算法:JVM 并发 GC 的核心底层逻辑
java·jvm·算法
sali-tec15 分钟前
C# 基于OpenCv的视觉工作流-章40-特征找图
图像处理·人工智能·opencv·算法·计算机视觉