Bellman-Ford 和 SPFA 算法的实现DEM路径搜索

server/2024/11/20 5:40:28/

首先,假设你已经有一个 2D 数组表示 DEM 数据,每个元素的值表示某个位置的高度。你可以根据特定的规则来决定哪些区域是障碍物或无效值。

  1. Bellman-Ford 算法的实现
#include <iostream>
#include <vector>
#include <climits>
#include <queue>using namespace std;// 定义一个邻接列表表示图
struct Edge {int u, v, weight;
};class BellmanFord {
public:BellmanFord(int n) : V(n), dist(n, INT_MAX) {}void addEdge(int u, int v, int weight) {edges.push_back({u, v, weight});}// Bellman-Ford算法求最短路径void run(int start) {dist[start] = 0;// 放松所有边 V-1 次for (int i = 0; i < V - 1; ++i) {for (auto& edge : edges) {if (dist[edge.u] != INT_MAX && dist[edge.u] + edge.weight < dist[edge.v]) {dist[edge.v] = dist[edge.u] + edge.weight;}}}// 检查负权环for (auto& edge : edges) {if (dist[edge.u] != INT_MAX && dist[edge.u] + edge.weight < dist[edge.v]) {cout << "Negative weight cycle detected!" << endl;return;}}}int getDistance(int vertex) {return dist[vertex];}private:int V;vector<Edge> edges;vector<int> dist;
};int main() {int V = 5; // 假设图中有5个节点BellmanFord bf(V);// 示例: 添加一些边bf.addEdge(0, 1, 10);bf.addEdge(0, 2, 5);bf.addEdge(1, 2, 2);bf.addEdge(1, 3, 1);bf.addEdge(2, 1, 3);bf.addEdge(2, 3, 9);bf.addEdge(3, 4, 4);int start = 0;  // 指定起点bf.run(start);// 输出从起点到每个点的最短距离for (int i = 0; i < V; ++i) {cout << "Distance from " << start << " to " << i << ": " << bf.getDistance(i) << endl;}return 0;
}
  1. SPFA (Shortest Path Faster Algorithm) 算法的实现
#include <iostream>
#include <vector>
#include <climits>
#include <queue>using namespace std;class SPFA {
public:SPFA(int n) : V(n), dist(n, INT_MAX), inQueue(n, false) {}void addEdge(int u, int v, int weight) {adj[u].push_back({v, weight});}void run(int start) {dist[start] = 0;queue<int> q;q.push(start);inQueue[start] = true;while (!q.empty()) {int u = q.front();q.pop();inQueue[u] = false;for (auto& edge : adj[u]) {int v = edge.first, weight = edge.second;if (dist[u] + weight < dist[v]) {dist[v] = dist[u] + weight;if (!inQueue[v]) {q.push(v);inQueue[v] = true;}}}}}int getDistance(int vertex) {return dist[vertex];}private:int V;vector<vector<pair<int, int>>> adj;  // 邻接表,存储边(目标节点,边的权重)vector<int> dist;vector<bool> inQueue;  // 判断节点是否已经在队列中
};int main() {int V = 5;  // 假设图中有5个节点SPFA spfa(V);// 示例: 添加一些边spfa.addEdge(0, 1, 10);spfa.addEdge(0, 2, 5);spfa.addEdge(1, 2, 2);spfa.addEdge(1, 3, 1);spfa.addEdge(2, 1, 3);spfa.addEdge(2, 3, 9);spfa.addEdge(3, 4, 4);int start = 0;  // 指定起点spfa.run(start);// 输出从起点到每个点的最短距离for (int i = 0; i < V; ++i) {cout << "Distance from " << start << " to " << i << ": " << spfa.getDistance(i) << endl;}return 0;
}
  1. 处理 DEM 数据和障碍物
    你可以将 DEM 数据表示为一个二维数组,每个位置的值是该位置的高度。假设高度低于某个阈值的区域表示障碍物或无效值。

