路径规划——Dijkstra算法

算法原理

Dijkstra算法采用贪心算法的思想,解决的问题可以描述为:在无向图G=(V,E)中,假设每条边E[i] 的长度为 w[i],找到由顶点vs到其余各点的最短路径。 通过Dijkstra计算图G中的最短路径时,需要指定起点vs(即从顶点vs开始计算)。此外,引进两个集合S和U。S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的顶点(以及该顶点到起点vs的距离)。初始时,S中只有起点vs;U中是除vs之外的顶点,并且U中顶点的路径是“起点vs到该顶点的路径”。然后,从U中找出路径最短的顶点,并将其加入到S中;接着,更新U中的顶点和顶点对应的路径。然后,再从U中找出路径最短的顶点,并将其加入到S中;接着,更新U中的顶点和顶点对应的路径。重复该操作,直到遍历完所有顶点。 时间复杂度为O(V^2)其中V为顶点数,但可以通过优先队列实现最小堆来优化时间复杂度。

所谓贪心是指每一点都存储该点到起点的最短路径。

算法实现

C++算法核心:


std::tuple<vector<pair<int, int>>, vector<double>> Dijkstra::get_neighbors(pair<int, int> node) {vector<pair<int, int>> neighbors;vector<double> distances;vector<PlanNode> nexts = {PlanNode({-1, 0}, 1), PlanNode({-1, 1}, sqrt(2)), PlanNode({0, 1}, 1), PlanNode({1, 1}, sqrt(2)),PlanNode({1, 0}, 1), PlanNode({1, -1}, sqrt(2)), PlanNode({0, -1}, 1), PlanNode({-1, -1}, sqrt(2))};for (auto& next : nexts) {pair<int, int> neighbor = {node.first + next.directions.first, node.second + next.directions.second};if (0 <= neighbor.first && neighbor.first < grid.size() && 0 <= neighbor.second && neighbor.second < grid[0].size()) {if (grid[neighbor.first][neighbor.second] == 0) {if (next.directions.first != 0 && next.directions.second != 0) {if (grid[node.first + next.directions.first][node.second] == 0 && grid[node.first][node.second + next.directions.second] == 0) {neighbors.push_back(neighbor);distances.push_back(next.cost);}} else {neighbors.push_back(neighbor);distances.push_back(next.cost);}}}}return make_tuple(neighbors,distances);
}double Dijkstra::plan() {priority_queue<pair<double, pair<int, int>>, vector<pair<double, pair<int, int>>>, greater<>> priority_queue;priority_queue.push({0, start});map<pair<int, int>, double> costs;map<pair<int, int>, pair<int, int>> previous_nodes;costs[start] = 0;while (!priority_queue.empty()) {auto [current_cost, current_node] = priority_queue.top();priority_queue.pop();if (visited.find(current_node) != visited.end()) continue;visited.insert(current_node);visit_order.push_back(current_node);if (current_node == goal) break;vector<pair<int, int>> neighbors;vector<double> distances;tie(neighbors,distances) = get_neighbors(current_node);for (size_t i=0; i<neighbors.size();++i) {pair<int, int> neighbor = neighbors[i];double distance = distances[i];double cost = current_cost + distance;// double cost = current_cost + sqrt(pow(neighbor.first - current_node.first, 2) + pow(neighbor.second - current_node.second, 2));if (costs.find(neighbor) == costs.end() || cost < costs[neighbor]) {costs[neighbor] = cost;previous_nodes[neighbor] = current_node;priority_queue.push({cost, neighbor});}}}path.clear();pair<int, int> current_node = goal;while (current_node != start) {path.push_back(current_node);current_node = previous_nodes[current_node];std::cout<<"node: "<<current_node.first<<","<<current_node.second<<" ";printf("cost:%lf\n",costs[current_node]);}path.push_back(start);reverse(path.begin(), path.end());return costs[goal];
}

 

Python算法核心:


class Node:def __init__(self,directions,cost):self.directions = directionsself.cost = costdef get_neighbors(self, node):neighbors = []distances = []nexts = [self.Node((-1, 0),1), self.Node((0, 1),1), self.Node((0, -1),1), self.Node((1,0),1),self.Node((-1,1),math.sqrt(2)), self.Node((1,1),math.sqrt(2)),self.Node((1, -1),math.sqrt(2)), self.Node((-1,-1),math.sqrt(2))]for next in nexts:neighbor = (node[0] + next.directions[0], node[1] + next.directions[1])if self.board_size <= neighbor[0] < len(self.grid)-self.board_size and self.board_size <= neighbor[1] < len(self.grid[0])-self.board_size:if self.grid[neighbor[0]][neighbor[1]] == 0:if next.directions[0] != 0 and next.directions[1] != 0:  # 对角线方向if self.grid[node[0] + next.directions[0]][node[1]] == 0 and self.grid[node[0]][node[1] + next.directions[1]] == 0:neighbors.append(neighbor)distances.append(next.cost)else:neighbors.append(neighbor)distances.append(next.cost)return neighbors,distancesdef plan(self):priority_queue = []heapq.heappush(priority_queue,(0,self.start))costs = {self.start: 0}previous_nodes = {self.start: None}self.visited = set()self.visit_order = []while priority_queue:current_cost, current_node = heapq.heappop(priority_queue)# Determines whether the current node has already been visitedif current_node in self.visited:continueself.visited.add(current_node)self.visit_order.append(current_node)if current_node == self.goal:break# Find passable neighborsneighbors, distances = self.get_neighbors(current_node)for neighbor,distance in zip(neighbors,distances):if neighbor[0] == -1:continue# Compute the cost from the start pointcost = current_cost + distance# Store cost and update to minimum valueif neighbor not in costs or cost < costs[neighbor]:costs[neighbor] = cost# The parent node of neighbor is current_nodeprevious_nodes[neighbor] = current_node# Push the node into priority_queueheapq.heappush(priority_queue,(cost, neighbor))self.path = []current_node = self.goalwhile current_node is not None:self.path.append(current_node)current_node = previous_nodes.get(current_node)self.path = self.path[::-1]return costs[self.goal]

路径规划——dijkstra(迪杰斯特拉)算法

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BI数据可视化看板的力量与应用

在当今数据驱动的时代&#xff0c;企业面对着海量的信息与数据。随着业务的复杂性加剧&#xff0c;如何有效地解读和利用这些数据&#xff0c;成为了企业决策的重要环节。而BI&#xff08;商业智能&#xff09;数据可视化看板&#xff0c;便是解决这一难题的关键工具。数聚将深…

idea-springboot后端所有@注释含义汇总-持续更新!

&#xff08;1&#xff09;启动类 ①SpringBootApplication 出现这个代表这个就是整个程序的入口&#xff0c;是运行的开始位置 &#xff08;2&#xff09;Dao层 ①Repository 作用就是声明自己这个为bean文件&#xff08;每一个controller都是一个bean文件&#xff09;&am…

vue3 中使用xlsx 插件 导出excel文件

介绍一下 vue中得导出excel 文件 功能 ① 安装插件 npm i xlsx ②导入插件 import * as XLSX from xlsx; ③ 使用插件 直接是一个 方法 const exportExcel()>{const data[["姓名","年龄"],["张三",18],["李四",20],["王五…

blender顶点乱飞的问题解决

初学blender&#xff0c;编辑模式下移动某些顶点&#xff0c;不管是移动还是滑动都会出现定点乱飞的问题&#xff0c;后来才发现是开了吸附工具的原因&#xff01;&#xff01;&#xff01;&#xff01; 像下面这样&#xff0c;其实我只是在Z轴上移动&#xff0c;但是就跑的很…

Anaconda目录

安装目录 Anaconda 在默认情况下会安装到 C:\ProgramData\Anaconda3&#xff0c;而 conda 环境和包会安装在 C:\Users\username\.conda\ 目录下。 备注&#xff1a;我是在windows下安装 的Anaconda。我的安装目录是C:\Program Files\Anaconda3 pkgs目录 在以上两个目录下都有…

CH571F基于官方模版创建工程

直接使用MounRiver创建的工程只有最简单的串口和GPIO功能&#xff0c;其他PWM和SPI等驱动基本上都有&#xff0c;但蓝牙和USB只有参考官方的示例来&#xff0c;全部自己写属实有点麻烦了&#xff0c;而且还需要添加BLE的库。下面就简单基于官方的示例工程创建我们自己的工程。 …

抓包工具——wireshark的使用

​ 什么是wireshark wireshark是一个数据包捕捉程序。和linux下的tcpdump&#xff0c;以及sniffer&#xff0c;Fidder等软件功能类似。按理说&#xff0c;我们的计算机中的网卡设备只会将发给本机的数据包传输到上层进行解析&#xff0c;而其他的数据包会进行丢弃&#xff0c;…

jenkins集成allure测试报告

1.allure插件安装 &#xff08;1&#xff09;点击首页的【Manage Jenkins】-【Manage Plugins】 &#xff08;2&#xff09;选择【Available】选项&#xff0c;搜索输入框输入Allure&#xff0c;搜索出来的名字就叫Allure&#xff0c;当安装后名字会变为Allure Jenkins Plugi…

QVariantMap是QVariant类型的键值对容器,它在 Qt 中被广泛使用,用于存储和传递复杂的数据结构

QVariantMap 是 QVariant 类型的键值对容器&#xff0c;它在 Qt 中被广泛使用&#xff0c;用于存储和传递复杂的数据结构。QVariantMap 类似于 QMap<QString, QVariant>&#xff0c;允许使用字符串作为键来存储各种类型的数据。 QVariantMap 的基本功能 创建和使用 QVa…

Android SurfaceFlinger——GraphicBuffer获取内存信息(三十一)

上一篇文章介绍了 GraphicBuffer 初始化的 initWithSize() 函数中的申请内存流程,这里我们看一下另一个比较重要的函数,GraphicBufferMapper. getTransportSize 获取内存信息。该函数通常在需要了解缓冲区的实际内存占用情况时调用,例如在调试内存使用情况或优化性能时。 一…

语言模型检索用的知识库,是越大越好吗?

语言模型在预训练时所使用的数据量越大&#xff0c;推理时的准确率等性能总的来说就会越好。根据美国华盛顿大学和艾伦AI研究所近期发表的一篇论文[1]&#xff0c;语言模型检索用的知识库同样也存在着规模效应&#xff0c;知识库的规模越大&#xff0c;模型完成知识密集型任务的…

MySQL 8.0 字符集与比较规则介绍

前言&#xff1a; 我们都知道 MySQL 8.0 与 MySQL 5.7 的区别之一就是默认字符集从 latin1 改成了 utf8mb4 &#xff0c;除此之外&#xff0c;MySQL 8.0 下的字符集和比较规则还有没有其他变化呢&#xff1f;本篇文章我们一起来学习下。 utf8mb4 字符集 在 MySQL 8.0 中&…

C和C++的区别?

C和C是两种广泛使用的编程语言&#xff0c;它们在许多方面有相似之处&#xff0c;但也有一些关键的区别。以下是C和C的一些主要区别&#xff1a; 目录 1. **语言起源和设计哲学**:2. **面向对象编程**:3. **内存管理**:4. **标准库**:5. **类型检查**:6. **函数重载**:7. **引…

PPT模板替换秘籍:一键撤销原模板,轻松更换新风格!

将PPT中的模板换成另一个模板&#xff0c;可以通过几种不同的方法实现。以下是几种常用的方法&#xff1a; 方法一&#xff1a;使用PowerPoint内置的设计选项卡 打开PowerPoint&#xff1a;首先&#xff0c;打开你想要更改模板的PPT文件。 选择“设计”选项卡&#xff1a;在…

(部署服务器系列四)部署Vue步骤(使用nodejs)

1. 构建项目&#xff08;打包Vue&#xff09;&#xff1a; 构建前设置main.js //关闭开发模式提示 Vue.config.devtoolsfalse Vue.config.productionTip false设置指向的服务端后端ip和端口&#xff0c;我的常量属性统一放在了constants.js export const AIOS_BASE_URL &q…

生成式AI的未来:智慧对话与自主代理的抉择

生成式AI的未来&#xff1a;智慧对话与自主代理的抉择 随着生成式AI技术的不断进步&#xff0c;关于其未来发展方向的讨论也愈发激烈。究竟生成式AI的未来是在对话系统&#xff08;Chat&#xff09;中展现智慧&#xff0c;还是在自主代理&#xff08;Agent&#xff09;中体现能…

Mysql-覆盖索引和前缀索引

一.SQL提示 SQL提示,是优化数据库的一个重要手段,简单来说&#xff0c;就是在SQL语句加入一些人为的提示来达到 二.覆盖索引 尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到),减少select* 知识小贴士: using index condition :查找…

android前台服务

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 未经允许不得转载 目录 一、导读二、使用2.1 添加权限2.2 新建…

数据丢失不用愁!这四款数据恢复大师免费版助你找回珍贵回忆

我们在办公或者是生活中常常会遇到不小心将手机设备或者计算机当中的重要数据误删除/格式化/或其他不小心丢失的情况&#xff0c;但是不用紧张&#xff0c;这篇文章就是给大家分享如何恢复他们&#xff0c;以下带来除易我数据恢复外的其他好用的数据恢复软件&#xff1a; 第一…

python windows环境部署

在官网安装www.python.org linux系统的只能编译安装 windows的可以直接安装 这里是windows安装 .3.9.6版本 一直下一步就可以&#xff0c;然后鼠标右键在按住shift用终端打开 输入py或者python验证一下是否安装成功 打开目录文件夹 在里面新建一下pip的文件夹&#xff0c;里…