热门标签 | HotTags
当前位置:  开发笔记 > 人工智能 > 正文

java算法导论之FloydWarshall算法实现代码

这篇文章主要介绍了算法导论之FloydWarshall算法实现代码的相关资料,需要的朋友可以参考下

摘要: 算法导论之FloydWarshall算法

求一个图中任意两点之间的最短路径  

    FloydWarshall算法是通过动态规划来计算任意两点之间的最短路径 

        如果普通求最短路径,可以对图进行V次(顶点数)BellmanFord算法。 这样的话时间复杂度为EV^2
        如果是稀疏图,则近似于V^3
        但是如果是密集图,则时间复杂度会近似达到V^4,这种情况需要优化,这里FloydWarshall通过动态规划进行优化
        ,并且使用邻接矩阵来表示图。

实例代码:

package org.loda.graph;

import java.math.BigDecimal;
import java.math.RoundingMode;

import org.loda.util.In;

/**
 * 
 * @ClassName: FloydWarshall
 * @Description: 求一个图中任意两点之间的最短路径
 * 
 *        FloydWarshall算法是通过动态规划来计算任意两点之间的最短路径
 * 
 *        如果普通求最短路径,可以对图进行V次(顶点数)BellmanFord算法。 这样的话时间复杂度为EV^2
 *        如果是稀疏图,则近似于V^3
 *        但是如果是密集图,则时间复杂度会近似达到V^4,这种情况需要优化,这里FloydWarshall通过动态规划进行优化
 *        ,并且使用邻接矩阵来表示图。 
 *         d(i,j); if m=0 
 *        D(i,j,m)={
 *         min(D(i,m,m-1)+D(m,j,m-1),D(i,j,m-1)); if m!=0
 * @author minjun
 * @date 2015年6月1日 上午9:39:42
 * 
 */
public class FloydWarshall {

 private double[][] d;

 private int[][] prev;

 private int v;

 private boolean negativeCycle;

