Dijkstra最短路径算法的C#实现

136 篇文章 ¥59.90 ¥99.00
本文介绍了Dijkstra最短路径算法的原理,并展示了如何用C#编写该算法的实现。算法通过计算从起点到各顶点的最短路径,使用优先队列选择最短路径的顶点进行扩展,最终找到目标顶点的最短路径。

Dijkstra最短路径算法是一种用于在加权有向图中找到最短路径的经典算法。它以荷兰计算机科学家Edsger W. Dijkstra的名字命名,是解决许多实际问题的一种常用方法。本文将介绍如何使用C#编写Dijkstra算法的实现,并提供相应的源代码。

Dijkstra算法的核心思想是通过计算从起点到各个顶点的最短路径来逐步扩展路径树,直到找到目标顶点或者遍历完所有的顶点。算法使用一个优先队列来选择下一个要扩展的顶点,以确保总是选择当前最短路径的顶点进行扩展。

首先,我们需要定义一个表示图的类,其中包含顶点和边的信息。以下是一个简单的图类的实现:

using System;
using System.Collections.Generic;

class Graph
### C++ 实现最短路径算法 (Dijkstra 和 BFS) #### 广度优先搜索 (BFS) 示例代码 对于无权图中的最短路径问题,广度优先搜索是一种高效的解决方案。以下是基于队列的 BFS 算法实现: ```cpp #include <iostream> #include <vector> #include <queue> using namespace std; void bfs(int start, vector<vector<int>> &adjList, int n) { vector<bool> visited(n, false); vector<int> distance(n, -1); // 初始化距离数组为 -1 表示未访问 queue<int> q; visited[start] = true; // 起始节点标记为已访问 distance[start] = 0; // 起始节点到自身的距离为 0 q.push(start); while (!q.empty()) { // 当队列不为空时继续遍历 int u = q.front(); // 取出当前节点 q.pop(); for (int v : adjList[u]) { // 遍历相邻节点 if (!visited[v]) { // 如果邻居节点未被访问过 visited[v] = true; // 标记为已访问 distance[v] = distance[u] + 1; // 更新距离 q.push(v); // 将该节点加入队列 } } } cout << "Shortest distances from node " << start << ": "; for (int i = 0; i < n; ++i) { cout << "\nNode " << i << ": " << ((distance[i] != -1) ? to_string(distance[i]) : "INF"); } } // 测试函数 int main() { int nodes = 6; vector<vector<int>> adjacencyList = {{1, 2}, {3, 4}, {5}, {}, {}, {}}; bfs(0, adjacencyList, nodes); } ``` 此代码实现了无权图上的 BFS 算法,并计算了从起始节点到其他所有节点的距离[^1]。 --- #### 迪杰斯特拉算法 (Dijkstra) 示例代码 对于有权图中的单源最短路径问题,迪杰斯特拉算法是经典的选择之一。下面是其 C++ 实现: ```cpp #include <iostream> #include <vector> #include <limits.h> #include <set> using namespace std; void dijkstra(vector<vector<pair<int, int>>> &graph, int src, int V) { vector<int> dist(V, INT_MAX); // 存储从起点到各点的最短距离 set<pair<int, int>> s; // 使用集合来维护候选节点 dist[src] = 0; // 起点到自己的距离为 0 s.insert({0, src}); // 插入初始节点 while (!s.empty()) { // 当集合中有待处理节点时循环 pair<int, int> tmp = *(s.begin()); // 获取并移除集合中距离最小的节点 s.erase(s.begin()); int u_dist = tmp.first; // 当前节点的距离 int u = tmp.second; // 当前节点编号 if (u_dist > dist[u]) continue; // 若已有更优解,则跳过 for (auto &edge : graph[u]) { // 遍历当前节点的所有邻接边 int v = edge.first; // 邻居节点编号 int weight = edge.second;// 边权重 if (dist[v] > dist[u] + weight) { // 松弛操作 if (dist[v] != INT_MAX) { // 删除旧记录(如果存在) s.erase(s.find({dist[v], v})); } dist[v] = dist[u] + weight; // 更新新距离 s.insert({dist[v], v}); // 添加新的候选节点 } } } // 输出结果 cout << "Vertex Distance from Source:\n"; for (int i = 0; i < V; ++i) { cout << i << " \t\t " << ((dist[i] == INT_MAX) ? "INF" : to_string(dist[i])) << endl; } } // 测试函数 int main() { int vertices = 9; vector<vector<pair<int, int>>> g(vertices); g = { {{1, 4}, {7, 8}}, // Node 0 {{0, 4}, {2, 8}, {7, 11}}, // Node 1 {{1, 8}, {3, 7}, {8, 2}, {5, 4}}, {{2, 7}, {4, 9}, {5, 14}}, {{3, 9}, {5, 10}}, {{2, 4}, {3, 14}, {4, 10}, {6, 2}}, {{5, 2}, {7, 1}, {8, 6}}, {{0, 8}, {1, 11}, {6, 1}, {8, 7}}, {{2, 2}, {6, 6}, {7, 7}} }; dijkstra(g, 0, vertices); } ``` 上述代码展示了如何通过优先级队列优化迪杰斯特拉算法以求解加权有向图最短路径的问题[^2]。 --- #### Boost Graph Library 中的应用实例 除了手动编写这些算法外,还可以利用 `Boost.Graph` 库简化开发过程。下面是如何使用 BGL 执行 BFS 或 Dijkstra 的简单例子: ```cpp #include <boost/graph/adjacency_list.hpp> #include <boost/graph/breadth_first_search.hpp> #include <boost/graph/dijkstra_shortest_paths.hpp> typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::no_property, boost::property<boost::edge_weight_t, int>> WeightedGraph; int main() { using namespace boost; // 创建一个带权图 const int num_nodes = 5; enum nodes { A, B, C, D, E }; char name[] = {'A', 'B', 'C', 'D', 'E'}; WeightedGraph G(num_nodes); property_map<WeightedGraph, edge_weight_t>::type weightmap = get(edge_weight, G); add_edge(A, B, 1, G); weightmap[edge(A, B, G).first] = 1; add_edge(B, C, 2, G); weightmap[edge(B, C, G).first] = 2; add_edge(C, D, 3, G); weightmap[edge(C, D, G).first] = 3; add_edge(D, E, 4, G); weightmap[edge(D, E, G).first] = 4; // 计算最短路径 vector<int> d(num_vertices(G)); // 距离存储 dijkstra_shortest_paths(G, A, distance_map(make_iterator_property_map(d.begin(), get(vertex_index, G)))); cout << "Distances from vertex A:" << endl; for (size_t i = 0; i < num_vertices(G); ++i) cout << name[i] << " -> " << d[i] << endl; } ``` 这段程序演示了如何借助第三方库快速构建复杂场景下的最短路径分析工具[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值