Tài Liệu Học Tập
No Result
View All Result
  • Đề Thi
  • Lớp 12
    • Lịch Sử Lớp 12
    • Địa Lí Lớp 12
    • Ngữ Văn Lớp 12
    • GD KTPL Lớp 12
    • Toán Lớp 12
    • Tiếng Anh Lớp 12
    • Hóa Học Lớp 12
    • Sinh Học Lớp 12
    • Vật Lí Lớp 12
  • Lớp 11
    • Toán Lớp 11
    • Ngữ Văn Lớp 11
    • Tiếng Anh Lớp 11
    • Hóa Học Lớp 11
    • Sinh Học Lớp 11
    • Vật Lí Lớp 11
    • Lịch Sử Lớp 11
    • Địa Lí Lớp 11
    • GDCD Lớp 11
  • Lớp 10
    • Toán Lớp 10
    • Ngữ Văn Lớp 10
    • Tiếng Anh Lớp 10
    • Hóa Học Lớp 10
    • Sinh Học Lớp 10
    • Vật Lí Lớp 10
    • Lịch Sử Lớp 10
    • Địa Lí Lớp 10
    • GDKTPL Lớp 10
    • Công nghệ lớp 10
    • Tin Học Lớp 10
  • Lớp 9
    • Toán Lớp 9
    • Ngữ Văn Lớp 9
    • Tiếng Anh Lớp 9
    • Lịch sử và địa lý lớp 9
    • Khoa Học Tự Nhiên Lớp 9
    • GDCD Lớp 9
  • Lớp 8
    • Toán Lớp 8
    • Ngữ Văn Lớp 8
    • Tiếng Anh Lớp 8
    • Lịch sử và địa lý lớp 8
    • Khoa Học Tự Nhiên Lớp 8
    • GDCD 8
  • Lớp 7
    • Toán Lớp 7
    • Văn Lớp 7
    • Tiếng Anh Lớp 7
    • Lịch Sử Và Địa Lí Lớp 7
    • Khoa Học Tự Nhiên Lớp 7
  • Lớp 6
    • Toán Lớp 6
    • Văn Lớp 6
    • Tiếng Anh lớp 6
    • Lịch Sử và Địa Lí Lớp 6
    • Khoa Học Tự Nhiên lớp 6
  • Lớp 5
    • Toán lớp 5
    • Tiếng Việt Lớp 5
    • Tiếng Anh Lớp 5
    • Lịch Sử và Địa Lí Lớp 5
  • Lớp 4
    • Toán lớp 4
    • Tiếng Việt Lớp 4
    • Tiếng Anh Lớp 4
    • Lịch Sử và Địa Lí Lớp 4
  • Lớp 3
    • Toán lớp 3
    • Tiếng Anh Lớp 3
    • Tiếng Việt Lớp 3
  • Mẹo Hay
  • Tin tức
  • Liên Hệ
Tài Liệu Học Tập
No Result
View All Result
Home Văn học

Bài toán tìm đường đi ngắn nhất với giải thuật Dijkstra

by Tranducdoan
05/04/2026
in Văn học
0
Đánh giá bài viết

Với các bạn sinh viên chuyên ngành công nghệ thông tin, chắc không lạ gì với bài toán tìm đường đi ngắn nhất (Shortest Path Problems) trong đồ thị trọng số nữa. Ở bài viết lần này, mình sẽ làm 3 việc:

  • Giới thiệu bài toán tìm đường đi ngắn nhất và ứng dụng của nó.
  • Giải thích giải thuật Dijkstra để giải quyết bài toán trên
  • Viết giải thuật Dijkstra bằng code Ruby .

Mục Lục Bài Viết

  1. 1. Giới thiệu bài toán tìm đường đi ngắn nhất
  2. 2. Giải thích về giải thuật Dijkstra
  3. 3. Giải thuật Diijkstra với code Ruby

1. Giới thiệu bài toán tìm đường đi ngắn nhất

Mình sẽ đưa ra một ví dụ cơ bản về bài toán này.

Bài toán: Cho một đồ thị trọng số gồm các nodes A,B,C,D,E,F và khoảng cách giữa các nodes tương ứng với các cạnh như hình bên dưới . Tìm đường đi ngắn nhất từ node B đến các node còn lại trong đồ thị?

Sau khi giải bài toán, ta được kết quả như sau. Đường đi ngắn nhất từ A đến 5 node còn lại:

  • Từ A -> B : A – B, tổng độ dài đường đi = 2
  • Từ A -> C : A – C, tổng độ dài đường đi = 5
  • Từ A -> D : A – D, tổng độ dài đường đi = 1
  • Từ A -> E : A – D – E, tổng độ dài đường đi = 2
  • Từ A -> F : A – D – E – F, tổng độ dài đường đi = 4

