Dijkstra算法实现(java)

这篇具有很好参考价值的文章主要介绍了Dijkstra算法实现(java)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、Dijkstra算法介绍

  Dijkstra(迪杰斯特拉)算法是求解单源最短路径的经典算法,其原理也是基于贪心策略的。

二、Dijkstra算法原理

  Dijkstra算法设置一个集合 S S S记录已求得的最短路径的顶点,初始时把源点 v 0 v_{0} v0放入 S S S,集合 S S S每并入一个新顶点 v i v_{i} vi,都要修改源点 v 0 v_{0} v0到集合 V − S V-S VS中顶点当前的最短路径长度值。
  在构造的过程中还设置了两个辅助数组:

(1)dist[]:记录从源点 v 0 v_{0} v0到其他各顶点当前的最短路径长度,它的初态为:若从 v 0 v_{0} v0 v i v_{i} vi有弧,则dist[i]为弧上的权值;否则置dist[i]为 ∞ ∞
(2)path[]: path[i]表示从源点到顶点i之间的最短路径的前驱结点。在算法结束时,可根据其值追溯得到源点 v 0 v_{0} v0到顶点 v i v_{i} vi的最短路径。

  假设从顶点0出发,即 v 0 = 0 v_{0}=0 v0=0,集合 S S S最初只包含顶点0,邻接矩阵arcs表示带权有向图,若不存在有向边<i,j>,则arcs [i][j]arcs[i][j]表示有向边<i,j>的权值 ∞ ∞
  Dijkstra算法的步骤如下(不考虑对path[]的操作):

1)初始化:集合S初始为{0},dist[]的初始值dist[i]=arcs[0][i];i=1,2,…,n-1
2)从顶点集合V-S中选出 v j v_{j} vj,满足dist[j]=Min {dist[i]} v i ∈ V − S v_{i} \in V-S viVS v j v_{j} vj就是当前求得的一条从 v 0 v_{0} v0出发的最短路径的终点,令 S = S ∪ j S=S\cup {j} S=Sj
3)修改从 v 0 v_{0} v0出发到集合V-S上任一顶点 v k v_{k} vk可达的最短路径长度:若dist[j]+arcs[j][k]<dist[k],则更新dist [k]=dist[j]+arcs[j][k]
4)重复2)~3)操作共n-1次,直到所有的顶点都包含在S中。

步骤3),每当一个顶点加入S后,可能需要修改源点 v 0 v_{0} v0到集合V-S中可达顶点当前的最短路径长度,下面举一简单例子证明。如下图所示,源点为 v 0 v_{0} v0,初始时S={ v 0 v_{0} v0},dist[1]=4,dist[2]=8,当将 v 1 v_{1} v1并入集合S后,dist[2]需要更新为6。
Dijkstra算法实现(java)

三、Dijkstra算法示例

Dijkstra算法实现(java)

