เมื่อพูดถึงการค้นหาเส้นทางสั้นที่สุดในวิชาการที่ซับซ้อนอย่าง Computer Science ไม่มีคำตอบใดที่แสนจะชัดเจนและเป็นที่เรียกร้องไปกว่า Dijkstra Algorithm นี่คืออัลกอริธึมที่ได้ประดิษฐ์ขึ้นโดย Edsger W. Dijkstra ในปี 1956 ซึ่งวิเศษซึ้งในการแก้ปัญหาการค้นหาเส้นทางที่สั้นที่สุดในกราฟที่มีน้ำหนักไม่เป็นลบ วันนี้เราจะมาสำรวจหัวใจของอัลกอริธึมนี้โดยการใช้ภาษา C# เป็นสื่อกลางในการเรียนรู้ พร้อมทั้งตระหนักรู้ถึงทั้งข้อดีและข้อเสียที่แฝงอยู่
Dijkstra Algorithm ออกแบบมาเพื่อการคำนวณหาเส้นทางที่สั้นที่สุดจากโหนดเริ่มต้นไปยังโหนดอื่นๆ ในกราฟที่มีน้ำหนักของเส้นเชื่อมระหว่างโหนด เริ่มแรกทุกโหนดจะมีค่าระยะทางเป็นอินฟินิตี้ (หรือค่าที่สูงมาก) ยกเว้นโหนดเริ่มต้นที่เรากำหนดให้มีค่าเป็น 0 เมื่ออัลกอริธึมทำงาน มันจะค่อยๆ ปรับปรุงค่าระยะทางไปยังโหนดอื่นๆ ตามความสัมพันธ์ของน้ำหนักเส้นเชื่อม
using System;
using System.Collections.Generic;
class Graph
{
private int _vertices;
private List>[] _edges;
public Graph(int vertices)
{
_vertices = vertices;
_edges = new List>[vertices];
for (int i = 0; i < vertices; ++i)
_edges[i] = new List>();
}
public void AddEdge(int startVertex, int endVertex, int weight)
{
_edges[startVertex].Add(new KeyValuePair(endVertex, weight));
}
public int[] Dijkstra(int source)
{
int[] distances = new int[_vertices];
bool[] shortestPathTreeSet = new bool[_vertices];
// Initialize distances as INFINITE and stpSet as false
for (int i = 0; i < _vertices; i++)
{
distances[i] = int.MaxValue;
shortestPathTreeSet[i] = false;
}
// Distance of source vertex from itself is always 0
distances[source] = 0;
// Find shortest path for all vertices
for (int count = 0; count < _vertices - 1; count++)
{
// Pick the minimum distance vertex from the set of vertices
// not yet processed.
int u = MinDistance(distances, shortestPathTreeSet);
// Mark the picked vertex as processed
shortestPathTreeSet[u] = true;
// Update dist value of the adjacent vertices of the picked vertex.
for (int v = 0; v < _edges[u].Count; v++)
{
KeyValuePair edge = _edges[u][v];
if (!shortestPathTreeSet[edge.Key] && distances[u] != int.MaxValue && distances[u] + edge.Value < distances[edge.Key])
{
distances[edge.Key] = distances[u] + edge.Value;
}
}
}
return distances;
}
private int MinDistance(int[] distances, bool[] shortestPathTreeSet)
{
int min = int.MaxValue, minIndex = -1;
for (int v = 0; v < _vertices; v++)
if (shortestPathTreeSet[v] == false && distances[v] <= min)
{
min = distances[v];
minIndex = v;
}
return minIndex;
}
}
//Example usage
class Program
{
static void Main(string[] args)
{
Graph g = new Graph(5); // Let's create a graph with 5 vertices
g.AddEdge(0, 1, 9);
g.AddEdge(0, 2, 6);
g.AddEdge(0, 3, 5);
g.AddEdge(0, 4, 3);
g.AddEdge(2, 1, 2);
g.AddEdge(2, 3, 4);
int[] distances = g.Dijkstra(0);
for (int i = 0; i < distances.Length; i++)
Console.WriteLine($"Distance from node 0 to node {i} is {distances[i]}");
}
}
อัลกอริธึม Dijkstra ถูกนำไปใช้ในหลายๆ สถานการณ์เช่น ระบบนำทางเช่น GPS ซึ่งประมวลผลเส้นทางสั้นที่สุดจากตำแหน่งปัจจุบันไปยังปลายทาง, ในเครือข่ายคอมพิวเตอร์เพื่อคำนวณเส้นทางที่สั้นที่สุดเพื่อส่งแพ็กเก็ตข้อมูล และแม้แต่การวางแผนเส้นทางในเกมวิดีโอเกมส์ที่ต้องการความคิดที่ฉับไว
Dijkstra Algorithm มีความซับซ้อนทางการคำนวณอยู่ที่ O(V^2) สำหรับกราฟที่มี V โหนดถ้าเราไม่ใช้คิวที่มีลำดับความสำคัญ (priority queue) ซึ่งหากใช้ priority queue สามารถลดความซับซ้อนลงเหลือ O((V + E) log V) ข้อดีหลักๆ คือมันให้ผลลัพธ์ที่ถูกต้องและเชื่อถือได้ สำหรับกราฟที่มีน้ำหนักไม่เป็นลบ แต่ข้อเสียคือไม่สามารถใช้กับกราฟที่มีน้ำหนักเป็นลบเพราะอาจจะทำให้เกิดการวนซ้ำไม่สิ้นสุด นอกจากนี้ ในกรณีที่กราฟมีโหนดจำนวนมาก อัลกอริธึมอาจจะมีประสิทธิภาพที่ไม่ค่อยดีเท่าที่ควร
Dijkstra Algorithm เป็นอีกหนึ่งตัวอย่างที่แสดงให้เห็นถึงพลังแห่งปัญญาประดิษฐ์ในการแก้ปัญหาทางคณิตศาสตร์ที่มีความซับซ้อน ซึ่งการเรียนรู้และค้นคว้าอัลกอริธึมนี้ย่อมเป็นทักษะที่มีค่าแก่ผู้เรียนไม่น้อย ณ Expert-Programming-Tutor หรือ EPT เรามุ่งมั่นที่จะผลักดันให้ผู้เรียนของเราได้งัดศักยภาพที่แท้จริงของตนเองออกมาผ่านการเรียนรู้ด้านโปรแกรมมิ่ง ไม่ว่าจะเป็นการคำนวณอัลกอริธึม การพัฒนาโปรแกรม หรือการทำโปรเจคที่น่าท้าทาย มาร่วมกันสร้างสรรค์อนาคตด้านไอทีที่รุ่งโรจน์ไปกับเรา ที่ EPT วันนี้!
หมายเหตุ: ข้อมูลในบทความนี้อาจจะผิด โปรดตรวจสอบความถูกต้องของบทความอีกครั้งหนึ่ง บทความนี้ไม่สามารถนำไปใช้อ้างอิงใด ๆ ได้ ทาง EPT ไม่ขอยืนยันความถูกต้อง และไม่ขอรับผิดชอบต่อความเสียหายใดที่เกิดจากบทความชุดนี้ทั้งทางทรัพย์สิน ร่างกาย หรือจิตใจของผู้อ่านและผู้เกี่ยวข้อง
Tag ที่น่าสนใจ: dijkstra_algorithm c# graph_theory shortest_path programming algorithm computer_science graph data_structure pathfinding complexity_analysis priority_queue network_routing gps_navigation video_game_pathfinding
หากมีข้อผิดพลาด/ต้องการพูดคุยเพิ่มเติมเกี่ยวกับบทความนี้ กรุณาแจ้งที่ http://m.me/Expert.Programming.Tutor
085-350-7540 (DTAC)
084-88-00-255 (AIS)
026-111-618
หรือทาง EMAIL: NTPRINTF@GMAIL.COM