Java利用Dijkstra和Floyd分别求取图的最短路径

Java 利用 Dijkstra 和 Floyd 算法分别求取图的最短路径可以分为以下几个步骤:

1. 建立图的数据结构

首先需要建立用于表示图的数据结构,通常可以使用邻接矩阵或邻接表来表示图。

以邻接矩阵为例,可以定义一个二维数组来表示图,数组中的每一个元素 a[i][j] 表示从节点 i 到节点 j 的边的权值。如果不存在从节点 i 到节点 j 的边,则 a[i][j] 的值设置为一个很大的数(如99999999)或者无穷大。

public class Graph {
    private int[][] edges;  // 图的邻接矩阵
    private int numVertices; // 图中节点的个数

    // 构造函数
    public Graph(int numVertices) {
        this.numVertices = numVertices;
        edges = new int[numVertices][numVertices];
        for (int i = 0; i < numVertices; i++) {
            for (int j = 0; j < numVertices; j++) {
                edges[i][j] = 0; // 初始化矩阵元素为0
            }
        }
    }

    // 添加一条边
    public void addEdge(int source, int destination, int weight) {
        edges[source][destination] = weight;
    }

    // 获取邻接矩阵
    public int[][] getMatrix() {
        return edges;
    }
}

2. Dijkstra 算法求最短路径

Dijkstra 算法是一种单源最短路径算法。它以一个节点为起点,依次计算出到其他节点的最短路径。

Dijkstra 算法的基本思想是:先将起点到各个点之间的距离初始化为 ∞,再通过松弛操作逐一更新各个节点的距离。

在 Dijkstra 算法的过程中,需要维护一个集合 S,存储已经确定了最短距离的节点;同时也需要维护一个数组 dist,dist[v] 表示从起点 s 到节点 v 的最短距离。

public class Dijkstra {
    public static void dijkstra(Graph graph, int source) {
        int[][] edges = graph.getMatrix();
        int numVertices = graph.getNumVertices();
        boolean[] visited = new boolean[numVertices]; // 标记节点是否已经加入集合S
        int[] dist = new int[numVertices]; // 存储从源点到其他节点的最短距离

        // 初始化 dist 数组
        for (int i = 0; i < numVertices; i++) {
            dist[i] = Integer.MAX_VALUE;
            visited[i] = false;
        }

        // 把起点加入集合 S
        dist[source] = 0;

        // 循环直到所有节点都被加入集合 S
        for (int count = 0; count < numVertices - 1; count++) {
            // 在未加入集合 S 的节点中找到距离起点最近的节点
            int u = minDistance(dist, visited);

            // 把节点 u 加入集合 S
            visited[u] = true;

            // 更新 u 的邻接节点的距离
            for (int v = 0; v < numVertices; v++) {
                if (!visited[v] && edges[u][v] != 0 && 
                    dist[u] != Integer.MAX_VALUE && 
                    dist[u] + edges[u][v] < dist[v]) {
                    dist[v] = dist[u] + edges[u][v];
                }
            }
        }

        // 输出最短距离
        for (int i = 0; i < numVertices; i++) {
            System.out.printf("从 %d 到 %d 的最短距离是 %d\n",
                    source, i, dist[i]);
        }
    }

    // 找到未加入集合 S 的节点中距离起点最近的节点
    private static int minDistance(int[] dist, boolean[] visited) {
        int min = Integer.MAX_VALUE, minIndex = -1;

        for (int i = 0; i < dist.length; i++) {
            if (!visited[i] && dist[i] <= min) {
                min = dist[i];
                minIndex = i;
            }
        }

        return minIndex;
    }
}

3. Floyd 算法求最短路径

Floyd 算法是一种多源最短路径算法,它可以计算出任意两个节点之间的最短距离。

Floyd 算法的基本思想是:对于图中的每个节点,求出它与其他节点之间的最短路径。算法采用动态规划的思想,通过一个矩阵来记录任意两个节点之间的最短距离。

public class Floyd {
    public static void floyd(Graph graph) {
        int[][] edges = graph.getMatrix();
        int numVertices = graph.getNumVertices();

        // 构造一个与边权矩阵大小相同的数组,初始为边权矩阵
        int[][] shortestPaths = new int[numVertices][numVertices];

        for (int i = 0; i < numVertices; i++) {
            for (int j = 0; j < numVertices; j++) {
                shortestPaths[i][j] = edges[i][j];
            }
        }

        // 通过中间节点 k 来更新最短路径
        for (int k = 0; k < numVertices; k++) {
            for (int i = 0; i < numVertices; i++) {
                for (int j = 0; j < numVertices; j++) {
                    if (shortestPaths[i][k] + shortestPaths[k][j] < shortestPaths[i][j]) {
                        shortestPaths[i][j] = shortestPaths[i][k] + shortestPaths[k][j];
                    }
                }
            }
        }

        // 输出最短距离
        for (int i = 0; i < numVertices; i++) {
            for (int j = 0; j < numVertices; j++) {
                System.out.printf("从 %d 到 %d 的最短距离是 %d\n",
                        i, j, shortestPaths[i][j]);
            }
        }
    }
}

4. 示例说明

假设有如下图形:

     1
(0)--(1)--(2)
 |   / \   |
6|  /   \  |5
 | /     \ |
(3)-------(4)    9
       2   

使用邻接矩阵表示该图:

    0   1   2   3   4  
0   0   1   6   0   0  
1   1   0   5   2   7  
2   6   5   0   0   3  
3   0   2   0   0   4  
4   0   7   3   4   0  

