迪杰斯特拉(Dijkstra)算法求最短路径

2023-11-19

一.最短路径

  • 从某顶点(源点)出发到另一顶点(目的地)的路径中,有一条各边(或弧)权值之和最小的路径称为最短路径
  • 迪杰斯特拉算法:从单原点到其余各店的最短路径

二.基本思想

依最短路径的长度递增的次序求得各条路径。其中,从源点到顶点v的最短路径是所有最短路径中长度最短者

  • 路径长度最短的最短路径的特点:
    在这条路上,必定只含一条弧,并且这条弧的权值最小(记为v0->v1)
  • 下一条路径长度次短的最短路径的特点:
    或者是直接从源点到该点(只含一条弧)
    或者是从源点经过顶点v1,再到达该顶点(由两条弧组成)(v0->v1->v2)
  • 再下一条路径长度次短的的最短路径的特点:
    或者是直接从源点到该点(只含一条弧)
    或者是从源点经过顶点v1,再到达该顶点(由两条弧)
    或者是从源点经过顶点v2,再到达该顶点(看v2的情况,第一种就两条弧,第二种就三条弧)
  • 重复步骤

三.步骤图解

在这里插入图片描述
在这里插入图片描述

步骤:

S中存放的是已经求得的最短路径的终点的集合,v-s集合包含其他点
i代表第i条最短路径(及可能路径走法)
邻接矩阵表示弧<vi,vj>上的权值
dist[i]值

若vi在S中,dist[i]表示源点到vi的最短路径长度
若vi在V-S中,dist[i]表示源点到vi的只包括S中的顶点为中间顶点的最短路径

  1. 找路径长度最短的最短路径,首先看从0开始弧度为1的点,列出即为v0->v2,v0->v4,v0->v5.以及它们的权值(即表格第一列)在第一列中找出第一条最短路径是v0->v2权值为10,画上对号。那么此时v0到v2的最短路径就找到了,v2一行可以省略了
  2. 继续以v2为顶点查找下一步可行路线,由邻接矩阵或者直接看图找,可得v0->v2->v3将此路线及它的权值与之前找到的最短路径(第一列剩下的路径)做比较,即从V-S中找出路径最短的顶点(即为v4),并将其加入到S中;接着,更新V-S中的顶点和顶点对应的路径(即第三步以v4为顶点查找)
  3. 以v4为顶点查找下一步,与上相同,从V-S中找出路径,相互比较,找出最小的(v3),并将其加入到S中;接着,更新V-S中的顶点和顶点对应的路径。
  4. 重复步骤,最终完成,找出来每次的最短路径,将所有可以到达的点都包含在S中。

四.代码说明

    /*
 * Dijkstra最短路径。
 * 即,统计图(G)中"顶点vs"到其它各个顶点的最短路径。
 *
 * 参数说明:
 *        G -- 图
 *       vs -- 起始顶点(start vertex)。即计算"顶点vs"到其它顶点的最短路径。
 *     prev -- 前驱顶点数组。即,prev[i]的值是"顶点vs"到"顶点i"的最短路径所经历的全部顶点中,位于"顶点i"之前的那个顶点。
 *     dist -- 长度数组。即,dist[i]是"顶点vs"到"顶点i"的最短路径的长度。
 */
