Categories
Computer

#20 – Graph และ Shortest Path Algorithms

Shortest Path Algorithm เป็นเทคนิคหาเส้นเชื่อมโหนดเริ่มต้น ไปโหนดสิ้นสุดที่สั้นที่สุด บทความนี้เราจะแนะนำข้อมูลแบบกราฟ กับ Dijkstra และ Bellman-Ford Algorithms

เทคนิคการหาเส้นทางที่สั้นที่สุด (Shortest Path Algorithms) เป็นวิธีการหาเส้นเชื่อมระหว่างโหนดเริ่มต้น และโหนดสิ้นสุดในกราฟที่ให้ผลรวมของค่าน้ำหนักของเส้น (Edge Weight) ที่ต่ำที่สุด

For English, please follow this article on Medium.

เทคนิคเหล่านี้นำไปใช้งานทางด้าน

  • การเชื่อมต่อเครือข่าย Network
  • การเดินทาง และการจัดการจราจร
  • การหาเส้นทางการบิน
  • การออกแบบอุปกรณ์ Electronic กับการออกแบบชิบ VLSI (Very-large-scale integration)
  • เครือข่ายสังคมออนไลน์ (Social Network)

เทคนิคที่ค้นหา Shortest Path ในบทความนี้เราจะกล่าวถึง 2 เทคนิค ได้แก่ Dijkstra และ Bellman-Ford Algorithms

แต่ก่อนที่เราจะเข้าไปยังรายละเอียดของแต่ละเทคนิค เรามาเริ่มต้นด้วยข้อมูลเบื้องต้นของกราฟว่ากราฟมันคืออะไร?

สารบัญ


กราฟ (Graph)

กราฟ [1] เป็นโครงสร้างข้อมูลที่ไม่เป็นเชิงส้น (Non-linear) ที่ประกอบไปด้วยโหนด (Node หรือ Vertex (V)) และเส้น (Line หรือ Edge (E)) ที่เชื่อมระหว่างโหนดสองโหนด

กราฟสามารถแบ่งประเภทได้ตามค่าน้ำหนัก (Weight) กับตามทิศทาง (Direction) และตาม Graph Representation

แบ่งตาม Weight

การแบ่งประเภทกราฟตาม Weight นั้นมีทั้งหมด 2 ประเภท

  1. กราฟที่ไม่ระบุค่าน้ำหนัก (Unweighted Graph) ที่สามารถแทนได้ด้วย G(V, E) กราฟในลักษณะนี้จะไม่มีค่า Weight ที่กำหนดไว้บนเส้นของกราฟ
  2. กราฟที่ระบุค่าน้ำหนัก (Weighted Graph) ที่แทนได้ด้วย G(V, E, W) กราฟในลักษณะนี้จะได้รบการกำหนดค่า Weight (ค่า W) ไว้บนเส้นของกราฟ
กราฟที่ไม่ได้ระบุ และระบุค่าน้ำหนัก (Unweighted และ Weighted graphs)

แบ่งตาม Direction

การแบ่งประเภทกราฟตาม Direction นั้นมีทั้งหมด 2 ประเภท

  1. กราฟที่ไม่ระบุทิศทาง (Undirected Graph) กราฟประเภทนี้จะอนุญาตให้ตัว Algorithm สามารถเดินทางไป-กลับบนเส้นของกราฟได้
  2. กราฟที่ระบุทิศทาง (Directed Graph) กราฟชนิดนี้จะระบุทิศทางไว้บนกราฟเพื่อกำหนดทิศทางการเดินของเส้นของกราฟ
กราฟที่ระบุ และไม่ระบุทิศทาง (Undirected กับ Directed Graphs) การของเดินบนเส้นในฟราก

แบ่งตาม Graph Representation

กราฟสามารถแทนได้ด้วยการใช้ Adjacency Matrix กับ Adjacency List