如果以节点 0 为起点,采用 Dijkstra 算法,则最短路径为:

从 0 到 0 的最短距离是 0
从 0 到 1 的最短距离是 1
从 0 到 2 的最短距离是 6
从 0 到 3 的最短距离是 8
从 0 到 4 的最短距离是 15

如果采用 Floyd 算法,则最短路径为:

从 0 到 0 的最短距离是 0
从 0 到 1 的最短距离是 1
从 0 到 2 的最短距离是 6
从 0 到 3 的最短距离是 8
从 0 到 4 的最短距离是 15
从 1 到 0 的最短距离是 1
从 1 到 1 的最短距离是 0
从 1 到 2 的最短距离是 5
从 1 到 3 的最短距离是 2
从 1 到 4 的最短距离是 7
从 2 到 0 的最短距离是 6
从 2 到 1 的最短距离是 5
从 2 到 2 的最短距离是 0
从 2 到 3 的最短距离是 6
从 2 到 4 的最短距离是 3
从 3 到 0 的最短距离是 8
从 3 到 1 的最短距离是 2
从 3 到 2 的最短距离是 6
从 3 到 3 的最短距离是 0
从 3 到 4 的最短距离是 4
从 4 到 0 的最短距离是 15
从 4 到 1 的最短距离是 7
从 4 到 2 的最短距离是 3
从 4 到 3 的最短距离是 4
从 4 到 4 的最短距离是 0

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java利用Dijkstra和Floyd分别求取图的最短路径 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Java springboot 配置文件与多环境配置与运行优先级

    Java Spring Boot 是一个轻量级、快速开发微服务架构的框架,它提供了一种快速简便的方式来配置应用程序。不同的环境需要不同的配置,因此Spring Boot提供了多环境配置功能,同时我们也可以在配置文件中定制应用程序的运行优先级。 1. 配置文件 Spring Boot 提供了多种配置文件的支持,其中最常用的是 application.prope…

    Java 2023年5月19日
    00
  • Tomcat 部署项目的三种方法详解

    当我们完成了一个 Java Web 项目的开发之后,接下来就需要将项目部署到服务器上面,让用户能够通过网络访问到我们的应用。那么,如何将 Java Web 项目部署到 Tomcat 服务器上呢?以下是 Tomcat 部署项目的三种方法详解: 方法一:将 War 包复制到 Tomcat 的 Webapps 目录下 将 War 包复制到 Tomcat 安装目录中…

    Java 2023年5月19日
    00
  • 一文带你深入了解Java的数据结构

    一文带你深入了解Java的数据结构 什么是数据结构 数据结构是指数据如何在计算机中组织和存储的方式。在计算机科学中,数据结构是一种特殊的格式化数据,使得计算机程序能够高效地访问和修改数据。其中,常用的数据结构有数组、链表、栈、队列、树等。 Java的数据结构 Java中自带了一些数据结构类库,例如:Collection、List、Set、Map等。这些数据结…

    Java 2023年5月23日
    00
  • JAVA CountDownLatch(倒计时计数器)用法实例

    JAVA CountDownLatch(倒计时计数器)用法实例 什么是 CountDownLatch CountDownLatch(倒计时计数器)是 Java 提供的一个同步工具类,通过它可以让一个或多个线程等待其它线程完成各自的工作后再继续执行。 在 CountDownLatch 中,我们可以设置一个计数器的初始值 n,然后调用 countDown() 方…

    Java 2023年5月20日
    00
  • 微信小程序登录态和检验注册过没的app.js写法

    微信小程序登录态和检验注册的实现涉及到小程序端的代码和服务端的代码,因此在您进行开发时需要分别处理。 实现登录态 小程序的登录态是通过wx.login()获取的,具体实现步骤如下: 在小程序中,在需要登录的页面中,首先调用wx.login()获取到微信返回的code码,然后使用wx.request()将该code码发送到服务端。以下是示例代码: wx.log…

    Java 2023年5月23日
    00
  • 基于java实现画图板功能

    下面我将详细讲解“基于Java实现画图板功能”的完整攻略。 1. 确定项目需求 首先,我们需要明确项目的需求。画图板的主要功能有绘制基础图形(如线、矩形、圆形、椭圆等)、编辑已绘制图形(包括拖动、改变大小等操作)、实现撤销和重做等操作。我们需要仔细分析需求,确定实现细节,以指导后续的开发。 2. 选择合适的开发工具 接下来,我们需要选择合适的开发工具。Jav…

    Java 2023年5月23日
    00
  • 如何在Java程序中访问mysql数据库中的数据并进行简单的操作

    让我们来讲解如何在Java程序中访问MySQL数据库中的数据并进行简单的操作。 步骤一:下载并安装MySQL连接器 在开始编写Java程序之前,需要下载并安装MySQL的JDBC驱动程序。可以在MySQL官方网站下载最新版本的MySQL连接器。下载完成后,将.jar文件添加到Java项目的类路径中。 步骤二:创建数据库连接 在Java程序中连接MySQL数据…

    Java 2023年5月19日
    00
  • Ajax实现注册并选择头像后上传功能

    下面我将详细讲解“Ajax实现注册并选择头像后上传功能”的完整攻略。 实现步骤 1. 注册功能 首先,在前端页面中设计一个注册表单,表单中包含必要的字段,例如“用户名”、“密码”、“邮箱”等。当用户填写完表单后,通过Ajax将表单数据提交到后台进行处理。后台需要对用户提交的信息进行验证,例如判断用户名是否已存在、判断邮箱格式是否正确等等。若验证通过,则在后台…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部