|
Dijkstra(戴克斯特拉)是一種用於計算帶有非負權重的圖中單源最短路徑的演算法。這個演算法以其作者荷蘭計算機科學家艾茲赫爾·戴克斯特拉(Edsger Dijkstra)的名字命名。 以下是 Dijkstra 演算法的基本方法與特色:
using System;
class ShortestPathAlgorithm
{
const int V = 5; // 節點數量
const int NoPath = -1;//無路徑
/// <summary>
/// 選擇未包含在最短路徑樹中,距離最短的節點
/// </summary>
/// <param name="dist">起點至各點的最短距離</param>
/// <param name="sptSet">已經拜訪過的點旗標</param>
/// <returns>傳回 索引值,起點至索引點為目前最短距離(扣除已拜訪過的點)</returns>
int MinDistance(int[] dist, bool[] sptSet)
{
int min = int.MaxValue, minIndex = NoPath;
for (int v = 0; v < V; v++)
{
if (sptSet[v] == false && dist[v] <= min)
{
min = dist[v];
minIndex = v;
}
}
return minIndex;
}
/// <summary>
/// 輸出起點到 dest 的最短路徑
/// </summary>
/// <param name="dist">起點至各點的最短距離</param>
/// <param name="parent">最短路徑連結</param>
/// <param name="dest">目標點</param>
void PrintSolution(int[] dist, int[] parent, int dest)
{
Stack <int> St = new Stack<int>();
Console.Write($"到節點 {dest} 的最短路徑:");
int i = dest;
while (parent[i] != NoPath) St.Push(i = parent[i]);
Console.Write(St.Pop());
while (St.Count > 0) Console.Write($" -> {St.Pop()}");
Console.WriteLine($" -> {dest} = {dist[dest]}");
}
/// <summary>
/// Dijkstra 最短路徑
/// </summary>
/// <param name="graph">地圖陣列</param>
/// <param name="src">起點</param>
/// <param name="dest">終點</param>
void Dijkstra(int[][] graph, int src, int dest)
{
// 初始化起始點至各點最短距離為無窮大,最短路徑已拜訪標記為 false,父節點為 NoPath
int[] dist = Enumerable.Repeat(int.MaxValue, V).ToArray();//距離
bool[] sptSet = Enumerable.Repeat(false, V).ToArray();//父節點
int[] parent = Enumerable.Repeat(NoPath, V).ToArray();//最短路徑標記
dist[src] = 0; // 起始節點到 src 自身的距離為 0
for (int count = 0; count < V - 1; count++) // 主循環,找到最短路徑
{
int u = MinDistance(dist, sptSet); // 選擇未包含在最短路徑樹中,距離最短的節點
sptSet[u] = true; // 將選定的節點標記為已納入最短路徑樹
for (int v = 0; v < V; v++) // 更新相鄰節點的最短距離
{
// 檢查節點是否未包含在最短路徑樹中,是否有邊相連,是否有更短的距離
if (!sptSet[v] && graph[u][v] != NoPath && dist[u] != int.MaxValue && dist[u] + graph[u][v] < dist[v])
{
dist[v] = dist[u] + graph[u][v]; //更新最短距離及父節點
parent[v] = u; //更新到 v 節點的路徑是從 u 點而來
}
}
}
PrintSolution(dist, parent, dest); //輸出最短距離及路徑
}
static void Main()
{
int[][] path = new int[][] //地圖路徑距離
{
new int[] {0, NoPath, 14, 3, 12},
new int[] {6, 0, NoPath, 5, 6},
new int[] {NoPath, 4, 0, 4, 2},
new int[] {5, 8, 4, 0, NoPath},
new int[] {NoPath, NoPath, 4, NoPath, 0}
};
ShortestPathAlgorithm x = new ShortestPathAlgorithm(); //x 為最短路徑物件
Console.Write("輸入起始節點 (source): "); int source = int.Parse(Console.ReadLine());
Console.Write("輸入目標節點 (destination): "); int destination = int.Parse(Console.ReadLine());
if(source != destination) x.Dijkstra(path, source, destination);
}
}
![]() ![]() ![]() ![]() |