Adjacency Matrix เป็นการกำหนดตัวแปรให้อยู่ในรูป Array ซ้อน Array (Nested Array) ที่เป็นตัวแปรประเภท Integer หรือ Boolean โดย

  • กราฟที่ไม่ได้ระบุค่า Weight (Unweighted Graph): เราจะกำหนดให้ในกรณีที่โหนดไม่ได้เชื่อมไปยังโหนดอื่นนั้นมีค่าเท่ากับ 0 แต่กรณีที่ได้เชื่อมไปยังอีกโหนด เราจะกำหนดให้มีค่าเท่ากับ 1
  • กราฟที่ระบุค่า Weight (Weighted Graph): เราจะกำหนดให้ในกรณีที่โหนดไม่ได้เชื่อมไปยังโหนดอื่นมีค่าเท่ากับ 0 แต่กรณีที่เชื่อมไปยังโหนดอื่น เราจะกำหนดให้มีค่าบนเส้นนั้นมีค่ามากกว่า 0 (หรือน้อยกว่า 0 ก็ได้) ขึ้นกับว่าเราจะกำหนดค่าน้ำหนัก (Weight) ของเส้นนั้นมีค่าเท่าไร

เราสามารถดูตัวอย่างได้ตามด้านล่างนี้

การกำหนด Adjacency Matrix ในกรณีที่กราฟไม่ได้ระบุค่า Weight (Unweighted Graph)
การกำหนด Adjacency Matrix ในกรณีที่กราฟระบุค่า Weight (Weighted Graph)

Adjacency List เป็นการกำหนดตัวแปรให้อยู่ในรูป Array ที่มี Linked List เพื่อกำหนดว่าโหนดนั้นเชื่อมไปยังโหนดอื่นหรือไม่ โดย

  • กราฟที่ไม่ได้ระบุค่า Weight (Unweighted Graph): เราจะไม่ได้กำหนด Weight ลงไปใน Node ของ Linked List
  • กราฟที่ระบุค่า Weight (Weighted Graph): เราจะกำหนดค่า Weight ลงไปใน Node ของ Linked List นั้น ๆ

เราสามารถดูตัวอย่างได้ตามด้านล่างนี้

การกำหนด Adjacency List ในกรณีที่กราฟไม่ได้ระบุค่า Weight (Unweighted Graph)
การกำหนด Adjacency List ในกรณีที่กราฟระบุค่า Weight (Weighted Graph)

หลังจากที่ทราบข้อมูลเบื้องต้นที่เกี่ยวกับกราฟแล้ว เรามาดูเทคนิคที่เกี่ยวข้องกับการหา Shortest Path ได้แก่ Dijkstra’s and Bellman-Ford’s algorithms

เลื่อนขึ้นไปข้างบนสุด ↑


Dijkstra’s Algorithm

Dijkstra’s algorithm [2, 3] เป็นเทคนิคการหา Shortest Path ที่มีประโยชน์ และได้รับความนิยมสำหรับการหาเส้นทางที่สั้นที่สุดจากโหนดเริ่มต้นไปยังโหนดปลายทางโดยใช้สำหรับกราฟที่ไม่มีค่าน้ำหนักบนเส้น Edge ที่มีค่าเป็นลบ (Negative Edge Weight)

เทคนิคนี้ได้รับการตั้งชื่อตามนักวิจัยชาว Dutch ที่มีชื่อว่า Edsger W. Dijkstra

ขั้นตอนการทำงาน

ขั้นตอนแรก เรากำหนดให้

  • โหนดเริ่มต้นเป็นโหนดที่ 1
  • ระยะทาง (distance) ในโหนดที่ 1 มีค่าเท่ากับ 0 ส่วนโหนดอื่นกำหนดให้มีค่าเท่ากับ Infinity
  • ตัวแปรเพื่อแสดงว่าเราไปยังโหนดนั้น ๆ แล้ว (Visited) มีค่าเท่ากับ False