 public FloydWarshall(int v) {
 this.v = v;

 d = new double[v][v];

 prev = new int[v][v];

 // 默认设置所有节点都不可达,而自己到自己是可达并且距离为0.0
 for (int i = 0; i j路径中的一个中间点
  for (int i = 0; i  d[i][k] + d[k][j]) {
   d[i][j] = d[i][k] + d[k][j];
   prev[i][j]=k;
   }
  }
  }
 }

 //四舍五入距离
 for (int i = 0; i i的距离d[i][i],如果存在小于0的,表示这个i->i的环路的权重和形成了一个负值,也就是存在这个负权重
 //在之前的其他最短路径算法中,无法通过这个方法来检测负环,因为之前路径距离都是保存在一个一维数组中,相等于只能检测d[0][0],无法检测每个d[i][i]
 for(int i=0;ib最短路径的距离
 * @param @param a
 * @param @param b
 * @param @return 设定文件
 * @return double 返回类型
 * @throws
 */
 public double distTo(int a, int b) {
 if (hasNegativeCycle())
  throw new RuntimeException("有负权重环,不存在最短路径");
 return d[a][b];
 }
 
 /**
 * 
 * @Title: printShortestPath
 * @Description: 打印a->b最短路径
 * @param @return 设定文件
 * @return Iterable 返回类型
 * @throws
 */
 public boolean printShortestPath(int a,int b){
 if (hasNegativeCycle()){
  System.out.print("有负权重环,不存在最短路径");
 }else if(a==b)
  System.out.println(a+"->"+b);
 else{
  System.out.print(a+"->");
  path(a,b);
  System.out.print(b);
 }
 return true;
 }

 private void path(int a, int b) {
 int k=prev[a][b];
 
 if(k==-1){
  return;
 }
 
 path(a,k);
 System.out.print(k+"->");
 path(k,b);
 }
 
 

 /**
 * 
 * @Title: addEdge
 * @Description: 添加边
 * @param @param a
 * @param @param b
 * @param @param w 设定文件
 * @return void 返回类型
 * @throws
 */
 public void addEdge(int a, int b, double w) {
 d[a][b] = w;
 }

 public static void main(String[] args) {
 // 不含负权重环的文本数据
 String text1 = "F:\\算法\\attach\\tinyEWDn.txt";
 // 含有负权重环的文本数据
 String text2 = "F:\\算法\\attach\\tinyEWDnc.txt";

 In in = new In(text1);

 int n = in.readInt();
 FloydWarshall f = new FloydWarshall(n);

 int e = in.readInt();

 for (int i = 0; i 

如果采用负权重环图,则会抛出异常,提示负环并表示无最短路径

如果采用不含负环的图,则会打印如下内容(目前以s=0作测试,其他点作为原点的最短路径可以自行尝试):

0到0的距离为:0.0
0->0

0到1的距离为:0.93
0->2->7->3->6->4->5->1
0到2的距离为:0.26
0->2
0到3的距离为:0.99
0->2->7->3
0到4的距离为:0.26
0->2->7->3->6->4
0到5的距离为:0.61
0->2->7->3->6->4->5
0到6的距离为:1.51
0->2->7->3->6
0到7的距离为:0.6
0->2->7

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


推荐阅读
  • 本文介绍如何利用动态规划算法解决经典的0-1背包问题。通过具体实例和代码实现,详细解释了在给定容量的背包中选择若干物品以最大化总价值的过程。 ... [详细]
  • 本文详细探讨了Java中的24种设计模式及其应用,并介绍了七大面向对象设计原则。通过创建型、结构型和行为型模式的分类,帮助开发者更好地理解和应用这些模式,提升代码质量和可维护性。 ... [详细]
  • 在金融和会计领域,准确无误地填写票据和结算凭证至关重要。这些文件不仅是支付结算和现金收付的重要依据,还直接关系到交易的安全性和准确性。本文介绍了一种使用C语言实现小写金额转换为大写金额的方法,确保数据的标准化和规范化。 ... [详细]
  • 在给定的数组中,除了一个数字外,其他所有数字都是相同的。任务是找到这个唯一的不同数字。例如,findUniq([1, 1, 1, 2, 1, 1]) 返回 2,findUniq([0, 0, 0.55, 0, 0]) 返回 0.55。 ... [详细]
  • 本文探讨了卷积神经网络(CNN)中感受野的概念及其与锚框(anchor box)的关系。感受野定义了特征图上每个像素点对应的输入图像区域大小,而锚框则是在每个像素中心生成的多个不同尺寸和宽高比的边界框。两者在目标检测任务中起到关键作用。 ... [详细]
  • 网络攻防实战:从HTTP到HTTPS的演变
    本文通过一系列日记记录了从发现漏洞到逐步加强安全措施的过程,探讨了如何应对网络攻击并最终实现全面的安全防护。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 深度学习理论解析与理解
    梯度方向指示函数值增加的方向,由各轴方向的偏导数综合而成,其模长表示函数值变化的速率。本文详细探讨了导数、偏导数、梯度等概念,并结合Softmax函数、卷积神经网络(CNN)中的卷积计算、权值共享及池化操作进行了深入分析。 ... [详细]
  • 机器学习中的相似度度量与模型优化
    本文探讨了机器学习中常见的相似度度量方法,包括余弦相似度、欧氏距离和马氏距离,并详细介绍了如何通过选择合适的模型复杂度和正则化来提高模型的泛化能力。此外,文章还涵盖了模型评估的各种方法和指标,以及不同分类器的工作原理和应用场景。 ... [详细]
  • 自学编程与计算机专业背景者的差异分析
    本文探讨了自学编程者和计算机专业毕业生在技能、知识结构及职业发展上的不同之处,结合实际案例分析两者的优势与劣势。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 深入浅出:Google工程师的算法学习指南
    通过Google工程师的专业视角,带你系统掌握算法的核心概念与实践技巧。 ... [详细]
  • 本文深入探讨了 Python 列表切片的基本概念和实际应用,通过具体示例展示了不同切片方式的使用方法及其背后的逻辑。 ... [详细]
  • 本文详细介绍了K-Medoids聚类算法,这是一种基于划分的聚类方法,适用于处理大规模数据集。文章探讨了其优点、缺点以及具体实现步骤,并通过实例进行说明。 ... [详细]
author-avatar
我爱上帝爱我
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有