#include <iostream>
#include <vector>using namespace std;bool isObstacle(int height, int threshold) {return height <= threshold;
}void buildGraphFromDEM(const vector<vector<int>>& dem, int threshold, SPFA& spfa) {int rows = dem.size();int cols = dem[0].size();// 邻接表构建for (int i = 0; i < rows; ++i) {for (int j = 0; j < cols; ++j) {if (isObstacle(dem[i][j], threshold)) {continue;  // 如果是障碍物或无效值,则跳过}// 将四个方向的邻接节点添加到图中if (i > 0 && !isObstacle(dem[i - 1][j], threshold)) {  // 上spfa.addEdge(i * cols + j, (i - 1) * cols + j, 1);}if (i < rows - 1 && !isObstacle(dem[i + 1][j], threshold)) {  // 下spfa.addEdge(i * cols + j, (i + 1) * cols + j, 1);}if (j > 0 && !isObstacle(dem[i][j - 1], threshold)) {  // 左spfa.addEdge(i * cols + j, i * cols + (j - 1), 1);}if (j < cols - 1 && !isObstacle(dem[i][j + 1], threshold)) {  // 右spfa.addEdge(i * cols + j, i * cols + (j + 1), 1);}}}
}int main() {vector<vector<int>> dem = {{1, 1, 1, 0, 1},{1, 0, 1, 1, 1},{1, 1, 0, 1, 0},{1, 1, 1, 1, 1}};int threshold = 0;  // 假设 0 以下为障碍物int V = dem.size() * dem[0].size();SPFA spfa(V);buildGraphFromDEM(dem, threshold, spfa);int start = 0;  // 从 (0, 0) 点出发spfa.run(start);// 输出从起点到目标点的最短距离int target = 4;  // 比如目标点为 (0, 4)cout << "Distance from start to target: " << spfa.getDistance(target) << endl;return 0;
}

代码解释:
Bellman-Ford 算法:该算法是用于解决单源最短路径问题的经典算法。它逐步放松所有的边
𝑉

1
V−1 次,适用于带负权边的情况。
SPFA 算法:SPFA 是一种基于队列的改进算法,它在大多数情况下比 Bellman-Ford 快。
DEM 数据处理:通过 isObstacle 函数判断高度是否低于给定的阈值,从而判断是否为障碍物。如果是障碍物,则不添加边。
运行:
程序会自动过滤掉无效区域(障碍物)并计算从起点到终点的最短路径。
可以通过修改 dem 和 threshold 来适配不同的地图和障碍物条件。
如果你有特定的数据或者需要进一步的功能扩展,随时告诉我!


http://www.ppmy.cn/server/143393.html

相关文章

C# 常用三方库

C# 第三方库 C# 第三方库日志工具库REST 客户端JSON 处理App.config 文件自定义ConfigSection 的 auto 配置ORM 工具嵌入数据库条码/二维码通讯类组件串口通讯 https://www.nuget.org/packages/GodSharp.SerialPort/Modbus 通讯组件西门子通讯组件Fins协议通讯组件, 报表组件包…

Python绘制雪花

文章目录 系列目录写在前面技术需求完整代码代码分析1. 代码初始化部分分析2. 雪花绘制核心逻辑分析3. 窗口保持部分分析4. 美学与几何特点总结 写在后面 系列目录 序号直达链接爱心系列1Python制作一个无法拒绝的表白界面2Python满屏飘字表白代码3Python无限弹窗满屏表白代码4…

java进阶:利用trueLicense实现项目离线证书授权

文章目录 0.引言1. trueLicense简介1.1 原理简介1.2 公钥私钥和证书1.3 trueLicense简介 2. 操作步骤2.1 生成公私钥2.1.1 keyTool工具介绍2.1.2 生成公私钥文件 2.2 license校验模块2.3 license生成模块2.4 测试模块2.5 完整代码 3.总结 0.引言 我们在实际项目中&#xff0c;…

#define定义宏(2)

大家好&#xff0c;今天给大家分享两个技巧。 首先我们应该先了解一下c语言中字符串具有自动连接的特点。注意只有将字符串作为宏参数的时候才可以把字符串放在字符串中。 下面我们来讲讲这两个技巧 1.使用#&#xff0c;把一个宏参数变成对应的字符串。 2.##的作用 可以把位…

使用低成本的蓝牙HID硬件模拟鼠标和键盘来实现自动化脚本

做过自动化脚本的都知道&#xff0c;现在很多传统的自动化脚本方案几乎都可以被检测&#xff0c;比如基于root&#xff0c;adb等方案。用外置的带有鼠标和键盘功能集的蓝牙HID硬件来直接点击和滑动是非常靠谱的方案&#xff0c;也是未来的趋势所在。 一、使用蓝牙HID硬件的优势…

基于Java Springboot滁州市特产销售系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

【jvm】方法区的理解

目录 1. 说明2. 方法区的演进3. 内部结构4. 作用5.内存管理 1. 说明 1.方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码缓存等数据。它是各个线程共享的内存区域。2.尽管《Java虚拟机规范》中把方法区描述为堆的一个逻辑部分&#xff0c;但它却…

android 如何获取当前 Activity 的类名和包名

其一&#xff1a;getClass().getSimpleName() public static String getTopActivity(Context context){ ActivityManager am (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE); ComponentName cn am.getRunningTasks(1).get(0).topAct…