广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >Dijkstra算法原理及C++怎么实现
  • 604
分享到

Dijkstra算法原理及C++怎么实现

2023-07-02 18:07:37 604人浏览 泡泡鱼
摘要

这篇文章主要介绍“Dijkstra算法原理及c++怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Dijkstra算法原理及C++怎么实现”文章能帮助大家解决问题。什么是最短路径问题如果从图中

这篇文章主要介绍“Dijkstra算法原理及c++怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Dijkstra算法原理及C++怎么实现”文章能帮助大家解决问题。

什么是最短路径问题

如果从图中某一顶点(称为源点)到达另一顶点(称为终点)的路径可能不止一条,如何找到一条路径使得沿此路径上各边上的权值总和达到最小。

单源最短路径问题是指对于给定的图G=(V,E),求源点v0到其它顶点vt的最短路径。

Dijkstra算法

Dijkstra算法用于计算一个节点到其他节点的最短路径。Dijkstra是一种按路径长度递增的顺序逐步产生最短路径的方法,是一种贪婪算法。

Dijkstra算法的核心思想是首先求出长度最短的一条最短路径,再参照它求出长度次短的一条最短路径,依次类推,直到从源点v0到其它各顶点的最短路径全部求出为止。

具体来说:图中所有顶点分成两组,第一组是已确定最短路径的顶点,初始只包含一个源点,记为集合S;第二组是尚未确定最短路径的顶点,记为集合U。

按最短路径长度递增的顺序逐个把U中的顶点加到S中去,同时动态更新U集合中源点到各个顶点的最短距离,直至所有顶点都包括到S中。

实现思路

初始时,S集合只包含起点v0;U集合包含除v0外的其他顶点vt,且U中顶点的距离为起点v0到该顶点的距离。(U 中顶点vt的距离为(v0,vt)的长度,如果v0和vt不相邻,则vt的最短距离为∞)

从U中选出距离最短的顶点vt′,并将顶点vt′加入到S中;同时,从U中移除顶点vt′

更新U中各个顶点vt到起点v0的距离以及最短路径中当前顶点的前驱顶点。之所以更新U中顶点的距离以及前驱顶点是由于上一步中确定了vt′是求出最短路径的顶点,从而可以利用vt′来更新U中其它顶点vt的距离,因为存在(v0,vt)的距离可能大于(v0,vt')+(vt',vt)距离的情况,从而也需要更新其前驱顶点

重复步骤(2)和(3),直到遍历完所有顶点

案例分析

Dijkstra算法原理及C++怎么实现

Dijkstra算法原理及C++怎么实现

Dijkstra算法原理及C++怎么实现

Dijkstra算法原理及C++怎么实现

Dijkstra算法原理及C++怎么实现

Dijkstra算法原理及C++怎么实现

Dijkstra算法原理及C++怎么实现

代码实现

使用了部分C++11特性,注释丰富,读起来应该不会太困难!