void dijkstra(Graph G, int vs, int prev[], int dist[])
{
    int i,j,k;
    int min;
    int tmp;
    int flag[MAX];      // flag[i]=1表示"顶点vs"到"顶点i"的最短路径已成功获取。
 
    // 初始化
    for (i = 0; i < G.vexnum; i++)
    {
        flag[i] = 0;              // 顶点i的最短路径还没获取到。
        prev[i] = 0;              // 顶点i的前驱顶点为0。
        dist[i] = G.matrix[vs][i];// 顶点i的最短路径为"顶点vs"到"顶点i"的权。
    }
 
    // 对"顶点vs"自身进行初始化
    flag[vs] = 1;
    dist[vs] = 0;
 
    // 遍历G.vexnum-1次;每次找出一个顶点的最短路径。
    for (i = 1; i < G.vexnum; i++)
    {
        // 寻找当前最小的路径;
        // 即,在未获取最短路径的顶点中,找到离vs最近的顶点(k)。
        min = INF;
        for (j = 0; j < G.vexnum; j++)
        {
            if (flag[j]==0 && dist[j]<min)
            {
                min = dist[j];
                k = j;
            }
        }
        // 标记"顶点k"为已经获取到最短路径
        flag[k] = 1;
 
        // 修正当前最短路径和前驱顶点
        // 即,当已经"顶点k的最短路径"之后,更新"未获取最短路径的顶点的最短路径和前驱顶点"。
        for (j = 0; j < G.vexnum; j++)
        {
            tmp = (G.matrix[k][j]==INF ? INF : (min + G.matrix[k][j])); // 防止溢出
            if (flag[j] == 0 && (tmp  < dist[j]) )
            {
                dist[j] = tmp;
                prev[j] = k;
            }
        }
    }
 
    // 打印dijkstra最短路径的结果
    printf("dijkstra(%c): \n", G.vexs[vs]);
    for (i = 0; i < G.vexnum; i++)
        printf("  shortest(%c, %c)=%d\n", G.vexs[vs], G.vexs[i], dist[i]);
}



参考文章
文章中附有迪杰斯特拉(Dijkstra)算法源码

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

迪杰斯特拉(Dijkstra)算法求最短路径 的相关文章