Để nói về ứng dụng của việc giải bài toán này, nếu bạn thay các node bằng các giao lộ, và các cạnh của nó là các tuyến đường, ta sẽ có 1 bài toán rất quen thuộc. Bài toán tìm đường đi ngắn nhất đến một địa điểm trên bản đồ.

Ví dụ như hình ở trên, bằng cách giải quyết bài toán này, bạn sẽ tìm được lộ trình ngắn nhất để đi từ vị trí của bạn đến Mễ Trì Thượng.

Ngoài ra, nếu thay các node bằng các router mạng hoặc các host , chúng ta có bài toán định tuyến đường đi của một hệ thống mạng – loại bài toán cơ bản mà các kỹ sư mạng cần phải biết đến:

Có khá nhiều giải thuật được đưa ra để giải quyết bài toán này : Dijkstra’s algorithm , Bellman-Ford algorithm, A* search algorithm, Floyd-Warshall algorithm, …..

Tuy nhiên ở bài viết này, mình sẽ giải thích về giải thuật Dijkstra và cách để viết nó bằng code Ruby.

2. Giải thích về giải thuật Dijkstra

Mô tả về giải thuật Dijkstra:

  • Bước 1: Chọn S = {} là tập các soure_node bao gồm current_node và passed_node . Với current_node là node đang được xét đến, passed_node là các node đã được xét. current_node đầu tiên sẽ là node đích của bài toán tìm đường đi ngắn nhất.
  • Bước 2: Khởi tạo giải thuật với current_node là node đích và cost(N) là giá trị của đường đi ngắn nhất từ N đến node đích.
  • Bước 3: Xét các node kề N với current_node . Gọi d(current_node,N) là khoảng cách giữa node kề N và current_node . Với p = d(current_node,N) + cost (current_node). Nếu p < cost(N) thì cost(N) = p . Nếu không thì cost(N) giữ nguyên giá trị .
  • Bước 4: Sau khi xét hết các node kề N, đánh dấu current_node thành passed_node .
  • Bước 5: Tìm current_node mới với 2 điều kiện: không phải passed_node và cost(current_node) là nhỏ nhất
  • Bước 6: Nếu tập S = {} chứa đủ các node của đồ thị thì dừng thuật toán. Nếu không thì quay trở lại Bước 3 .

Để giải thích về cách giải thuật Dijkstra hoạt động, mình sẽ sử dụng đồ thị trọng số dưới đây để đi tìm đường đi ngắn nhất từ node C đến mọi node còn lại trong đồ thị :

Trong quá trình thuật toán chạy, ta gọi cost(node) là khoảng cách ngắn nhất từ mỗi node đến node C và đánh dấu nó trên hình (giá trị số màu xanh da trời) . Khi thuật toán mới bắt đầu, ta mặc định lưu cost(C) = 0 , cost(A) = cost(B) = cost(D) = cost(E) = infinity.

Ta cũng đánh dấu current_node (node đang xét hiện tại) bằng một dấu chấm đỏ trên hình. current_node đầu tiên sẽ là node đích của bài toán – ở đây là C.

Thuật toán bắt đầu chạy bằng cách xét tất cả các node kề với current_node (các node được nối trực tiếp với current_node ) , ở đây là A, B và D. Ta sẽ bắt đầu với node B trước và thực hiện 4 bước:

  • Đầu tiên ta tìm được khoảng các từ current_node đến node B: d(C,B) = 7.
  • Tính toán giá trị đường đi từ node đích -> current_node -> node B : p = d(C,B) + cost(current_node) = 0 + 7 = 7
  • Nếu giá trị vừa tính p < cost(B) thì cost(B) = p, ngược lại thì cost(B) giữ nguyên. ( ở đây 7 < infinity nên cost(B) = 7 )
  • Đánh dấu cost(B) lên hình.

Tương tự với A và D, ta cũng tìm được cost(A) = 1 và cost(D) = 2 .

Sau khi xét hết tất cả các node kề với current_node, ta chuyểncurrent_node thành passed_node – tức là node đã được xét rồi. passed_node sẽ được đánh 1 dấu tích xanh trên hình.

Bài toán tìm đường đi ngắn nhất với giải thuật Dijkstra

Bây giờ chúng ta sẽ chọn 1 current_node mới với 2 điều kiện:

  • current_node không thể là passed_node.
  • cost(current_node) có giá trị nhỏ nhất.

Nếu xét trên hình, current_node tiếp theo sẽ là node A . Ta đánh dấu node A với 1 dấu chấm đỏ.