ขั้นตอนที่สอง เราพิจารณาจากโหนดปัจจุบัน เพื่อดูโหนดข้างเคียงตามเส้นเชื่อมทุกโหนดที่ยังไม่ได้ไปเยือน และคำนวณหาระยะทางต่อเชื่อมจากเส้นเชื่อม เพื่อดูว่าค่าที่ได้มีค่าน้อยที่สุดหรือไม่ ในกรณีที่ค่านั้นมีค่าน้อยที่สุด ให้เราอัพเดทระยะทางใหม่ด้วยค่าที่เราคำนวณได้

หลังจากนั้น เรากำหนดให้โหนดปัจจุบันที่เราเข้าไปแล้วให้มีค่า Visited เท่ากับ True เพื่อแสดงให้เห็นว่าเราไปเยือนโหนดนั้น ๆ เรียบร้อย

เราแสดงตัวอย่างการพิจารณาในแต่ละโหนดได้ตามขั้นตอนตามด้านล่างนี้

หนึ่ง เราพิจารณาในโหนดที่ 1 ด้วยการคำนวณระยะทาง (Distance) จากโหนดที่ 1 ไปยังโหนดข้างเคียง ได้แก่โหนดที่ 2 และ 3 โดยคำนวณได้ตามด้านล่างนี้

  • Distance of 2 = (Distance of 1) + (Weight from 1 to 2) = 0 + 3 = 3
  • Distance of 3 = (Distance of 1) + (Weight from 1 to 3) = 0 + 2 = 2

ผลลัพธ์การคำนวณระยะทางจากโหนดที่ 1 ไปโหนดที่ 2 และ 3 มีค่าเท่ากับ 3 และ 2 ตามลำดับ ซึ่งมีค่าน้อยกว่า infinity ให้เรานำค่านั้นไปอัพเดทในตาราง และกำหนดให้โหนดที่ 1 ได้รับการเยือนเรียบร้อย (ด้วยกำหนด Visited ให้เป็น True)

สอง เราพิจารณาในโหนดข้างเคียงที่เชื่อมจากโหนดที่ 1 โดยเราพิจารณาในโหนดที่ 2 ก่อน

โหนดนี้จะมีโหนดที่เชื่อมต่อจากโหนดที่ 2 เพียงโหนดเดียว คือโหนดที่ 3 ให้เราคำนวณหาระยะทางโดยการนำค่าที่ได้จากขั้นตอนก่อนหน้า มาบวกกับระยะทางระหว่างระหว่างโหนดที่ 2 และ 3

การคำนวณแสดงได้ตามด้านล่างนี้

  • Distance of 3 = (Distance of 2) + (Weight from 2 to 3) = 3 + 2 = 5

ผลลัพธ์ที่ได้จะมีค่าเท่ากับ 5 ซึ่งมีค่ามากกว่าผลลัพธ์ที่ได้จากการคำนวณในขั้นตอนก่อนหน้าที่หาระยะทางระหว่างโหนดที่ 1 และโหนดที่ 3 ดังนั้นแล้ว เราจะไม่อัพเดทค่านี้ในตาราง

ต่อมาเรากำหนดให้โหนดที่ 2 ได้รับการเยือนเรียบร้อย (ด้วยกำหนด Visited ให้เป็น True)

สาม เราพิจารณาในโหนดข้างเคียงที่เชื่อมจากโหนดที่ 1 อีกโหนดหนึ่ง คือโหนดที่ 3

โหนดนี้จะมีโหนดที่เชื่อมต่อจากโหนดที่ 3 เพียง 2 โหนด คือโหนดที่ 4 และโหนดที่ 5 ให้เราคำนวณหาระยะทางโดยการนำค่าที่ได้จากขั้นตอนก่อนหน้า มาบวกกับระยะทางระหว่างระหว่างโหนดที่ 3 กับโหนดที่เชื่อมต่อกัน

การคำนวณแสดงได้ตามด้านล่างนี้

  • Distance of 4 = (Distance of 3) + (Weight from 3 to 4) = 2 + 4 = 6
  • Distance of 5 = (Distance of 3) + (Weight from 3 to 5) = 2 + 3 = 5