#include <cstdio>#include <iOStream>#include <vector>#include <list>#include <stack>using namespace std;using Matrix = vector<vector<uint>>;                // 连接矩阵(使用嵌套的vector表示)using Snodes = vector<tuple<uint, uint, uint>>;     // 已计算出最短路径的顶点集合S(类似一个动态数组)using UNodes = list<tuple<uint, uint, uint>>;       // 未进行遍历的顶点集合U(使用list主要是方便元素删除操作)using ENode = tuple<uint, uint, uint>;              // 每个节点包含(顶点编号,当前顶点到起始点最短距离,最短路径中当前顶点的上一个顶点)信息ENode searchNearest(const UNodes &unvisitedNodes) {    uint minDistance = UINT_MAX;    ENode nearest;    for (const auto &node: unvisitedNodes) {        if (get<1>(node) <= minDistance) {            minDistance = get<1>(node);            nearest = node;        }    }    return nearest;}SNodes dijkstra(const Matrix &graph, uint startNodeIndex) {    const uint numOfNodes = graph.size();   // 图中顶点的个数    // S是已计算出最短路径的顶点的集合(顶点编号,当前顶点到起始点最短距离,最短路径中当前顶点的上一个顶点)    SNodes visitedNodes;    // U是未计算出最短路径的顶点的集合(其中的key为顶点编号,value为到起始顶点最短距离和最短路径中上一个节点编号组成的pair)    UNodes unvisitedNodes;    // 对S和U集合进行初始化,起始顶点的距离为0,其他顶点的距离为无穷大    // 最短路径中当前顶点的上一个顶点初始化为起始顶点,后面会逐步进行修正    for (auto i = 0; i < numOfNodes; ++i) {        if (i == startNodeIndex) visitedNodes.emplace_back(i, 0, startNodeIndex);        else unvisitedNodes.emplace_back(i, graph[startNodeIndex][i], startNodeIndex);    }    while (!unvisitedNodes.empty()) {        // 从U中找到距离起始顶点距离最短的顶点,加入S,同时从U中删除        auto nextNode = searchNearest(unvisitedNodes);        unvisitedNodes.erase(find(unvisitedNodes.begin(), unvisitedNodes.end(), nextNode));        visitedNodes.emplace_back(nextNode);        // 更新U集合中各个顶点的最短距离以及最短路径中的上一个顶点        for (auto &node: unvisitedNodes) {            // 更新的判断依据就是起始顶点到当前顶点(nextNode)距离加上当前顶点到U集合中顶点的距离小于原来起始顶点到U集合中顶点的距离            // 更新最短距离的时候同时需要更新最短路径中的上一个顶点为nextNode            if (graph[get<0>(nextNode)][get<0>(node)] != UINT_MAX &&                graph[get<0>(nextNode)][get<0>(node)] + get<1>(nextNode) < get<1>(node)) {                get<1>(node) = graph[get<0>(nextNode)][get<0>(node)] + get<1>(nextNode);                get<2>(node) = get<0>(nextNode);            }        }    }    return visitedNodes;}void print(const SNodes &paths) {    stack<int> tracks;  //从尾部出发,使用stack将每个顶点的最短路径中的前一个顶点入栈,然后出栈的顺序就是最短路径顺序    // 第一个元素是起始点,从第二个元素进行打印输出    for (auto it = ++paths.begin(); it != paths.end(); ++it) {        // 打印头部信息        printf("%c -> %c:\t Length: %d\t Paths: %c",               char(get<0>(paths[0]) + 65),               char(get<0>(*it) + 65),               get<1>(*it),               char(get<0>(paths[0]) + 65));        auto pointer = *it;        // 如果当前指针pointer指向的节点有中途节点(判断的条件是最短路径中的前一个节点不是起始点)        while (get<2>(pointer) != get<0>(paths[0])) {            tracks.push(get<0>(pointer));            // Lambda表达式,使用find_if函数把当前顶点的前一个顶点从paths中找出来继续进行循环直到前一个节点就是起始点            auto condition = [pointer](tuple<uint, uint, uint> x) { return get<0>(x) == get<2>(pointer); };            pointer = *find_if(paths.begin(), paths.end(), condition);        }        tracks.push(get<0>(pointer));        // 以出栈的顺序进行打印输出        while (!tracks.empty()) {            printf(" -> %c", char(tracks.top() + 65));            tracks.pop();        }        printf("\n");    }}int main() {    Matrix graph = {            {0,        12,       UINT_MAX, UINT_MAX, UINT_MAX, 16, 14},            {12,       0,        10,       UINT_MAX, UINT_MAX, 7, UINT_MAX},            {UINT_MAX, 10,       0, 3,               5,        6, UINT_MAX},            {UINT_MAX, UINT_MAX, 3, 0,               4, UINT_MAX, UINT_MAX},            {UINT_MAX, UINT_MAX, 5, 4,               0,        2,  8},            {16,       7,        6,        UINT_MAX, 2,        9,  9},            {14,       UINT_MAX, UINT_MAX, UINT_MAX, 8,        9,  0}    };  // 图对应的连接矩阵    auto results = dijkstra(graph, uint('D' - 65));          // 选取顶点C(大写字母A的ASCII编码是65)    print(results);     // 打印输出结果    return 0;}

运行结果:

D -> C:     Length: 3     Paths: D -> C
D -> E:     Length: 4     Paths: D -> E
D -> F:     Length: 6     Paths: D -> E -> F
D -> G:     Length: 12     Paths: D -> E -> G
D -> B:     Length: 13     Paths: D -> C -> B
D -> A:     Length: 22     Paths: D -> E -> F -> A

关于“Dijkstra算法原理及C++怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网其他教程频道,小编每天都会为大家更新不同的知识点。

--结束END--

本文标题: Dijkstra算法原理及C++怎么实现