随机推荐

  • Nacos下载安装与配置(windows)

    一 Nacos下载 外网不好下载以下提供了两个版本 官网地址 https nacos io zh cn 蓝奏云地址 nacos server 1 4 1 zip 蓝奏云 1 4 1 版本 windows nacos server 2 0 0
  • 像智能手机一样造车,可能吗?

    造车这件事有多火 从小鹏 理想等昔日 造车新势力 在互联网军团的入局浪潮中 都变成了 前浪 就可见一斑 春节前后 我们见证了一波波互联网企业在汽车领域的布局 百度与吉利组建合资公司 苹果传出与韩国现代合作 阿里与上汽的智己汽车注册不到20天
  • 2023年VSCode插件最新推荐(54款)

    本文介绍前端开发领域常用的一些VSCode插件 插件是VSCode最重要的组成部分之一 本文列出了我自己在以往工作经验中积累的54款插件 个人觉得这些插件是有用或有趣的 根据它们的作用 我粗略的把它们分成了代码管理 文本和图片处理 前端框架
  • 端到端学习在车辆测距中的探索与实践

    yolo车距1 订阅车距专栏获得源码 http t csdn cn sU3U6 随着深度学习技术的快速发展 端到端学习在计算机视觉领域取得了显著的成果 端到端学习是一种直接从输入数据到输出结果的模型训练方法 无需进行复杂的特征工程 在车辆测
  • 【Arduino学习】05.驱动4个数码管

    数码管介绍 如图 本次使用的数码管为共阴极 四个数码管有 12 个引脚 可以分为位选脚和段选脚 段选脚 8个引脚a b c d e f g 位选脚 4 个引脚 D1 D2 D3 D4 哪个数码管显示由片选脚决定 片选脚为高电平 则该数码管点
  • 九宫格人车识别

    一 原理 通过霍夫检测圆的个数来识别小人位置 二 过程 1 二值图像 2 去掉宫格内容 便于分割 3 对二值图填补 减少纹理 4 分割九宫格 依次检测每个宫格中圆个数 5 最终显示小人所在宫格图片 在img6 jpg中 详细程序运行结果 三
  • xshell连接提示Linux服务器发送了一个意外的数据包

    服务器发送了一个意外的数据包received 3 expected 20 打开需要连接的Linux主机 编辑vim etc ssh sshd config 在最后一行添加 KexAlgorithms curve25519 sha256 li
  • Java通过自定义类加载器模拟冰蝎免杀功能

    一 Java类加载器 类加载器属于JVM的一个重要知识点 也是Java安全里命令执行 webshell管理器编写的常用技术 类加载器简介 我们知道java源文件在运行前会被编译为class类文件 存放着编译后JVM虚拟机指令的二进制字节流
  • 字符编码悉知

    1 查看windows系统代码页 代码页是字符集编码的别名 也有人称 内码表 早期 代码页是IBM称呼电脑BIOS本身支持的字符集编码的名称 当时通用的操作系统都是命令行界面系统 这些操作系统直接使用BIOS供应的VGA功能来显示字符 操作
  • BrokenPipeError: [Errno 32] Broken pipe

    运行Pytorch tutorial代码报错 BrokenPipeError Errno 32 Broken pipe 源代码地址 Training a classifier CIFAR10 该问题的产生是由于windows下多线程的问题
  • QMap遍历(修改)

    方法一 STL风格的遍历器 个人较常用 直观易读 方便修改值 QMap
  • 解决 MDK keil 注册中出现 TOOLS.INI TOOLCHAIN NOT INSTALLED 办法

    MDK Keil 兼容 C51 Keil 我们的电脑有32位系统和64位系统 当keil出现这个错误时 可以按以下办法解决 有两种解决办法 第一种 同时安装MDK Keil 和 C51 Keil 有可能解决此问题 安装必须路径相同 第二种
  • leetcode-合并两个有序链表(详解)

    合并两个有序链表 前言 一 题链接 题意 题思路 题思路图解 题代码 总结 前言 路漫漫及修远兮 一 题链接 题意 将两个升序链表合并为一个新的 升序 链表并返回 新链表是通过拼接给定的两个链表的所有节点组成的 输入 l1 1 2 4 l2
  • 【车道线】TwinLiteNet 复现过程全纪录

    码字不易 喜欢的请点赞收藏 论文全文翻译 freespace TwinLiteNet An Efficient and Lightweight Model for Driveable Area and Lane Segmentation 莫
  • 虹软人脸识别 - ArcFace SDK介绍及使用注意事项

    很多朋友在开发人脸识别系统的时候 会遇到各种各样的问题 现在我们以安卓平台使用虹软的免费离线人脸识别SDK开发为例 给大家介绍一下如何开发一个带有图片的人脸检测 视频画面的人脸属性检测 人脸注册识别等功能的人脸识别系统 一 获取SDK 1
  • [rk3588]多种wifi模组兼容

    硬件部分 M 2接口 使用的wifi模组是PCIE接口的RTL8852BE和SDIO接口的AP6256 软件部分 M 2接口介绍 M 2接口是一种用于连接各种扩展设备的接口标准 它最初设计用于连接固态硬盘 SSD 但也广泛用于连接其他设备
  • spark hadoop环境及运行

    hadoop配置 在Ubuntu20 04里安装Hadoop详细步骤 图文 亲测成功 ubuntu20 04安装hadoop 菜鸡的学习之路的博客 CSDN博客 启动hadoop root ubuntu usr local hadoop s
  • 服务器处理发生异常:java.text.ParseException: Unparseable date

    测试上传报文的时候遇见报错 服务器处理发生异常 java text ParseException Unparseable date 2023 03 03 错误报文 实际需要的报文 错误原因 上传时间字段 与Date字段数据位数不匹配 Jav
  • python贝叶斯网络预测模型_高效灵活的概率建模方法基于Python

    前言 在今天给大家介绍一个研究工具 pomegranate 它比其他软件包更加灵活 更快 直观易用 并且可以在多线程中并行完成 The API 主要模型介绍一般混合模型 隐马尔可夫模型 贝叶斯网络 贝叶斯分类器 所有模型使用做多的方法 mo
  • 迪杰斯特拉(Dijkstra)算法求最短路径

    文章目录 一 最短路径 二 基本思想 三 步骤图解 步骤 S中存放的是已经求得的最短路径的终点的集合 v s集合包含其他点 i代表第i条最短路径 及可能路径走法 邻接矩阵表示弧 一 最短路径 从某顶点 源点 出发到另一顶点 目的地 的路径中