C# 弗洛伊德(Floyd)算法

弗洛伊德(Floyd)算法 主要是用于计算图中所有顶点对之间的最短距离长度的算法,如果是要求某一个特定点到图中所有顶点之间的最短距离可以用 Dijkstra(迪杰斯特拉)算法来求。

 弗洛伊德(Floyd)算法的算法过程是:

1、从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。

2、对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短。如果是更新它。

把图用邻接矩阵G表示出来,如果从Vi到Vj有路可达,则G[i,j]=d,d表示该路的长度;否则G[i,j]=无穷大。定义一个矩阵D用来记录所插入点的信息,D[i,j]表示从Vi到Vj需要经过的点,初始化D[i,j]=j。把各个顶点插入图中,比较插点后的距离与原来的距离,G[i,j] = min( G[i,j], G[i,k]+G[k,j] ),如果G[i,j]的值变小,则D[i,j]=k。在G中包含有两点之间最短道路的信息,而在D中则包含了最短路径的信息。

比如,要寻找从V5到V1的路径。根据D,假如D(5,1)=3则说明从V5到V1经过V3,路径为{V5,V3,V1},如果D(5,3)=3,说明V5与V3直接相连,如果D(3,1)=1,说明V3与V1直接相连。 

 时间复杂度和空间复杂度

时间复杂度:O(n^3);

空间复杂度: O(n^2);

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConAppFlody
{
   
     class Program
    {
         private  const  int MaxSize =  6;
         private  const  int INF =  32767;     // INF表示∞
         private  const  int MAXV =  4;     // 最大顶点个数
        
// 结构体的成员定义里不能直接赋值,也就是等号后的应该移除,在你后面实例化整个结构体以后,
        
// 再对Study_Data[n].input=new double[50] 其他成员类似。顺便说下其实用class简单得多。

         struct VertexType
        {
             public  int no;                         // 顶点编号
             public  int info;                     // 顶点其他信息
        } ;                                // 顶点类型
         struct MGraph                     // 图的定义
        {
             public  int[,] edges;        // 邻接矩阵
             public  int n, e;              // 顶点数,弧数
             public VertexType[] vexs;           // 存放顶点信息
        } ;                                // 图的邻接矩阵类型

         static  void initdata()
        {
             int i,j;
            MGraph g;
            g.n = MAXV; g.e =  8;
            g.edges =  new  int[MAXV, MAXV];
            g.vexs =  new VertexType[MAXV];
             // int [,] anArray = new int [2, 4] {{1,2,3,4},{5,6,7,8}};
             int[,] a =  new  int[MAXV, MAXV] {
            { 05,INF, 7},
            { 50,   4, 1},
            {INF,  40,INF},
            { 7, 1,INF, 0}
            };

             for (i =  0; i < g.n; i++)         // 建立图的图的邻接矩阵
                 for (j =  0; j < g.n; j++)
                    g.edges[i, j] = a[i, j]; / //
            Console.WriteLine( " 各顶点的最短路径: ");
            Floyd(g);
          
    
        }

         static  void Floyd(MGraph g)
        {
             int[,] A =  new  int[MAXV, MAXV]; // A用于存放当前顶点之间的最短路径长度,分量A[i][j]表示当前顶点vi到顶点vj的最短路径长度。
             int[,] path =  new  int[MAXV, MAXV]; // 从顶点vi到顶点vj的路径上所经过的顶点编号不大于k的最短路径长度。
             int i, j, k;
             for (i =  0; i < g.n; i++)
            {
                 for (j =  0; j < g.n; j++) // 对各个节点初始已经知道的路径和距离
                {
                    A[i, j] = g.edges[i, j];
                    path[i, j] = - 1;
                }
            }
             for (k =  0; k < g.n; k++)
            {
                 for (i =  0; i < g.n; i++)
                     for (j =  0; j < g.n; j++)
                         if (A[i, j] > A[i, k] + A[k, j]) // 从i到j的路径比从i经过k到j的路径长
                        {
                            A[i, j] = A[i, k] + A[k, j]; // 更改路径长度
                            path[i, j] = k; // 更改路径信息经过k
                        }
            }

            Dispath(A, path, g.n);    // 输出最短路径
        }

         static  void Dispath( int[,] A,  int[,] path,  int n)
        {

             int i, j;
             for (i =  0; i < n; i++)
                 for (j =  0; j < n; j++)
                {
                     if (A[i, j] == INF)
                    {
                         if (i != j)
                        {

                            Console.WriteLine( " 从{0}到{1}没有路径\n ", i, j);
                        }
                       
                    }
                     else
                    {
                        Console.Write( " 从{0}到{1}=>路径长度:{2} 路径: ", i, j, A[i, j]);
                        
                        Console.Write( " {0}, ", i);     // 输出路径上的起点
                        Ppath(path,i,j);             // 输出路径上的中间点
                        Console.WriteLine( " {0} ", j);     // 输出路径上的终点
                    }
                }
        }

         static  void Ppath( int[,] path,  int i,  int j)   // 前向递归查找路径上的顶点
        {
             int k;
            k = path[i, j];
             if (k == - 1return;     // 找到了起点则返回
            Ppath(path, i, k);     // 找顶点i的前一个顶点k

            Console.Write( " {0}, ", k);     // 输出路径上的终点
            Ppath(path, k, j);     // 找顶点k的前一个顶点j
        }

         static  void Main( string[] args)
        {
            initdata();
            
             // Console.Write("{0}", MaxSize);
            
// Console.Write("{0}", MAXV);
            Console.ReadKey();
        }
    }
}

 

转载于:https://www.cnblogs.com/lanshy/p/4441685.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值