java使用Dijkstra算法实现单源最短路径

Java使用Dijkstra算法实现单源最短路径攻略

算法简介

Dijkstra算法是一种经典的计算图的单源最短路径的算法。它的基本思想是从起始点开始,首先确定该点到其他所有点的最短距离,然后以最短距离作为中介点,依次直到所有点的最短路径都被确定。Dijkstra算法主要应用在网络路由、航空等行业中。

算法步骤

  • 将图中节点分为两个集合:已确定路径的节点集合和未确定路径的节点集合,分别使用两个数组visited和distance记录。
  • 初始化过程:设置起始节点为已确定路径的节点,将其distance值设置为0,将所有其他节点的distance值设置为正无穷。
  • 重复以下过程,直到所有节点都被添加到已确定的路径集合中:
    • 从未确定路径的节点集合中选出当前distance值最小的节点,将其加入到已确定的路径集合中。
    • 更新该节点的相邻节点的distance值,如果distance变短了,则更新其父节点和最短路径。

Java代码实现

以下代码实现了Dijkstra算法,用于求解最短路径。图使用邻接矩阵来表示,Graph类包含两个方法:dijsktra方法用于求解最短路径,printResult方法用于输出结果。

public class Graph {
    private int vertexCount;
    private int[][] adjacencyMatrix;

    public Graph(int vertexCount) {
        this.vertexCount = vertexCount;
        this.adjacencyMatrix = new int[vertexCount][vertexCount];
    }

    public void dijkstra(int sourceVertex) {
        boolean[] visited = new boolean[vertexCount];
        int[] distance = new int[vertexCount];

        for (int i = 0; i < vertexCount; i++) {
            distance[i] = Integer.MAX_VALUE;
        }

        distance[sourceVertex] = 0;

        for (int i = 0; i < vertexCount - 1; i++) {
            int minDistance = Integer.MAX_VALUE;
            int minDistanceVertex = -1;

            for (int j = 0; j < vertexCount; j++) {
                if (!visited[j] && distance[j] < minDistance) {
                    minDistance = distance[j];
                    minDistanceVertex = j;
                }
            }

            visited[minDistanceVertex] = true;
            for (int k = 0; k < vertexCount; k++) {
                int edgeDistance = adjacencyMatrix[minDistanceVertex][k];
                if (edgeDistance > 0 && ((minDistance + edgeDistance) < distance[k])) {
                    distance[k] = minDistance + edgeDistance;
                }
            }
        }

        printResult(distance, sourceVertex);
    }

    public void printResult(int[] distance, int sourceVertex) {
        System.out.println("最短路径从起点 " + sourceVertex + " 到各点的距离:");
        for (int i = 0; i < vertexCount; i++) {
            System.out.println("点 " + i + ": 距离 = " + distance[i]);
        }
    }

    public static void main(String[] args) {
        Graph graph = new Graph(9);
        graph.adjacencyMatrix = new int[][]{ {0, 4, 0, 0, 0, 0, 0, 8, 0},
                                             {4, 0, 8, 0, 0, 0, 0, 11, 0},
                                             {0, 8, 0, 7, 0, 4, 0, 0, 2},
                                             {0, 0, 7, 0, 9, 14, 0, 0, 0},
                                             {0, 0, 0, 9, 0, 10, 0, 0, 0},
                                             {0, 0, 4, 14, 10, 0, 2, 0, 0},
                                             {0, 0, 0, 0, 0, 2, 0, 1, 6},
                                             {8, 11, 0, 0, 0, 0, 1, 0, 7},
                                             {0, 0, 2, 0, 0, 0, 6, 7, 0}};
        graph.dijkstra(0);
    }
}

示例说明

以下是一个基于上述代码实现的示例:

假设有以下图中的图,其中矩阵元素代表两点间的距离,0表示自身或不连通。

{0, 4, 0, 0, 0, 0, 0, 8, 0},
{4, 0, 8, 0, 0, 0, 0, 11, 0},
{0, 8, 0, 7, 0, 4, 0, 0, 2},
{0, 0, 7, 0, 9, 14, 0, 0, 0},
{0, 0, 0, 9, 0, 10, 0, 0, 0},
{0, 0, 4, 14, 10, 0, 2, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 6},
{8, 11, 0, 0, 0, 0, 1, 0, 7},
{0, 0, 2, 0, 0, 0, 6, 7, 0}

我们将起点设置为节点0,执行dijkstra方法,可以得到最短路径为:

最短路径从起点 0 到各点的距离:
点 0: 距离 = 0
点 1: 距离 = 4
点 2: 距离 = 12
点 3: 距离 = 19
点 4: 距离 = 21
点 5: 距离 = 11
点 6: 距离 = 9
点 7: 距离 = 8
点 8: 距离 = 14