ผลลัพธ์การคำนวณระยะทางจากโหนดที่ 3 ไปโหนดที่ 4 และ 5 มีค่าเท่ากับ 6 และ 5 ตามลำดับ ซึ่งมีค่าน้อยกว่า infinity ให้เรานำค่านั้นไปอัพเดทในตาราง และกำหนดให้โหนดที่ 3 ได้รับการเยือนเรียบร้อย (กำหนด Visited ให้เป็น True)

สี่ เราพิจารณาในโหนดข้างเคียงที่เชื่อมจากโหนดที่ 3 โดยเราพิจารณาในโหนดที่ 4 ก่อน

โหนดนี้จะมีโหนดที่เชื่อมต่อจากโหนดที่ 4 เพียงโหนดเดียว คือโหนดที่ 5 ให้เราคำนวณหาระยะทางโดยการนำค่าที่ได้จากขั้นตอนก่อนหน้า มาบวกกับระยะทางระหว่างระหว่างโหนดที่ 4 และ 5

การคำนวณแสดงได้ตามด้านล่างนี้

  • Distance of 5 = (Distance of 4) + (Weight from 4 to 5) = 6 + 3 = 9

ผลลัพธ์ที่ได้จะมีค่าเท่ากับ 9 ซึ่งมีค่ามากกว่าผลลัพธ์ที่ได้จากการคำนวณในขั้นตอนก่อนหน้าที่หาระยะทางระหว่างโหนดที่ 3 และโหนดที่ 5 ดังนั้นแล้ว เราจะไม่อัพเดทค่านี้ในตาราง

ต่อมาเรากำหนดให้โหนดที่ 4 ได้รับการเยือนเรียบร้อย (Visited เท่ากับ True)

ห้า เราพิจารณาในโหนดข้างเคียงที่เชื่อมจากโหนดที่ 3 อีกโหนดหนึ่ง คือโหนดที่ 5

โหนดนี้จะไม่มีโหนดที่เชื่อมต่อจากโหนดที่ 5 เลย ดังนั้น เราไม่จำเป็นต้องคำนวณอะไรในโหนดนี้อีก

สุดท้าย เราจะได้ Shortest Path โดยเดินจากโหนดที่ 1 ผ่านโหนดที่ 3 ไปยังโหนดที่ 5 โดยการแสดงภาพตามด้านล่างนี้

เขียนโค้ดด้วย Python

def djikstra_algorithm(distance, start = 0, final = 5):
    visited, dist_table = [], []
    for i in range(final + 1):
        visited.append(False)
        dist_table.append([float('inf'), None])

    queue = [start]
    dist_table[start][0] = 0
    while len(queue) > 0:
        vertex = queue.pop(0)
        visited[vertex] = True
        dist_previous, parent_previous = dist_table[vertex]
        for idx, dist_each in enumerate(distance[vertex]):
            if visited[idx] or dist_each == 0:
                continue

            if (dist_each + dist_previous) < dist_table[idx][0]:
                dist_table[idx][0] = dist_each + dist_previous
                dist_table[idx][1] = vertex
                queue.append(idx)

    vertex = dist_table[final]
    path = [final]
    distance = vertex[0]
    parent = vertex[1]
    while parent is not None:
        vertex = dist_table[parent]
        path.append(parent)
        parent = vertex[1]

    return path

เขียนโค้ดด้วย JavaScript

