首先,假设你已经有一个 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 来适配不同的地图和障碍物条件。
如果你有特定的数据或者需要进一步的功能扩展,随时告诉我!

11-20 07:53