这意味着从节点0到节点8的最短路径为14,该路径穿过节点7。

另一个示例,我们将起点设置为节点8,执行dijkstra方法:

最短路径从起点 8 到各点的距离:
点 0: 距离 = 14
点 1: 距离 = 19
点 2: 距离 = 2
点 3: 距离 = 6
点 4: 距离 = 14
点 5: 距离 = 12
点 6: 距离 = 6
点 7: 距离 = 7
点 8: 距离 = 0

这意味着从节点8到节点2的最短路径为2,该路径穿过节点5。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java使用Dijkstra算法实现单源最短路径 - Python技术站

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

相关文章

  • Java通过Lambda表达式实现简化代码

    下面是Java通过Lambda表达式实现简化代码的攻略: 1. 什么是Lambda表达式 Lambda表达式是Java 8中推出的一种新语法,用于简化Java代码。Lambda表达式可以理解成一种匿名函数,可以像变量一样将它们传递给方法,并在调用时使用。Lambda表达式可以将代码写得更简练、更易读、更易维护。 2. Lambda表达式的语法 Lambda表…

    Java 2023年5月30日
    00
  • springboot的java配置方式(实例讲解)

    下面给出SpringBoot的Java配置方式的详细攻略: 1. 什么是Java配置方式? SpringBoot提供了三种配置方式:XML配置方式、注解配置方式和Java配置方式。Java配置方式是一种纯粹的编程式的方式,通过Java类的方式来完成Bean的配置,相比于XML和注解更加灵活。Java配置方式的主要思想就是用一个Java类替代了XML配置文件或…

    Java 2023年5月15日
    00
  • MySQL之JSON类型字段的使用技巧分享

    MySQL之JSON类型字段的使用技巧分享 在MySQL 5.7及以上版本中,除了常见的数据类型之外,还新增了一个JSON类型字段。JSON类型的字段可以存储JSON格式的数据,对于存储半结构化数据非常方便。本文将详细讲解JSON类型字段的使用技巧,包括JSON格式、创建、插入、更新、查询等操作。 1. JSON格式的数据 JSON(JavaScript O…

    Java 2023年5月26日
    00
  • 详解Java代码常见优化方案

    详解Java代码常见优化方案 Java作为一门常用的编程语言,其代码的性能优化是开发过程中需要考虑的一项重要问题。本文将分析常见的Java代码优化方案,以及如何在实际项目中应用这些优化方案,提高程序的运行效率。 1. 合理使用变量 在Java中,变量使用的不合理将会带来很多性能问题。例如,如果在循环中声明一个大对象,将会带来显著的内存压力,降低程序的运行效率…

    Java 2023年5月23日
    00
  • js中let能否完全替代IIFE

    首先,让我们了解一下IIFE(Immediately Invoked Function Expression)和let的定义。 IIFE是一种JavaScript函数,它可以立即执行,并且只执行一次。通常在IIFE中定义局部变量,可以避免全局变量的污染。 let是ES6中引入的块级作用域声明变量的关键字,可以定义块级作用域中的变量。 那么,js中let能否完…

    Java 2023年6月15日
    00
  • springboot全局异常处理代码实例

    下面就给您详细讲解一下“springboot全局异常处理代码实例”的完整攻略。 什么是SpringBoot全局异常处理 SpringBoot是一种非常流行的Java Web框架,它具有快速构建应用、开箱即用等优点。然而,当我们的应用出现错误时,如果不进行有效的异常处理,就会给用户带来不好的使用体验。SpringBoot提供了全局异常处理机制,可以针对应用中的…

    Java 2023年5月27日
    00
  • java高级用法之绑定CPU的线程Thread Affinity简介

    Java高级用法之绑定CPU的线程Thread Affinity简介 什么是Thread Affinity? Thread Affinity(线程亲和性)是指将一个线程绑定到一个指定的 CPU 上面,使得线程只在这个特定的 CPU 上运行。在高性能计算和计算机游戏等领域,Thread Affinity 被广泛使用,以提高应用的执行效率。 Thread Aff…

    Java 2023年5月19日
    00
  • java字符转码的三种方法总结及实例

    它们是: Java字符转码的三种方法总结及实例 在Java编程中,处理字符编码转换是常见的任务。不正确或不一致的字符编码转换可能导致各种问题,例如乱码、字符截断或不完整等等。因此,我们必须正确、准确地处理字符编码转换。本文将介绍3种常用的Java字符转码方法,并提供相关示例以方便理解和实践。 1. 使用Java内置的Charset类 该方法主要利用了Java…

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