function djikstra_algorithm(distance, start = 0, final = 5)
{
  let dist_table = [], visited = [];
  for(let i = start; i <= final; i++) {
    dist_table.push([Infinity, null]);
    visited.push(false);
  }
  
  let queue = [start]
  dist_table[start] = [0, null];
  
  while(queue.length > 0) {
    let vertex = queue.shift();
    let [dist_current, parent] = dist_table[vertex];
    visited[vertex] = true;
    
    for(let target = 0; target < distance.length; target++) {
      let weight = distance[vertex][target];
      if((!visited[target] && weight > 0) && (dist_current + weight < dist_table[target][0]) ) {
        dist_table[target] = [
          dist_current + weight, vertex
        ];
        
        queue.push(target);
      }
    }
  }
  
  let [dist, prev] = dist_table[final];
  let path = [final];
  while(prev != null) {
    path.push(prev);
    [dist, prev] = dist_table[prev];
  }
  
  return path;
}

Computational Complexity

Time Complexity ของ Algorithm นี้ด้วย

  • การใช้ Adjacency Matrix มีค่าเท่ากับ O(V^2)
  • การใช้ Adjacency List มีค่าเทา่กับ O(E log V)

ส่วน Space Complexity ของ Algorithm นี้มีค่าเท่ากับ O(V)

สำหรับรายละเอียดเกี่ยวกับ Time Complexity, Space Complexity และตัว Big-O อ่านได้ที่บทความที่แล้ว

เลื่อนขึ้นไปข้างบนสุด ↑


Bellman-Ford Algorithm

Bellman-Ford Algorithm [4] เป็นเทคนิคในการหา Shortest Path อีกเทคนิคหนึ่งที่มีลักษณะการทำงานคล้ายกันกับ Dijkstra’s Algorithm แต่มีข้อแตกต่างอยู่ โดย Bellman-Ford Algorithm รองรับ

  • กราฟที่เป็น Unweighted กับ Weighted graphs
  • การตรวจสอบว่ากราฟเป็นมี Negative Cycle หรือไม่ ถ้ามีผลลัพธ์การคำนวณจะมีค่าลดลงไปเรื่อย ๆ จนเกิดเป็นการวนลูปไม่มีที่สิ้นสุด (Indefinite Loop)

ขั้นตอนการทำงาน

ขั้นตอนแรก เรากำหนดให้โหนดเริ่มต้น (Source ที่แสดงเป็นวงกลมสีเขียวตามภาพด้านล่างนี้) มีค่าระยะทาง (Distance) เท่ากับ 0 ส่วนโหนดอื่นมีค่าเท่ากับ Infinity

ต่อมา เราหา Shortest Path ในกราฟ โดยกราฟมีโหนดทั้งหมด N โหนด ให้เราคำนวณ Distance บริเวณโหนดเริ่มต้นเสียก่อน จากนั้นประมวลผลในทุกโหนด [edges(u, v, weight)] เพื่อหา Shortest Path ทั้งหมด N-1 ครั้ง ด้วยการคำนวณตามฟังก์ชัน dist[v] = minimum(dist[v], distance[u] + weight)

ขั้นตอนการประมวลผลแสดงรายละเอียดตามด้านล่างนี้

หนึ่ง คำนวณ Distance ในโหนดที่ 1 โดยในโหนดนี้จะเชื่อมต่อไปอีก 2 โหนด ได้แก่ โหนดที่ 2 และโหนดที่ 3

เราสามารถคำนวณหาระยะทางระหว่างโหนดปัจจุบันกับโหนดที่เชื่อมต่อกันได้ตามด้านล่างนี้

  • Distance of 2 = (Distance of 1) + (Weight from 1 to 2) = 0 + 3 = 3
  • Distance of 3 = (Distance of 1) + (Weight from 1 to 3) = 0 + 2 = 2

ค่าที่ได้จากการคำนวณจากโหนดที่ 1 ไปโหนดที่ 2 และ 3 มีค่าน้อยกว่า Infinity ดังนั้น เราจะอัพเดท Distance ลงไปในตาราง

สอง คำนวณ Distance ในโหนดที่ 2 โดยในโหนดนี้จะเชื่อมต่อไปอีก 1 โหนด คือโหนดที่ 3