Ta tiếp tục giải thuật bằng cách xét các node kề với current_node với điều kiện node kề không được là passed_node . Như vậy ở đây ta chỉ được xét node B .

  • d(A,B) = 3, cost(A) = 1 .
  • p = d(A,B) + cost(A) = 4
  • p < cost(B) ( 4 < 7 ) . Vậy cost(B) = 4
  • Đánh dấu cost(B) lên hình

Bài toán tìm đường đi ngắn nhất với giải thuật Dijkstra

Đánh dấu node A trở thành passed_node. Ta tiếp tục tìm current_node mới, lần này nó là node D với cost(D) = 2:

Bài toán tìm đường đi ngắn nhất với giải thuật Dijkstra

Có 2 node kề với D là B và E.

Xét với node B

  • d(D,B) = 5, cost(D) = 2 .
  • p = d(D,B) + cost(D) = 7
  • p > cost(B) ( 7 > 4 ) . Vậy cost(B) = 4
  • Giữ nguyên cost(B)

Xét với node E

  • d(D,E) = 7, cost(D) = 2 .
  • p = d(D,E) + cost(D) = 9
  • p < cost(E) ( 7 < infinity ) . Vậy cost(E) = 9
  • Đánh dấu cost(E) lên hình.

Đánh dấu node D trở thành passed_node. Ta tiếp tục tìm current_node mới, lần này nó là node B với cost(B) = 4 :

Chỉ còn 1node kề với B là E.

Xét với node E

  • d(B,E) = 1, cost(B) = 4 .
  • p = d(B,E) + cost(B) = 5
  • p < cost(E) ( 5 < 9 ) . Vậy cost(E) = 5
  • Đánh dấu cost(E) lên hình.

Giờ chúng ta không còn node nào để check nữa. Đánh dấu node E trở thành passed_node và kết thúc thuật toán.

Vậy ta có kết quả của thuật toán với đường đi ngắn nhất từ C đến các điểm còn lại là:

  • Từ C -> A: C – A, cost(A) = 1
  • Từ C -> B: C – A – B, cost(B) = 4
  • Từ C -> D: C – D, cost(D) = 2
  • Từ C -> E: C – A – B – E, cost(E) = 5

3. Giải thuật Diijkstra với code Ruby

Mình đã giải thích rất rõ cách hoạt động của giải thuật Dijkstra rồi. Nên việc triển khai nó trong code Ruby khá dễ hiểu.

Đây là sourecode Ruby về giải thuật này:

class Graph # Constructor def initialize @g = {} # the graph // {node => { edge1 => weight, edge2 => weight}, node2 => … @nodes = Array.new @INFINITY = 1 << 64 end def add_edge(s,t,w) # s= source, t= target, w= weight if (not @g.has_key?(s)) @g[s] = {t=>w} else @g[s][t] = w end # Begin code for non directed graph (inserts the other edge too) if (not @g.has_key?(t)) @g[t] = {s=>w} else @g[t][s] = w end # End code for non directed graph (ie. deleteme if you want it directed) if (not @nodes.include?(s)) @nodes << s end if (not @nodes.include?(t)) @nodes << t end end # based of wikipedia’s pseudocode: http://en.wikipedia.org/wiki/Dijkstra’s_algorithm def dijkstra(s) @d = {} @prev = {} @nodes.each do |i| @d[i] = @INFINITY @prev[i] = -1 end @d[s] = 0 q = @nodes.compact while (q.size > 0) u = nil; q.each do |min| if (not u) or (@d[min] and @d[min] < @d[u]) u = min end end if (@d[u] == @INFINITY) break end q = q – [u] @g[u].keys.each do |v| alt = @d[u] + @g[u][v] if (alt < @d[v]) @d[v] = alt @prev[v] = u end end end end # To print the full shortest route to a node def print_path(dest) if @prev[dest] != -1 print_path @prev[dest] end print “>#{dest}” end # Gets all shortests paths using dijkstra def shortest_paths(s) @source = s dijkstra s puts “Source: #{@source}” @nodes.each do |dest| puts “nTarget: #{dest}” print_path dest if @d[dest] != @INFINITY puts “nDistance: #{@d[dest]}” else puts “nNO PATH” end end end end gr = Graph.new gr.add_edge(“a”,”b”,5) gr.add_edge(“b”,”c”,3) gr.add_edge(“c”,”d”,1) gr.add_edge(“a”,”d”,10) gr.add_edge(“b”,”d”,2) gr.add_edge(“f”,”g”,1) gr.shortest_paths(“a”)

Mình sẽ thử chạy nó ở trong terminal nhé:

Bài viết của mình còn nhiều thiếu xót, mong nhận được nhiều phản hồi tốt từ các bạn.

References:

https://gist.github.com/yaraki/1730288

https://en.wikipedia.org/wiki/Dijkstra’s_algorithm

Previous Post

Trong tùy bút Người lái đò Sông Đà, Nguyễn Tuân viết: …Đám tảng đám hòn chia làm ba hàng

Next Post

Trắc nghiệm KHTN 6 Kết nối tri thức Bài 41 (có đáp án): Biểu diễn lực

Tranducdoan

Tranducdoan

Trần Đức Đoàn sinh năm 1999, anh chàng đẹp trai đến từ Thái Bình. Hiện đang theo học và làm việc tại trường cao đẳng FPT Polytechnic

Next Post

Trắc nghiệm KHTN 6 Kết nối tri thức Bài 41 (có đáp án): Biểu diễn lực

đọc sách online cm88 Ca Khia TV trực tiếp XoilacTV 88vv Socolive trực tiếp sumclub https://www.intermedio.io/ tructiepbongda Xoilac Xoilac365 cakhia tv Trực tiếp bóng đá 90phut i9bet.us.com jbo Nhà cái M88 Mansion Xoilac fly88 https://p789bet.biz/ fly88 max79
Tài Liệu Học Tập

Copyright © 2022 Tài Liệu Học Tập.

Chuyên Mục

  • Đề Thi
  • Lớp 12
  • Lớp 11
  • Lớp 10
  • Lớp 9
  • Lớp 8
  • Lớp 7
  • Lớp 6
  • Lớp 5
  • Lớp 4
  • Lớp 3
  • Mẹo Hay
  • Tin tức
  • Liên Hệ

Tham Gia Group Tài Liệu Học Tập

No Result
View All Result
  • Đề Thi
  • Lớp 12
    • Lịch Sử Lớp 12
    • Địa Lí Lớp 12
    • Ngữ Văn Lớp 12
    • GD KTPL Lớp 12
    • Toán Lớp 12
    • Tiếng Anh Lớp 12
    • Hóa Học Lớp 12
    • Sinh Học Lớp 12
    • Vật Lí Lớp 12
  • Lớp 11
    • Toán Lớp 11
    • Ngữ Văn Lớp 11
    • Tiếng Anh Lớp 11
    • Hóa Học Lớp 11
    • Sinh Học Lớp 11
    • Vật Lí Lớp 11
    • Lịch Sử Lớp 11
    • Địa Lí Lớp 11
    • GDCD Lớp 11
  • Lớp 10
    • Toán Lớp 10
    • Ngữ Văn Lớp 10
    • Tiếng Anh Lớp 10
    • Hóa Học Lớp 10
    • Sinh Học Lớp 10
    • Vật Lí Lớp 10
    • Lịch Sử Lớp 10
    • Địa Lí Lớp 10
    • GDKTPL Lớp 10
    • Công nghệ lớp 10
    • Tin Học Lớp 10
  • Lớp 9
    • Toán Lớp 9
    • Ngữ Văn Lớp 9
    • Tiếng Anh Lớp 9
    • Lịch sử và địa lý lớp 9
    • Khoa Học Tự Nhiên Lớp 9
    • GDCD Lớp 9
  • Lớp 8
    • Toán Lớp 8
    • Ngữ Văn Lớp 8
    • Tiếng Anh Lớp 8
    • Lịch sử và địa lý lớp 8
    • Khoa Học Tự Nhiên Lớp 8
    • GDCD 8
  • Lớp 7
    • Toán Lớp 7
    • Văn Lớp 7
    • Tiếng Anh Lớp 7
    • Lịch Sử Và Địa Lí Lớp 7
    • Khoa Học Tự Nhiên Lớp 7
  • Lớp 6
    • Toán Lớp 6
    • Văn Lớp 6
    • Tiếng Anh lớp 6
    • Lịch Sử và Địa Lí Lớp 6
    • Khoa Học Tự Nhiên lớp 6
  • Lớp 5
    • Toán lớp 5
    • Tiếng Việt Lớp 5
    • Tiếng Anh Lớp 5
    • Lịch Sử và Địa Lí Lớp 5
  • Lớp 4
    • Toán lớp 4
    • Tiếng Việt Lớp 4
    • Tiếng Anh Lớp 4
    • Lịch Sử và Địa Lí Lớp 4
  • Lớp 3
    • Toán lớp 3
    • Tiếng Anh Lớp 3
    • Tiếng Việt Lớp 3
  • Mẹo Hay
  • Tin tức
  • Liên Hệ

Copyright © 2022 Tài Liệu Học Tập.