本文链接: https://www.lsjlt.com/news/343713.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Dijkstra算法原理及C++怎么实现
    这篇文章主要介绍“Dijkstra算法原理及C++怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Dijkstra算法原理及C++怎么实现”文章能帮助大家解决问题。什么是最短路径问题如果从图中...
    99+
    2023-07-02
  • 详解Dijkstra算法原理及其C++实现
    目录什么是最短路径问题Dijkstra算法实现思路案例分析代码实现什么是最短路径问题 如果从图中某一顶点(称为源点)到达另一顶点(称为终点)的路径可能不止一条,如何找到一条路径使得沿...
    99+
    2022-11-13
  • 怎么使用C++实现Dijkstra算法
    本篇内容介绍了“怎么使用C++实现Dijkstra算法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!具体代码1.graph类graph类用于...
    99+
    2023-07-02
  • C++实现Dijkstra算法的示例代码
    目录一、算法原理二、具体代码1.graph类2.PathFinder类3. main.cpp三、示例一、算法原理 链接: Dijkstra算法及其C++实现参考这篇文章 二、具体代码...
    99+
    2022-11-13
  • C++最短路径Dijkstra算法如何实现
    这篇文章主要介绍“C++最短路径Dijkstra算法如何实现”,在日常操作中,相信很多人在C++最短路径Dijkstra算法如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++最短路径Dijkstra...
    99+
    2023-07-05
  • MD5算法原理及C#和JS实现的方法是什么
    本篇内容主要讲解“MD5算法原理及C#和JS实现的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MD5算法原理及C#和JS实现的方法是什么”吧!一、简介MD5 是哈希算法(散列算法)的...
    99+
    2023-07-05
  • SHA-256算法原理及C#和JS实现的方法是什么
    本篇内容主要讲解“SHA-256算法原理及C#和JS实现的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SHA-256算法原理及C#和JS实现的方法是什么”吧!一、简介SHA-256 ...
    99+
    2023-07-05
  • KNN算法原理及python实现
    文章目录 1 KNN算法原理1.1 基本概念1.2 KNN算法原理1.3 实现步骤1.3 KNN算法优缺点 2 python手工实现KNN算法2.1 KNN算法预测单个数据2.2 KNN算...
    99+
    2023-10-22
    python 机器学习
  • DES&3DES算法原理及C#和JS实现的方法是什么
    这篇文章主要介绍“DES&3DES算法原理及C#和JS实现的方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“DES&3DES算法原理及C#和JS实现的方法是什么”文章能帮助大...
    99+
    2023-07-05
  • Python使用邻接矩阵实现图及Dijkstra算法问题
    目录使用邻接矩阵实现图及Dijkstra算法将邻接矩阵输出成图总结使用邻接矩阵实现图及Dijkstra算法 # 邻接矩阵实现无向图 Dijkstra算法 inf = float("...
    99+
    2022-12-16
    Python使用邻接矩阵 Dijkstra算法 Python邻接矩阵
  • 详解MD5算法的原理以及C#和JS的实现
    目录一、简介二、C# 代码实现三、js 代码实现一、简介 MD5 是哈希算法(散列算法)的一种应用。Hash 算法虽然被称为算法,但实际上它更像是一种思想。Hash 算法没有一个固定...
    99+
    2023-03-19
    C# MD5算法 JS MD5算法 MD5算法实现
  • Java Bellman-Ford算法原理及实现方法
    本篇内容介绍了“Java Bellman-Ford算法原理及实现方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一 点睛如果遇到...
    99+
    2023-07-02
  • C/C++最短路径算法之迪杰斯特拉Dijkstra的实现详解
    目录前言一、迪杰斯特拉(Dijkstra)算法是什么二、实现步骤1.算法思路2.进入主函数ShortestPath()1.创建final数组并且初始化path[]、dist[]数组2...
    99+
    2022-11-13
  • 详解DES&3DES算法的原理以及C#和JS的实现
    目录一、简介1、DES 简介2、3DES 简介二、C# 代码实现1、DES2、3DES三、js 语言实现 1、DES2、3DES一、简介 1、DES 简介 DES 全称为 ...
    99+
    2023-03-19
    C# DES算法 JS DES算法 DES算法实现
  • 详解JavaBellman-Ford算法原理及实现
    目录一 点睛二 算法步骤三 算法实现四 测试一 点睛 如果遇到负权边,则在没有负环(回路的权值之和为负)存在时,可以采用 Bellman-Ford 算法求解最短路径。该算法...
    99+
    2022-11-13
  • C++最短路径Dijkstra算法的分析与具体实现详解
    目录前言Dijkstra 算法分析初始条件第一轮第二轮及以后Dijkstra 代码实现输入输出格式时间复杂度前言 经典的求解最短路径算法有这么几种:广度优先算法、Dijkstra算法...
    99+
    2023-03-10
    C++最短路径Dijkstra算法 C++最短路径算法 C++ Dijkstra算法
  • 详解Bagging算法的原理及Python实现
    目录一、什么是集成学习二、Bagging算法三、Bagging用于分类四、Bagging用于回归一、什么是集成学习 集成学习是一种技术框架,它本身不是一个单独的机器学习算法,而是通过构建并结合多个机器学习器来完成学习...
    99+
    2022-06-02
    Python Bagging算法 python 装袋算法
  • Redis常见限流算法原理及实现
    目录前言简介固定时间窗口原理示例说明优缺点相关实现限流脚本具体实现测试滑动时间窗口实现原理示例说明具体实现漏桶算法原理具体实现令牌桶算法原理具体实现小结总结前言 在高并发系统中,我们通常需要通过各种手段来提供系统的可以用...
    99+
    2022-08-08
    Redis限流算法原理实现 Redis限流算法
  • 一文搞懂JavaMD5算法的原理及实现
    目录MD5加密简介MD5加密原理MD5加密常用方法MD5加密简介 哈希算法又称散列算法,是将任何数据转换成固定长度的算法的统称。 从本质上讲,MD5也是一种哈希算法,其输出...
    99+
    2022-11-13
  • react diff 算法实现思路及原理解析
    目录事例分析diff 特点diff 思路实现 diff 算法修改入口文件实现 React.Fragment我们需要修改 children 对比前面几节我们学习了解了 react 的渲...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作