การคำนวณระยะทางของโหนดนี้เราทำได้โดยเอาค่าการคำนวณระยะทางจากจากโหนดเริ่มต้น มายังโหนดปัจจุบัน (โหนดที่ 1 มายังโหนดที่ 2) มาบวกกับระยะทางระหว่างโหนดปัจจุบันกับโหนดที่เชื่อมกันอยู่

การคำนวณทำได้ตามด้านล่างนี้

  • Distance of 3 = (Distance of 2) + (Weight from 2 to 3) = 3 + 2 = 5

ค่าที่ได้จากการคำนวณจากโหนดที่ 2 ไปโหนดที่ 3 มีค่ามากกว่าการคำนวณจากข้อที่แล้ว ดังนั้นเราจะไม่อัพเดทค่านี้ลงไปในตาราง

สาม คำนวณ Distance ในโหนดที่ 3 โดยในโหนดนี้จะเชื่อมต่อไปอีก 2 โหนด ได้แก่โหนดที่ 4 และ 5

การคำนวณทำได้ตามด้านล่างนี้

  • Distance of 4 = (Distance of 3) + (Weight from 3 to 4) = 2 + 4 = 6
  • Distance of 5 = (Distance of 3) + (Weight from 3 to 5) = 2 + 3 = 5

ค่าที่ได้จากการคำนวณ ไปโหนดที่ 4 และ 5 มีค่าน้อยกว่า Infinity ดังนั้นเราจะอัพเดทค่าเหล่านี้ลงไปในตาราง

สี่ คำนวณ Distance ในโหนดที่ 4 โดยในโหนดนี้จะเชื่อมต่อไปอีก 1 โหนด คือโหนดที่ 5

การคำนวณทำได้ตามด้านล่างนี้

  • Distance of 5 = (Distance of 4) + (Weight from 4 to 5) = 6 + 3 = 9

ค่าที่ได้จากการคำนวณมีค่ามากกว่าการคำนวณจากข้อที่ผ่านมา ดังนั้นเราจะไม่อัพเดทค่านี้ลงไปในตาราง

หลังจากที่วนลูปเข้าไปดูในแต่ละโหนดของกราฟตามขั้นตอนที่กล่าวมาข้างบนนี้เรียบร้อยแล้ว เรามาวนลูปอีกรอบหนึ่งเพื่อมองหา Negative Cycle ในกราฟว่ามีหรือไม่?

เหตุผลของการวนลูปเข้าไปในกราฟอีกรอบหนึ่งเพื่อคำนวณระยะทางอีกรอบ แล้วตรวจสอบว่าระยะทางที่ผ่านการคำนวณนั้นสั้นกว่าที่เราได้บันทึกในตารางหรือไม่ ถ้าใช่ แสดงว่าเราพบ Negative Cycle ในกราฟ

เขียนโค้ดด้วย Python

class Graph:
 def __init__(self, vertices):
  self.V = vertices
  self.graph = []
  
 def add(self, source, destination, weight):
  self.graph.append([
    source, destination, weight
   ])
   
 def bellmanford(self, source):
  distance = [float('inf') for i in range(self.V)]
  previous = [None for i in range(self.V)]
  distance[source] = 0
  
  for _ in range(self.V - 1):
   for s, d, w in self.graph:
    if distance[s] != float('inf') and distance[s] + w < distance[d]:
     distance[d] = distance[s] + w
     previous[d] = s
     
  for s, d, w in self.graph:
   if distance[s] + w < distance[d]:
    print("Error: Negative Cycle Exists")
    return None, None
    
  return distance, previous
  
if __name__ == '__main__':
 g = Graph(5)
 g.add(0, 1, 5)
 g.add(0, 2, 4)
 g.add(1, 3, 3)
 g.add(2, 1, 6)
 g.add(3, 2, 2)
 
 distance, previous = g.bellmanford(0)
 
 for i, (d, p) in enumerate(zip(distance, previous)):
  print(i, d, p)

เขียนโค้ดด้วย JavaScript

class Graph
{
  constructor(vertex)
  {
    this.vertex = vertex;
    this.graph = [];
  }
  
