路径规划——搜索算法详解(一):Dijkstra算法详解与代码

前言:

本文为小陈同学原创,本人为路径规划方向的研狗一枚,转载请阅读文末的“授权说明”,学习笔记为连载,不定期分享路径规划的知识,欢迎转载、关注、点赞👍 !

纠结了很久还是打算做这个系列,给自己的研究生研究内容做一个总结,该系列将分为三大部分,分为搜索算法篇、路径优化篇、控制基础篇,希望对刚入门这一研究方向的朋友有所帮助!废话不多说,直接上干货。

首先,路径规划算法可以被简单地分为前端路径搜索与后端轨迹优化两个部分,路径搜索算法可以分为两大类——基于采样的路径搜索算法(如RRT、PRM)、基于图搜索的路径搜索算法(如Dijkstra、A*等),本篇将从零介绍Dijkstra算法。

Dijkstra算法解决的问题是从点A到点B的最短路径的求解,其是贪心算法的典型代表,时间复杂度为O(n2)。

一、 算法过程讲解与案例分析

借鉴B站视频案例讲解:【算法】最短路径查找—Dijkstra算法_哔哩哔哩_bilibili

1. 初始化:

如下图所示,起点为A,其余B-G为未探索节点,目标点为G,点与点之间的连线标注数字为该路径的代价,在现实问题中物理意义可能是两点之间的距离,用来衡量点之间的成本信息。同时定义两个列表——L为当前路径列表,存储每一步骤中所选择的最优路径点,而X为待选择路径点列表,存储未搜索的的路径点信息。对于每一个路径点记录着两个数据:距离起始点的最小距离、上一个路径点,初始化最小距离均为无穷大,初始化上层节点为空,每一步实时更新,初始化时将起点加入路径点,由于起点距离本身长度为0,起点本身就为上层节点,所以此时记为A(0,A)。

2.更新当前点的连接点与起点的距离与上一路径点(2、3步骤为第一轮循环):

更新当前点所连接路径点的代价,可以看到与当前所在点(蓝色)A连接的路径点(红色)有B、C,从起点A到B、C的距离分别为5 < ∞、8 < ∞,上一节点为A,故此时将X列表中的B(∞, )、C(∞, )分别更新为B(5,A)、C(8,A)。

3. 选择路径点:
在X列表中,悬着代价最小的路径点加入到路径列表L中,作为下一路径点:

4. 更新当前点的连接点与起点的距离与上一路径点(4、5步骤为第二轮循环):

与B相连接的点有三个分别为E、D、C,其中从A经过B到达E、D两个点的距离分别为5+7=12、5+6=11,均小于正无穷,故更新,而C点处经过B到达A的距离为15>8故不更新:

5. 选择路径点:

6. 更新当前点的连接点与起点的距离与上一路径点(6、7步骤为第三轮循环):

D经过C到达A的距离为16>11故不更新,而F为8+2=10故更新:

7. 选择路径点:

选择代价最小的F点加入到L列表中

8. 更新当前点的连接点与起点的距离与上一路径点(8、9步骤为第四轮循环):

由于与F点相连接的点只有目标点G,此时更新G

9. 选择路径点:

此时代价最小的为D点,故将D加入L列表中:

10. 更新当前点的连接点与起点的距离与上一路径点(10、11步骤为第五轮循环):

只有E与D相连,此时E通过D连接A的长度为11+3>12故不更新:

11.选择路径点:

此时代价最小的为E点,将其加入到L列表中:

 12.  更新当前点的连接点与起点的距离与上一路径点(12、13步骤为第六轮循环):

此时通过E连接G的代价为12+6=18 > 17,故不更新代价与上一路径点:

13. 此时将G加入到L列表中,此时目标点加入到L中,搜索结束:

从搜索结果L中,我们可以得到最小搜索距离为17,搜索回溯为G -> F -> C -> A,故A到G最短路径为A -> C -> F -> G:

至此,搜索完成。

二、 代码部分(C++)

搞清楚了上面的理论思想,代码写了一个比较简单的版本,没有加回溯,直接编译运行就好

#include <iostream>
#include <vector>
#include <limits>

using namespace std;

// 定义一个表示图的邻接矩阵的结构
const int INF = numeric_limits<int>::max();
typedef vector<vector<int>> Graph;