顶点 第1轮 第2轮 第3轮 第4轮
2 10( v 1 v_{1} v1-> v 2 v_{2} v2 8( v 1 v_{1} v1-> v 5 v_{5} v5-> v 2 v_{2} v2 8( v 1 v_{1} v1-> v 5 v_{5} v5-> v 2 v_{2} v2
3 ∞ ∞ 14( v 1 v_{1} v1-> v 5 v_{5} v5-> v 3 v_{3} v3 13( v 1 v_{1} v1-> v 5 v_{5} v5-> v 4 v_{4} v4-> v 3 v_{3} v3 9( v 1 v_{1} v1-> v 5 v_{5} v5-> v 2 v_{2} v2-> v 3 v_{3} v3
4 ∞ ∞ 7( v 1 v_{1} v1-> v 5 v_{5} v5-> v 4 v_{4} v4
5 5( v 1 v_{1} v1-> v 5 v_{5} v5
集合S {1,5} {1,5,4} {1,5,4,2} {1,5,4,2,3}

  从顶点1开始,每次将最短路径的顶点加入集合,根据集合中已有是的顶点,寻找到各个顶点的最短路径。文章来源地址https://www.toymoban.com/news/detail-403971.html

四、代码实现

package com.haiyang.algorithm.dijkstra;

import com.sun.corba.se.impl.orbutil.graph.Graph;

import java.util.Arrays;

/**
 * @author haiYang
 * @create 2022-02-03 10:33
 */
public class DijkstraAlgorithm {
    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;// 表示不可以连接
        /*                    1  2  3  4   5   */
        matrix[0] = new int[]{N, 10, N, N, 5};/*1*/
        matrix[1] = new int[]{N, N, 1, N, 2};/*2*/
        matrix[2] = new int[]{N, N, N, 4, N};/*3*/
        matrix[3] = new int[]{7, N, 6, N, N};/*4*/
        matrix[4] = new int[]{N, 3, 9, 2, N};/*5*/


        //创建 Graph对象
        DGraph graph = new DGraph(vertex, matrix);
        //测试, 看看图的邻接矩阵是否ok
        graph.showGraph();
        //测试迪杰斯特拉算法
        graph.dijkstra(0);
        graph.showDijkstra('A', 'C');


    }


}

//已访问顶点集合
class VisitedVertex {
    //记录各个顶点是否访问,1表示访问过,0表示未访问过
    public int[] alreadyVertex;
    //表示从源点到顶点i之间的最短路径的前驱结点
    public int[] path;
    //记录从源点到其他各个顶点当前的最短路径长度
    public int[] dist;

    /**
     * 构造器
     *
     * @param vertexNum   顶点数目
     * @param vertexIndex 顶点索引(顶点数组对应的下标)
     */
    public VisitedVertex(int vertexNum, int vertexIndex) {
        this.alreadyVertex = new int[vertexNum];
        this.path = new int[vertexNum];
        this.dist = new int[vertexNum];

        //初始化dist数组,顶点i到其他顶点的距离初始为65536,到自己的距离初始为0。
        Arrays.fill(dist, 65535);
        dist[vertexIndex] = 0;
        //初始顶点已访问
        this.alreadyVertex[vertexIndex] = 1;
    }

    /**
     * 判断该顶点是否已经访问过
     *
     * @param vertexIndex 顶点索引
     * @return
     */
    public boolean isVisited(int vertexIndex) {
        return alreadyVertex[vertexIndex] == 1;
    }

    /**
     * 更新源点到目标顶点的最短路径长度
     *
     * @param objectiveVertexIndex  目标顶点索引
     * @param objectiveVertexLength 目标顶点长度
     */
    public void updateDist(int objectiveVertexIndex, int objectiveVertexLength) {
        dist[objectiveVertexIndex] = objectiveVertexLength;
    }

    /**
     * 更新源点到该顶点最短路径下,该顶点的前驱顶点
     *
     * @param preVertexIndex 前驱顶点
     * @param VertexIndex    该顶点
     */
    public void updatePath(int VertexIndex, int preVertexIndex) {
        path[VertexIndex] = preVertexIndex;
    }

    /**
     * 返回源点到该顶点的上一次更新的最短路径
     * 用于判断此次是否更新最短路径长度
     *
     * @param vertexIndex
     * @return
     */
    public int getDist(int vertexIndex) {
        return dist[vertexIndex];
    }

    /**
     * 寻找与源点之间最短距离且未访问顶点的索引
     *
     * @return
     */
    public int updateArr() {
        int min = 65536, index = 0;
        for (int i = 0; i < alreadyVertex.length; i++) {
            if (alreadyVertex[i] == 0 && dist[i] < min) {
                min = dist[i];
                index = i;
            }
        }
        alreadyVertex[index] = 1;
        return index;
    }

    public void show(char begin, char end) {
        System.out.println("===================");
        int beginIndex = 0;
        int endIndex = 0;
        char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
        for (int i = 0; i < vertex.length; i++) {
            if (vertex[i] == begin) {
                beginIndex = i;
            }
            if (vertex[i] == end) {
                endIndex = i;
            }
        }

        System.out.println(begin + " -> " + end + "的最短距离为:" + dist[endIndex]);
        System.out.print(begin + " -> " + end + "的最短路径为:");
        showPath(beginIndex, endIndex);
        System.out.println(vertex[endIndex]);


    }

    /**
     * 通过递归遍历先驱数组path返回最短路径
     *
     * @param beginIndex
     * @param endIndex
     */
    private void showPath(int beginIndex, int endIndex) {
        char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
        if (path[endIndex] == beginIndex) {
            System.out.print(vertex[beginIndex] + " -> ");
            return;
        } else {
            showPath(beginIndex, path[endIndex]);
        }
        System.out.print(vertex[path[endIndex]] + " -> ");
    }

}

class DGraph {
    private char[] vertex;//顶点数组
    private int[][] arcs;//邻接矩阵
    private VisitedVertex visitedVertex;


    public DGraph(char[] vertex, int[][] arcs) {
        this.vertex = vertex;
        this.arcs = arcs;
    }

    public void showGraph() {
        for (int[] link : arcs) {
            System.out.println(Arrays.toString(link));
        }
    }

    /**
     * dijkstra算法
     *
     * @param index 出发顶点的下标
     */
    public void dijkstra(int index) {
        visitedVertex = new VisitedVertex(vertex.length, index);
        update(index);
        for (int i = 1; i < vertex.length; i++) {
            index = visitedVertex.updateArr();
            update(index);
        }

    }

    //更新index下标顶点到周围顶点的距离和周围顶点的前驱顶点
    public void update(int index) {
        int len = 0;
        //根据邻接矩阵找到邻接顶点
        for (int i = 0; i < arcs[index].length; i++) {
            //从出发顶点到index顶点的距离+ 从index顶点到i顶点的距离的和
            len = visitedVertex.getDist(index) + arcs[index][i];
            if (!visitedVertex.isVisited(i) && len < visitedVertex.getDist(i)) {
                visitedVertex.updatePath(i, index);//更新前驱顶点
                visitedVertex.updateDist(i, len); //更新最短距离
            }

        }

    }

    public void showDijkstra(char begin, char end) {
        visitedVertex.show(begin, end);
    }

}

到了这里,关于Dijkstra算法实现(java)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 自动驾驶算法(一):Dijkstra算法讲解与代码实现

    目录 0 本节:栅格地图、算法、路径规划 1 Dijkstra算法详解 2 Dijkstra代码详解         用于图中寻找最短路径。节点是地点,边是权重。         从起点开始逐步扩展,每一步为一个节点找到最短路径:         While True:                 1.从未访问的节

    2024年02月06日
    浏览(43)
  • Dijkstra算法——邻接矩阵实现+路径记录

    本文是在下面这篇文章的基础上做了一些补充,增加了路径记录的功能。具体Dijkstra的实现过程可以参考下面的这篇文章。 [jarvan:Dijkstra算法详解 通俗易懂](Dijkstra算法详解 通俗易懂 - jarvan的文章 - 知乎 https://zhuanlan.zhihu.com/p/338414118) 创建 GraphAdjMat 类 GraphAdjMat 类用来实现图的

    2024年01月18日
    浏览(42)
  • 【路径规划】全局路径规划算法——Dijkstra算法(含python实现 | c++实现)

    路径规划与轨迹跟踪系列算法学习 最短路径算法-迪杰斯特拉(Dijkstra)算法 迪杰斯特拉dijkstra算法的python实现 Python实现迪杰斯特拉算法 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个节点遍历其余各节点的最短路

    2024年02月08日
    浏览(48)
  • 基于Dijkstra算法实现无人机三维路径规划

    基于Dijkstra算法实现无人机三维路径规划 无人机在飞行任务中往往需要寻找一条最优路径以达到最佳的飞行效果。而在三维空间中,路径规划问题变得更加复杂。本文将介绍如何基于Dijkstra算法来解决无人机三维路径规划问题,并且提供相应的matlab代码。 一、Dijkstra算法简介

    2024年02月14日
    浏览(66)
  • 用matlab实现Dijkstra算法,内附函数详解

            学习数学建模清风大佬课程时,在图论章节中清风大佬留下了让我们手搓dijkstra算法的任务,笔者翻阅了CSDN和B站视频,再加上自己对代码和matlab的理解,手搓了一版dijkstra算法函数,代码如果有考虑不周,欢迎各位看官指出!!!         首先,还是来先了解

    2024年02月04日
    浏览(40)
  • 数据结构(12)Dijkstra算法JAVA版:图的最短路径问题

    目录 12.1.概述 12.1.1.无权图的最短路径  12.1.2.带权图的最短路径 1.单源最短路径 2.多源最短路径 12.2.代码实现 无权图的最短路径,即最少步数,使用BFS+贪心算法来求解最短路径,比较好实现,此处不做展开讨论。 有权图的最短路径,不考虑权重为负数的情况,因为权重为负

    2024年02月06日
    浏览(48)
  • Dijkstra’s 最短路径算法的 Matlab实现

    随机生成400个点,再去除其中的120个点作为‘路障’。采用dijkstra算法寻找最短路径。   思路: step1:定义地图大小/内容 step2:把随机生成的‘视觉地图’信息载入‘矩阵地图’ step3:使用dijkstra原理寻找最短路径 step4:连点成线 把 ‘视觉地图’ 信息载入矩阵的原理/逻辑

    2024年02月07日
    浏览(43)
  • ROS:move_base路径规划介绍、更换全局路径规划算法(A star、Dijkstra、DWA,测试当前是哪种算法,效果展示图)

    前提: 需要安装navigation包 ,才可以运行move_base。 move_base包默认算法: 全局路径规划:Dijkstra; 局部路径规划:航迹推算; A*、Dijkstra属于全局路径规划、DWA属于局部路径规划。 move_base.launch文件需要 添加以下内容 : 整体的move_base.launch文件内容如下(其中 turtlebot3_navigati

    2024年02月08日
    浏览(227)
  • 【FPGA开源项目分享】中国铁路网的 Dijkstra 算法实现

    如果本文图片和视频无法显示,请直接跳转到 友晶科技公众号FPGA开源项目分享——中国铁路网的 Dijkstra 算法实现 阅读原文。 常春藤名校之一——康奈尔大学有一门名叫ECE 5760的FPGA 课程,网站( Final Projects ECE 5760)公开了该课程讲师Bruce Land与学生们的项目作品(包含源码

    2024年01月19日
    浏览(47)
  • 数据结构与算法 —— 最短路径Dijkstra算法(迪杰斯特拉)详细图解以及python实现

    目录 前言 1. 介绍 2. 加权图 2.1 概念 3. 最短路径 -- Dijkstra 算法 3.1 历史 3.2 Dijkstra 算法的基本思路 3.3 Dijkstra 算法图解 4.  python中dijkstra算法的实现 5. 总结  前两章我们讲到了关于图的基本知识,和广度/深度优先搜索。 本章,我们将介绍 加权图 和 最短路径 的相关知识。 最

    2024年02月12日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包