ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

弗洛伊德算法

2021-10-25 16:31:28  阅读:206  来源: 互联网

标签:弗洛伊德 matrix int vertex length 算法 new dis


基本介绍

Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。

思路

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中则包含了最短通路径的信息。

优缺点分析

Floyd算法适用于APSP(All Pairs Shortest Paths,多源最短路径),是一种动态规划算法,稠密图效果最佳,边权可正可负。此算法简单有效,由于三重循环结构紧凑,对于稠密图,效率要高于执行|V|次Dijkstra算法,也要高于执行|V|次SPFA算法。
优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单。
缺点:时间复杂度比较高,不适合计算大量数据。

代码

import java.util.Arrays;

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(matrix, vertex);
    graph.floyd();
    graph.show();
  }
}

class Graph {
  char[] vertex;  //存放顶点
  int[][] dis;  //各个顶点到其它顶点的距离
  int[][] pre;  //到达各个顶点的前驱顶点

  public Graph(int[][] dis,char[] vertex) {
    int length = vertex.length;
    this.vertex = new char[length];
    System.arraycopy(vertex, 0, this.vertex, 0, vertex.length);
    this.dis = new int[length][length];
    for (int i = 0; i < length; i++) {
      System.arraycopy(dis[i], 0, this.dis[i], 0, length);
    }
    this.pre=  new int[length][length];
    for (int i = 0; i < length; i++) {
      Arrays.fill(this.pre[i],i);
    }
  }

  /**
   * 显示结果
   */
  public void show() {
    for (int i = 0; i < dis.length; i++) {
      for (int j = 0; j < dis.length; j++) {
        System.out.print(pre[i][j] + "\t");
      }
      System.out.println();
      for (int k = 0; k < dis.length; k++) {
        System.out.print("(" + vertex[i] + "到" + vertex[k] + "的最短距离是:" + dis[i][k] + ")");
      }
      System.out.println();
    }
  }

  /**
   * 弗洛伊德算法
   */
  public void floyd() {
    int length;
    for (int i = 0; i < dis.length; i++) {
      for (int j = 0; j < dis.length; j++) {
        for (int k = 0; k < dis.length; k++) {
          length = dis[j][i] + dis[i][k];
          if (length < dis[j][k]) {
            dis[j][k] = length;
            pre[j][k] = pre[i][k];
          }
        }
      }
    }
  }

}

标签:弗洛伊德,matrix,int,vertex,length,算法,new,dis
来源: https://www.cnblogs.com/ftlzypx/p/15459187.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有