// Dijkstra算法的实现
vector<int> dijkstra(const Graph& graph, int start) {
    int n = graph.size();
    vector<int> dist(n, INF); // 初始距离设为无穷大
    vector<bool> visited(n, false); // 标记节点是否已被访问

    dist[start] = 0; // 设置起始节点距离为0

    for (int i = 0; i < n - 1; ++i) {
        // 选取未访问的距离最小的节点
        int minDist = INF, minIndex = -1;
        for (int j = 0; j < n; ++j) {
            if (!visited[j] && dist[j] < minDist) {
                minDist = dist[j];
                minIndex = j;
            }
        }

        if (minIndex == -1)
            break;

        // 标记节点已访问
        visited[minIndex] = true;

        // 更新与该节点相邻的节点的距离
        for (int j = 0; j < n; ++j) {
            if (!visited[j] && graph[minIndex][j] != INF && dist[minIndex] + graph[minIndex][j] < dist[j]) {
                dist[j] = dist[minIndex] + graph[minIndex][j];
            }
        }
    }

    return dist;
}

int main() {
    // 举例一个简单的图
    Graph graph = {
        {0, 1, 4, INF, INF},
        {1, 0, 4, 2, 7},
        {4, 4, 0, 3, INF},
        {INF, 2, 3, 0, 4},
        {INF, 7, INF, 4, 0}
    };

    // 调用Dijkstra算法计算从节点0出发到其他节点的最短路径
    vector<int> shortestDistances = dijkstra(graph, 0);

    // 输出结果
    cout << "Shortest distances from node 0:" << endl;
    for (int i = 0; i < shortestDistances.size(); ++i) {
        cout << "Node " << i << ": " << shortestDistances[i] << endl;
    }

    return 0;
}

授权说明

  1. 原创文章在发布三天内禁止转载;
  2. 转载本人文章禁止声明原创;
  3. 转载必须标明作者与来源,本人保留追诉权利;
  4. 若非直接转载而是改变排版后转载,请联系本人,获得本人同意后即可转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/479813.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

原型、原型链

如图&#xff1a; 判断对错&#xff1a; Q1:在JS 中 proto 和 constructor 属性是对象和函数都有的属性 prototype属性仅是函数对象所独有的。 由于JavaScript中一切皆对象,即函数对象也是一种对象,所以函数也拥有__proto__和constructor属性。 Q2:通过 proto 属性来连接对象…

利用WebGL绘制简单几何

利用WebGL绘制最简单的几何图形 一、WebGL简介 WebGL是一种用于在网页上渲染交互式3D和2D图形的JavaScript API。它基于OpenGL ES 2.0&#xff0c;提供了一种在浏览器中使用硬件加速图形的方式。 二、图形系统绘图流程 图形系统的通用绘图流程会包括六个部分&#xff1a; …

langchain+chatglm3+BGE+Faiss Linux环境安装依赖

前言 本篇默认读者已经看过之前windows版本&#xff0c;代码就不赘述&#xff0c;本次讲述是linux环境配置 超短代码实现&#xff01;&#xff01;基于langchainchatglm3BGEFaiss创建拥有自己知识库的大语言模型(准智能体)本人python版本3.11.0&#xff08;windows环境篇&…

Golang案例开发之gopacket抓包三次握手四次分手(3)

文章目录 前言一、理论知识三次握手四次分手二、代码实践1.模拟客户端和服务器端2.三次握手代码3.四次分手代码验证代码完整代码总结前言 TCP通讯的三次握手和四次分手,有很多文章都在介绍了,当我们了解了gopacket这个工具的时候,我们当然是用代码实践一下,我们的理论。本…

Python计算机二级选择易错题(三)

选择题第02&#xff0c;03&#xff0c;04套 题目来源&#xff1a;python计算机二级真题&#xff08;选择题&#xff09; - 知乎 选择题第02套 选择题第03套 选择题第04套 time()获取当前时间&#xff0c;即计算机内部时间&#xff0c;浮点数&#xff1b;import time库&#x…

鸿蒙Harmony应用开发—ArkTS-@AnimatableExtend装饰器:定义可动画属性

AnimatableExtend装饰器用于自定义可动画的属性方法&#xff0c;在这个属性方法中修改组件不可动画的属性。在动画执行过程时&#xff0c;通过逐帧回调函数修改不可动画属性值&#xff0c;让不可动画属性也能实现动画效果。 可动画属性&#xff1a;如果一个属性方法在animation…

必知必会干货!1分钟搞定Python编程中捕获异常

​ 在Python编程中&#xff0c;异常就是程序在运行过程中出现的问题或错误&#xff0c;比如除数为零、文件找不到等等。而异常捕获&#xff0c;就是通过在代码中设置特定的语句&#xff0c;来捕捉这些异常&#xff0c;并对其进行处理&#xff0c;防止程序崩溃。 那么&#xff…

YOLOv5全网首发改进: 注意力机制改进 | 上下文锚点注意力(CAA) | CVPR2024 PKINet 遥感图像目标检测