  add(source, destination, value)
  {
    this.graph.push([
      source, destination, value
    ]);
  }
  
  bellmanford(source)
  {
    let distance = [], previous = [];
    for(let i = 0;  i < this.vertex; i++) {
      distance.push(Infinity);
      previous.push(null);
    }
    
    distance[source] = 0;
    
    let target_loop_range = this.vertex - 1;
    for(let i = 0; i < target_loop_range; i++) {
      for(let [s, d, weight] of this.graph) {
        if(distance[s] != Infinity && 
     distance[s] + weight < distance[d]) {
          distance[d] = distance[s] + weight;
          previous[d] = s;
        }
      }
    }
    
    for(let [s, d, weight] of this.graph) {
      if(distance[s] + weight < distance[d]) {
        console.error("Error: Negative Cycle Exists");
        return [null, null];
      }
    }
    
    return [distance, previous];
  }
}

g = new Graph(5);
g.add(0, 1, 5);
g.add(0, 2, 4);
g.add(1, 3, 3);
g.add(2, 1, 6);
g.add(3, 2, 2);

let [distance, previous] = g.bellmanford(0);

if(distance && previous) {
  for(let i = 0; i < distance.length; i++) {
    let d = distance[i],
        p = previous[i];
    console.log(`${ i }: ${ d }, ${ p }`);
  }
}

Computational Complexity

Time Complexity ของ Algorithm นี้ในกรณีที่เป็น

  • Best case: เมื่อค่าระยะทางที่คำนวณได้หลังจากที่วนลูปที่ 1 และ 2 มีค่าเท่ากันแล้ว เราจะได้ค่าเท่ากับ O(E)
  • Average กับ Worst Case: มีค่าเท่ากับ O(VE)

ส่วน Space Complexity ของ Algorithm นี้มีค่าเท่ากับ O(V)

เลื่อนขึ้นไปข้างบนสุด ↑


สรุป

เทคนิคการหาเส้นทางที่สั้นที่สุด (Shortest Path Algorithms) เป็นวิธีการหาเส้นเชื่อมระหว่างโหนดเริ่มต้น และโหนดสิ้นสุดในกราฟที่ให้ผลรวมของค่าน้ำหนักของเส้น (Edge Weight) ที่ต่ำที่สุด

เทคนิคที่เราได้กล่าวถึงในบทความนี้ก็ได้แก่ Dijkstra กับ Bellman-Ford Algorithms ที่มีความคล้ายคลึงกัน แต่ Bellman-Ford Algorithm รองรับการจัดการกับกราฟที่มี Negative Edge Weight และ Negative Cycle ครับ

สำหรับผู้อ่านที่เห็นว่าบทความนี้ดี มีประโยชน์ ให้กดไลค์ หรือกดแชร์ไปยังแพลตฟอร์มโซเชียลต่าง ๆ นอกจากนี้ ผู้อ่านยังติดตามได้่ใน Linkedin หรือ X (หรือ Twitter) ได้ครับ

เลื่อนขึ้นไปข้างบนสุด ↑


ที่มา

  1. https://www.geeksforgeeks.org/introduction-to-graphs-data-structure-and-algorithm-tutorials/
  2. Grok AI
  3. https://www.geeksforgeeks.org/introduction-to-dijkstras-shortest-path-algorithm/#dijkstras-algorithm
  4. https://www.geeksforgeeks.org/bellman-ford-algorithm-dp-23/

เลื่อนขึ้นไปข้างบนสุด ↑

By Kittisak Chotikkakamthorn

อดีตนักศึกษาฝึกงานทางด้าน AI ที่ภาควิชาวิศวกรรมไฟฟ้า มหาวิทยาลัย National Chung Cheng ที่ไต้หวัน ที่กำลังหางานทางด้าน Data Engineer ที่มีความสนใจทางด้าน Data, Coding และ Blogging / ติดต่อได้ที่: contact [at] nickuntitled.com

Exit mobile version