💡💡💡本文独家改进:引入了CAA模块来捕捉长距离的上下文信息,利用全局平均池化和1D条形卷积来增强中心区域的特征,从而提升检测精度,CAA和C3进行结合实现二次创新,改进思路来自CVPR2024 PKINet,2024年前沿最新改进,抢先使用 💡💡💡小目标数据集,涨点近两个…

005——串口移植(基于鸿蒙liteos-a)

目录 一、 Liteos-a中串口的使用 1.1 内核里打印 1.2 APP控制台 ​编辑 1.2.1 /dev/console 1.2.2 /dev/serial 1.2.3 /dev/uartddev-0 1. 总体介绍 2. device_t 3. drvier_t 4. uartdev_fops 1.2.4 uart_ops 二、 鸿蒙串口内部的一些机制&#xff08;流水账&…

阿里云4核8G服务器优惠价格表,ECS u1实例

阿里云4核8G服务器优惠价格955元一年&#xff0c;配置为ECS通用算力型u1实例&#xff08;ecs.u1-c1m2.xlarge&#xff09;4核8G配置、1M到3M带宽可选、ESSD Entry系统盘20G到40G可选&#xff0c;CPU采用Intel(R) Xeon(R) Platinum处理器&#xff0c;阿里云活动链接 aliyunfuwuq…

就业班 第二阶段 2401--3.21 day3 备份

一、逻辑备份 备份的是建表、建库、插入等操作所执行SQL语句&#xff0c;适用于中小型数据库&#xff0c;效率相对较低。 本质&#xff1a;导出的是SQL语句文件 优点&#xff1a;不论是什么存储引擎&#xff0c;都可以用mysqldump备成SQL语句 缺点&#xff1a;速度较慢&…

谷歌推出通用AI代理:能自动执行600多种动作,游玩复杂3D游戏

谷歌DeepMind的研究人员推出了一种面向3D环境的通用AI代理——SIMA。 SIMA无需访问游戏的源代码&#xff0c;也不需要定制的API。只需要输入图像和用户提供的简单自然语言文本指令&#xff0c;SIMA就能像人类玩家一样执行走路、跑步、建造、打开地图等各种游戏中的操作。 为了…

市场复盘总结 20240322

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 二进三&#xff1a; 进级率中 36% 最常用…

C++初阶:vector的使用与自实现

目录 1. vector与顺序表2. vector的使用2.1 默认成员函数2.2 vector的迭代器2.3 容量相关成员函数2.4 遍历访问方式2.5 vector的修改操作 3. vector的自实现3.1 自实现功能3.2 vector的结构与自实现的逻辑3.3 自实现vector功能接口 1. vector与顺序表 我们在初阶数据结构中学习…

34 | 到底可不可以使用join?

在实际生产中&#xff0c;关于 join 语句使用的问题&#xff0c;一般会集中在以下两类&#xff1a; 1. 我们 DBA 不让使用 join&#xff0c;使用 join 有什么问题呢&#xff1f; 2. 如果有两个大小不同的表做 join&#xff0c;应该用哪个表做驱动表呢&#xff1f; 今天这篇文…

【进程和线程】操作系统中的并发执行机制

目录 一、什么是进程(Process)&#xff1f; 进程的管理 进程调度(重点) 二、什么是线程(Thread)&#xff1f; 三、进程和线程的区别与联系 进程(Process) 线程(Thread) 总结比较 一、什么是进程(Process)&#xff1f; 进程和线程是操作系统中一个非常核心的话题&#…

鸿蒙Harmony应用开发—ArkTS-@Provide装饰器和@Consume装饰器:与后代组件双向同步

Provide和Consume&#xff0c;应用于与后代组件的双向数据同步&#xff0c;应用于状态数据在多个层级之间传递的场景。不同于上文提到的父子组件之间通过命名参数机制传递&#xff0c;Provide和Consume摆脱参数传递机制的束缚&#xff0c;实现跨层级传递。 其中Provide装饰的变…

随笔】Git -- 常用命令(四)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

OpenHarmony实现一次开发多端部署分布式新闻客户端页面

分布式新闻客户端&#xff08;ArkTS&#xff09; 介绍 本篇Codelab基于栅格布局、设备管理和多端协同&#xff0c;实现一次开发&#xff0c;多端部署的分布式新闻客户端页面。主要包含以下功能&#xff1a; 展示新闻列表以及左右滑动切换新闻Tab。点击新闻展示新闻详情页。点…

产生死锁的四大条件

死锁 由于两个或两个以上的线程相互争夺对方的资源&#xff0c;而同时不释放自己的资源&#xff0c;导致所有线程同时被阻塞 产生死锁的四大条件 互斥条件&#xff1a;一个资源在同一时刻只能由一个运算单元&#xff08;进程、线程或协程&#xff09;占用&#xff08;排它性&…