Bao Cao Thuc Tap Co s Thuat Toan Floyd

47
LỜI NÓI ĐẦU Lý thuyết đồ thị là một lĩnh vực nghiên cứu đã có từ lâu đời và có nhiều ứng dụng hiện đại. Những tư tưởng cơ bản của lý thuyết đồ thị đươc đề xuất từ những năm đầu của thế kỷ 18 bởi nhà toán học lỗi lạc người Thụy Sĩ Leonhard Euler. Chính ông là người đã sử dụng đồ thị để giải bài toán nổi tiếng về các cái cầu ở thàng phố Konigsberg. Đồ thị được sử dụng để giải quyết các bài toán trong nhiều lĩnh vực khác nhau. Chẳng hạn, đồ thị có thể sử dụng để xác định các mạch vòng trong vấn đề giải tích mạch điện. Chúng ta có thể phân biệt các hợp chất hoá học hữu cơ khác nhau với cùng công thức phân tử nhưng khác nhau về cấu trúc phân tử nhờ đồ thị. Chúng ta có thể xác định xem hai máy tính trong mạng có thể trao đổi thông tin được với nhau hay không nhờ mô hình đồ thị của mạng máy tính. Đồ thị có trọng số trên các cạnh có thể sử dụng để giải các bài toán như: tìm đường đi ngắn nhất giữa hai thành phố trong cùng một mạng giao thông. Chúng ta còn sử dụng đồ thị để giải các bài toán về lập lịch, thời khoá biểu, và phân bố tần số cho các trạm phát thanh và truyền hình.... Mục đích của đề tài là tìm hiểu là nhằm giới thiệu các khái niệm cơ bản, các bài toán ứng dụng quan trọng của lý thuyết đồ thị như bài toán tìm đường đi ngắn nhất... và những thuật toán để giải quyết chúng đã được trình bày chi tiết cùng với việc phân tích và hướng dẫn cài đặt chương trình trên máy tính. Trong thời gian làm đề tài em được giúp đỡ và trực tiếp chỉ bảo tận tình của cô giáo DƯƠNG THỊ MAI THƯƠNG. Em xin chân thành cảm ơn cô đã giúp đỡ em hoàn thành báo cáo này. Mặc dù đã cố gắng hoàn thiện đề tài với tất cả sự nỗ lực của bản thân, nhưng không thể tránh khỏi những thiếu sót. Kính mong quý Thầy Cô tận tình chỉ bảo. Em xin chân thành cảm ơn! - Trang 1 -

Transcript of Bao Cao Thuc Tap Co s Thuat Toan Floyd

Page 1: Bao Cao Thuc Tap Co s Thuat Toan Floyd

LỜI NÓI ĐẦU

Lý thuyết đồ thị là một lĩnh vực nghiên cứu đã có từ lâu đời và có nhiều ứng dụng hiện đại. Những tư tưởng cơ bản của lý thuyết đồ thị đươc đề xuất từ những năm đầu của thế kỷ 18 bởi nhà toán học lỗi lạc người Thụy Sĩ Leonhard Euler. Chính ông là người đã sử dụng đồ thị để giải bài toán nổi tiếng về các cái cầu ở thàng phố Konigsberg.

Đồ thị được sử dụng để giải quyết các bài toán trong nhiều lĩnh vực khác nhau. Chẳng hạn, đồ thị có thể sử dụng để xác định các mạch vòng trong vấn đề giải tích mạch điện. Chúng ta có thể phân biệt các hợp chất hoá học hữu cơ khác nhau với cùng công thức phân tử nhưng khác nhau về cấu trúc phân tử nhờ đồ thị. Chúng ta có thể xác định xem hai máy tính trong mạng có thể trao đổi thông tin được với nhau hay không nhờ mô hình đồ thị của mạng máy tính. Đồ thị có trọng số trên các cạnh có thể sử dụng để giải các bài toán như: tìm đường đi ngắn nhất giữa hai thành phố trong cùng một mạng giao thông. Chúng ta còn sử dụng đồ thị để giải các bài toán về lập lịch, thời khoá biểu, và phân bố tần số cho các trạm phát thanh và truyền hình....

Mục đích của đề tài là tìm hiểu là nhằm giới thiệu các khái niệm cơ bản, các bài toán ứng dụng quan trọng của lý thuyết đồ thị như bài toán tìm đường đi ngắn nhất... và những thuật toán để giải quyết chúng đã được trình bày chi tiết cùng với việc phân tích và hướng dẫn cài đặt chương trình trên máy tính.

Trong thời gian làm đề tài em được giúp đỡ và trực tiếp chỉ bảo tận tình của cô giáo DƯƠNG THỊ MAI THƯƠNG. Em xin chân thành cảm ơn cô đã giúp đỡ em hoàn thành báo cáo này.

Mặc dù đã cố gắng hoàn thiện đề tài với tất cả sự nỗ lực của bản thân, nhưng không thể tránh khỏi những thiếu sót. Kính mong quý Thầy Cô tận tình chỉ bảo.

Em xin chân thành cảm ơn!

Thái Nguyên, tháng 04 năm 2013 Sinh viên

Nguyễn Khương Duy

- Trang 1 -

Page 2: Bao Cao Thuc Tap Co s Thuat Toan Floyd

MỤC LỤC

CHƯƠNG 1 : LÝ THUYẾT VỀ THUẬT TOÁN TÌM ĐƯỜNG ĐI NGẮN NHẤT

1.1 Các khái niệm cơ bản của lý thuyết đồ thị.....................................................................51.1.1 Giới thiệu.........................................................................................................51.1.2 Định nghĩa đồ thị..............................................................................................61.1.3 Phân loại đồ thị................................................................................................71.1.4 Các thuật ngữ ..................................................................................................81.1.5 Định lý về bậc của đỉnh...................................................................................91.1.6 Đường đi, chu trình, đồ thị liên thông.............................................................10

1.2 Các thuật toán tìm đường đi ngắn nhất....................................................................111.2.1 Thuật toán Ford-Bellman...............................................................................111.2.2 Thuật toán Dijkstra ........................................................................................121.2.3 Đường đi trong đồ thị không có chu trình........................................................131.2.4 Đường đi ngắn nhất giữa tất cả các cặp đỉnh..................................................16

CHƯƠNG 2 : THUẬT TOÁN FLOYD

2.1 Nội dung thuật toán Floyd...........................................................................................182.2 Ứng dụng của thuật toán Floyd-Warshall.................................................................23

CHƯƠNG 3 : CHƯƠNG TRÌNH MÔ TẢ THUẬT TOÁN

3.1 Giao diện chính của chương trình...............................................................................243.2 Các bước thực hiện chương trình.............................................................................243.3 Các chức năng chính của chương trình.......................................................................253.4 Cài đặt – thử nghiệm...................................................................................................26

KẾT LUẬN........................................................................................................................30TÀI LIỆU THAM KHẢO..................................................................................................31

- Trang 2 -

Page 3: Bao Cao Thuc Tap Co s Thuat Toan Floyd

DANH MỤC HÌNH VẼ

Hình 1.1 Cầu ở Konigsberg.................................................................................................5Hình 1.2 Nhà toán học Thụy Sĩ Leonhard Euler.................................................................5Hình 1.3 Đồ thị vô hướng....................................................................................................6Hình 1.4 Đồ thị con.............................................................................................................6Hình 1.5 Các loại đồ thị.......................................................................................................7Hình 1.6 Đơn đồ thị.............................................................................................................7Hình 1.7 Đa đồ thị...............................................................................................................7Hình 1.8 Giả đồ thị..............................................................................................................8Hình 1.9 Ví dụ bậc của đỉnh................................................................................................9Hình 1.10 Bậc vào và bậc ra................................................................................................9Hình 1.11 Đồ thị G và các thành phần liên thông G1, G2, G3..........................................10Hình 1.12 Liên thông mạnh và liên thông yếu..................................................................11Hình 1.13 Khớp và cầu......................................................................................................11Hình 1.14 Thí dụ 1.............................................................................................................12Hình 1.15 Đồ thị không có chu trình.................................................................................14Hình 2.1 Đồ thị ví dụ ........................................................................................................20Hình 3.1 Giao diện chương trình ......................................................................................24Hình 3.2 Công cụ vẽ..........................................................................................................25Hình 3.3 Công cụ chỉnh sửa và hỗ trợ vẽ đồ thị................................................................25Hình 3.4 Truy xuất kết quả................................................................................................25Hình 3.5 Hiển thị kết quả của chương trình......................................................................26Hình 3.6 Bài toán thử nghiệm...........................................................................................27Hình 3.7 Kết quả chạy chương trình.................................................................................28Hình 3.8 Dòng thông báo..................................................................................................29

- Trang 3 -

Page 4: Bao Cao Thuc Tap Co s Thuat Toan Floyd

DANH MỤC BẢNG BIỂU

Bảng 1.1 So sánh các loại đồ thị…………………………….……………………………8Bảng 1.2 Kết quả tính toán theo thuật toán Dijkstra…………………………………….13Bảng 2.1 Kết quả lần lặp đầu tiên………………………………………..………………20Bảng 2.2 Kết quả lần lặp thứ 1……………………………………………..……………21Bảng 2.3 Kết quả lần lặp thứ 2…………………………………………………………..21Bảng 2.4 Kết quả lần lặp thứ 3……………………………………….………………….21Bảng 2.5 Kết quả lần lặp thứ 4………………………………………..…………………22Bảng 2.6 Kết quả lần lặp thứ 5……………………………………..……………………22Bảng 2.7 Kết quả lần lặp thứ 6………………………………………….……………….22Bảng 3.1 Ma trận trọng số…………………………………………….…………………28

- Trang 4 -

Page 5: Bao Cao Thuc Tap Co s Thuat Toan Floyd

Chương I : LÝ THUYẾT VỀ THUẬT TOÁN TÌM ĐƯỜNG ĐI NGẮN NHẤT

I.1 Các khái niệm cơ bản của lý thuyết đồ thị1.1.1 Giới thiệu- Bài toán về các cây cầu ở Konigsberg:Có cách nào để đi dạo qua tất cả bảy cây cầu, mà mỗi cây cầu chỉ đi qua một lần ?

Hình 1.1 Cầu ở Konigsberg- Năm 1736, là năm khai sinh lý thuyết đồ thị, qua việc công bố lời giải bài toán về

các cây cầu ở Konigsberg của nhà toán học Euler.

- Năm 1736, là năm khai sinh lý thuyết đồ

thị, qua việc công bố lời giải bài toán về các cây cầu ở Konigsberg của nhà toán học Euler.

Hình 1.2 Nhà toán học Thụy SĩLeonhard Euler(April 1707 – September 1783)

- Trang 5 -

Page 6: Bao Cao Thuc Tap Co s Thuat Toan Floyd

1.1.2 Định nghĩa đồ thị

Khái niệm đồ thị là một mô hình toán học dùng để giải quyết rất nhiều bài toán và các vấn đề toán học.

Một đồ thị có thể hiểu một cách đơn giản là một hệ thống các đỉnh và các cạnh nối các đỉnh này với nhau.

Ví dụ: Một bản đồ giao thông là một đồ thị với hệ thống đỉnh là các ngã ba, ngã tư. Các đường đi là các cạnh của đồ thị.

Định nghĩa 1: Đồ thị G được xác định bởi (V, E) gồm:- V là tập hợp hữu hạn khác rỗng các phần tử gọi là đỉnh (hay nút) của đồ thị;- E là tập hợp các cặp đỉnh. Mỗi phần tử của E được gọi là một cạnh.

Hình 1.3 Đồ thị vô hướng

Định nghĩa 2: Cho hai đồ thị G = (V,E) và G’ = (V’,E’) - G’ được gọi là đồ thị con của G, ký hiệu G’£ G nếu V’ Í V và E’ Í E- Nếu V’ = V và E’ Í E thì G’ được gọi là đồ thị con khung của G.

Hình 1.4 Đồ thị con

- Trang 6 -

G H

Page 7: Bao Cao Thuc Tap Co s Thuat Toan Floyd

1.1.3 Phân loại đồ thị

Đồ thị G được phân loại theo đặc tính và số lượng của tập các cạnh E:

Hình 1.5 Các loại đồ thị

Đồ thị G được phân loại theo đặc tính và số lượng của tập các cạnh E:- G được gọi là đơn đồ thị nếu giữa hai đỉnh u, v thuộc V chỉ có nhiều nhất là 1 cạnh.

Hình 1.6 đơn đồ thị

- G được gọi là đa đồ thị nếu giữa hai đỉnh u, v thuộc V có nhiều hơn 1 cạnh.

Hình 1.7 Đa đồ thị

- Đa đồ thị G được gọi là giả đồ thị nếu có khuyên. Khuyên là cạnh có hai đầu mút trùng nhau, dạng (u,u).

- Trang 7 -

San Francisco

DenverLos Angeles

New York

ChicagoWashington

Detroit

San Francisco

DenverLos Angeles

New YorkChicagoWashington

Detroit

Page 8: Bao Cao Thuc Tap Co s Thuat Toan Floyd

Hình 1.8 Giả đồ thị

- G là đồ thị vô hướng nếu các cạnh trong E là không định hướng. Tập E gồm các cặp (u,v) không sắp thứ tự (u,v)≡ (v,u)

- G là đồ thị có hướng nếu các cạnh trong E là có định hướng. Trong đồ thị có hướng, hai điểm u và v, có thể được nối bởi hai cung (u,v) và (v,u).

Loại đồ thị Cạnh Có cạnh bội

Có khuyên

Đơn đồ thị vô hướng Vô hướng Không Không

Đa đồ thị vô hướng Vô hướng Có Không

Giả đồ thị vô hướng Vô hướng Có Có

Đồ thị có hướng Có hướng Không Có

Đa đồ thị có hướng Có hướng Có Có

Bảng 1.1 So sánh các loại đồ thị

1.1.4 Các thuật ngữ

Cạnh uv nối u với v, cạnh uv được gọi là cạnh liên thuộc với u,v; đỉnh u được gọi là kề với đỉnh v.

Hai cạnh nối cùng một cặp đỉnh gọi là cạnh song song.Cạnh uv nối u với v, cạnh uv được gọi là cạnh liên thuộc với u,v; đỉnh u được gọi là

kề với đỉnh v. Cho đồ thị vô hướng G = (V,E). Bậc của đỉnh v, ký hiệu deg(v), là số cạnh liên thuộc

với v. Trong đó một khuyên tại một đỉnh được đếm hai lần cho bậc của đỉnh ấy.- Đỉnh có bậc bằng 0 gọi là đỉnh cô lập- Đỉnh có bậc bằng 1 gọi là đỉnh treo

- Trang 8 -

San Francisco

DenverLos Angeles

New YorkChicago

Washington

Detroit

Page 9: Bao Cao Thuc Tap Co s Thuat Toan Floyd

Ví dụ 1:

Hình 1.9 Ví dụ bậc của đỉnh

deg(a)=2; deg(b)=4; deg(f)= 3deg(d)=0; deg(c)=1Đỉnh d là đỉnh cô lậpĐỉnh c là đỉnh treo

Cho đồ thị có hướng G* = (V,E). - bậc ra của đỉnh v, ký hiệu deg+(v), là số cung đi ra khỏi đỉnh, - bậc vào của đỉnh v, ký hiệu deg-(v), là số cung đi vào đỉnh.

Hình 1.10 Bậc vào và bậc ra

1.1.5 Định lý về bậc của đỉnhĐịnh lý: Với G là đồ thị vô hướng, với m cạnh, khi đó tổng số bậc của đỉnh là 2m.

Hệ quả: Trong đồ thị vô hướng, tổng số đỉnh bậc lẻ là một số chẵn.Định lý:

- Trang 9 -

a b

d

c

e

f

a

b cd

ef

Page 10: Bao Cao Thuc Tap Co s Thuat Toan Floyd

Với G là đồ thị vô hướng, với m cạnh, khi đó tổng số bậc của đỉnh là 2m.

Hệ quả: Trong đồ thị vô hướng, tổng số đỉnh bậc lẻ là một số chẵn.

Định lý: Với G* là đồ thị có hướng, với m cung, khi đó chúng ta có công thức:

1.1.6 Đường đi, chu trình, đồ thị liên thông

Định nghĩa:Cho G = (V,E) là đồ thị vô hướng u,vÎV a) Đường đi (dây chuyền) độ dài k nối hai đỉnh u,v là dãy đỉnh và cạnh liên tiếp

nhau v0e1v1e2…vk-1ekvk sao cho: v0=u ,vk= v, ei=vi-1vi , i=1,2,…,k b) Đường đi không có cạnh nào xuất hiện quá một lần gọi là đường đi đơn c) Đường đi không có đỉnh nào xuất hiện quá một lần gọi là đường đi sơ cấp Định nghĩa: Đường đi được gọi là chu trình nếu bắt đầu và kết thúc tại cùng một đỉnh Đường đi đơn có đỉnh bắt đầu và đỉnh kết thúc trùng nhau tạo ra chu trình đơn.Định nghĩa: Đồ thị vô hướng G = (V,E) được gọi là liên thông nếu luôn tìm được đường đi giữa

hai đỉnh bất kỳ của đồ thị. Với đồ thị G không liên thông, G được phân rã thành một số đồ thị con liên thông.

Mỗi đồ thị con này được gọi là thành phần liên thông.

Hình 1.11 Đồ thị G và các thành phần liên thông G1, G2, G3Định nghĩa:Đồ thị có hướng G* = (V,E) tính liên thông được xác định theo hướng của cung. Đồ thị G* là liên thông mạnh nếu luôn tìm được đường đi giữa hai đỉnh bất kỳ của đồ

thị. Đồ thị G* là liên thông yếu nếu chỉ tồn tại đồ thị vô hướng nền của nó là liên thông.

- Trang 10 -

Page 11: Bao Cao Thuc Tap Co s Thuat Toan Floyd

Hình 1.12 Liên thông mạnh và liên thông yếu

Định nghĩa: Cho G = (V,E) là đồ thị vô hướng liên thônga) Đỉnh v được gọi là đỉnh khớp nếu G\v không liên thông (G\v là đồ thị con của G

có được bằng cách xoá v và các cạnh kề với v)b) Cạnh e được gọi là cầu nếu G\e không liên thông( G\e là đồ thị con của G có được

bằng cách xoá cạnh e).

Hình 1.13 Khớp và cầu

1.2 Các thuật toán tìm đường đi ngắn nhất1.2.1 Thuật toán Ford-Bellman

Thuật toán Ford-Bellman có thể phát biểu rất đơn giản: Với đỉnh xuất phát s. Gọi d[v] là khoảng cách từ s tới v với các giá trị khởi tạo là: �+ d[s] := 0 �+ d[v] := +∞ nếu v ≠ s Sau đó ta tối ưu hoá dần các d[v] như sau: Xét mọi cặp đỉnh u, v của đồ thị, nếu có

một cặp đỉnh u, v mà d[v] > d[u]+ c[u, v] thì ta đặt lại d[v] := d[u] + c[u, v]. Tức là nếu độ dài đường đi từ s tới v lại lớn hơn tổng độ dài đường đi từ s tới u cộng với chi phí đi từ u tới v thì ta sẽ huỷ bỏ đường đi từ s tới v đang có và coi đường đi từ s tới v chính là đường đi từ s tới u sau đó đi tiếp từ u tới v. Chú ý rằng ta đặt c[u, v] = +∞ nếu (u, v) không là cung. Thuật toán sẽ kết thúc khi không thể tối ưu thêm bất kỳ một nhãn d[v] nào nữa.

for (∀v ∈ V) do d[v]:= +∞; d[s]:= 0; repeat Stop:= True; for (∀u ∈ V) do for (∀v ∈ V:(u,v) ∈ E) do

- Trang 11 -

Page 12: Bao Cao Thuc Tap Co s Thuat Toan Floyd

if d[v] > d[u] + c[u,v] then begin d[v] := d[u] + c[u,v]; Stop := False; end; until Stop;

Tính đúng của thuật toán: Tại bước khởi tạo thì mỗi d[v] chính là độ dài ngắn nhất của đường đi từ s tới v qua

không quá 0 cạnh. Giả sử khi bắt đầu bước lặp thứ i (i ≥ 1), d[v] đã bằng độ dài đường đi ngắn nhất từ s

tới v qua không quá i - 1 cạnh. Bởi đường đi từ s tới v qua không quá i cạnh sẽ phải thành lập bằng cách: lấy một đường đi từ s tới một đỉnh u nào đó qua không quá i - 1 cạnh, rồi đi tiếp tới v bằng cung (u, v), nên độ dài đường đi ngắn nhất từ s tới v qua không quá i cạnh sẽ được tính bằng giá trị nhỏ nhất trong các giá trị (Nguyên lý tối ưu Bellman):

- Độ dài đường đi ngắn nhất từ s tới v qua không quá i - 1 cạnh- Độ dài đường đi ngắn nhất từ s tới u qua không quá i - 1 cạnh cộng với trọng số

cạnh (u, v) (∀u) Vì vậy, sau bước lặp tối ưu các d[v] bằng công thức:

d[v]bước i = min(d[v]bước i-1, d[u]bước i-1+ c[u, v]) (∀u) thì các d[v] sẽ bằng độ dài đường đi ngắn nhất từ s tới v qua không quá i cạnh. Sau bước lặp tối ưu thứ n - 1, ta có d[v] = độ dài đường đi ngắn nhất từ s tới v qua

không quá n - 1 cạnh. Vì đồ thị không có chu trình âm nên sẽ có một đường đi ngắn nhất từ s tới v là đường đi cơ bản (qua không quá n - 1 cạnh). Tức là d[v] sẽ là độ dài đường đi ngắn nhất từ s tới v.

Vậy thì số bước lặp tối ưu hoá sẽ không quá n - 1 bước. Trong khi cài đặt chương trình, nếu mỗi bước lặp được mô tả dưới dạng: for u := 1 to n do for v := 1 to n do d[v] := min(d[v], d[u] + c[u, v]); Sự tối ưu bắc cầu (dùng d[u] tối ưu d[v] rồi lại có thể dùng d[v] tối ưu d[w] nữa…)

chỉ làm tốc độ tối ưu các nhãn d[.] tăng nhanh hơn nên số bước lặp vẫn sẽ không quá n - 1 bước.

1.2.2 Thuật toán Dijkstra

Trong trường hợp trọng số trên các cung không âm, thuật toán do Dijkstra đề xuất dưới đây hoạt động hiệu quả hơn nhiều so với thuật toán Ford-Bellman. Ta hãy xem trong trường hợp này, thuật toán Ford-Bellman thiếu hiệu quả ở chỗ nào:

Với đỉnh v ∈ V, Gọi d[v] là độ dài đường đi ngắn nhất từ s tới v. Thuật toán Ford-Bellman khởi gán d[s] = 0 và d[v] = +∞ với ∀v ≠ s, sau đó tối ưu hoá dần các nhãn d[v] bằng cách sửanhãn theo công thức: d[v] := min(d[v], d[u] + c[u, v]) với ∀u, v ∈ V. Như vậy nếu như ta dùng đỉnh u sửa nhãn đỉnh v, sau đó nếu ta lại tối ưu được d[u] thêm nữa

- Trang 12 -

Page 13: Bao Cao Thuc Tap Co s Thuat Toan Floyd

thì ta cũng phải sửa lại nhãn d[v] dẫn tới việc d[v] có thể phải chỉnh đi chỉnh lại rất nhiều lần. Vậy nên chăng, tại mỗi bước không phải ta xét mọi cặp đỉnh (u, v) để dùng đỉnh u sửa nhãn đỉnh v mà sẽ chọn đỉnh u là đỉnh mà không thể tối ưu nhãn d[u] thêm được nữa.

Thuật toán Dijkstra (E.Dijkstra - 1959) có thể mô tả như sau: Bước 1: Khởi tạo Với đỉnh v ∈ V, gọi nhãn d[v] là độ dài đường đi ngắn nhất từ s tới v. Ban đầu d[v]

được khởi gán như trong thuật toán Ford-Bellman (d[s] = 0 và d[v] = ∞ với ∀v ≠ s). Nhãn của mỗi đỉnh có hai trạng thái tự do hay cố định, nhãn tự do có nghĩa là có thể còn tối ưu hơn được nữa và nhãn cố định tức là d[v] đã bằng độ dài đường đi ngắn nhất từ s tới v nên không thể tối ưu thêm. Để làm điều này ta có thể sử dụng kỹ thuật đánh dấu: Free[v] = TRUE hay FALSE tuỳ theo d[v] tự do hay cố định. Ban đầu các nhãn đều tự do.

Bước 2: Lặp Bước lặp gồm có hai thao tác:

- Cố định nhãn: Chọn trong các đỉnh có nhãn tự do, lấy ra đỉnh u là đỉnh có d[u] nhỏ nhất, và cố định nhãn đỉnh u.

- Sửa nhãn: Dùng đỉnh u, xét tất cả những đỉnh v và sửa lại các d[v] theo công thức:

d[v]:= min(d[v],d[u]+c[u,v])Bước lặp sẽ kết thúc khi mà đỉnh đích f được cố định nhãn (tìm được đường đi ngắn

nhất từ s tới f); hoặc tại thao tác cố định nhãn, tất cả các đỉnh tự do đều có nhãn là +∞ (không tồn tại đường đi). Có thể đặt câu hỏi, ở thao tác 1, tại sao đỉnh u như vậy được cố định nhãn, giả sử d[u] còn có thể tối ưu thêm được nữa thì tất phải có một đỉnh t mang nhãn tự do sao cho d[u] > d[t] + c[t, u]. Do trọng số c[t, u] không âm nên d[u] > d[t], trái với cách chọn d[u] là nhỏ nhất. Tất nhiên trong lần lặp đầu tiên thì s là đỉnh được cố định nhãn do d[s] = 0.

Bước 3: Kết hợp với việc lưu vết đường đi trên từng bước sửa nhãn, thông báo đường đi ngắn nhất tìm được hoặc cho biết không tồn tại đường đi (d[f] = +∞).

for (∀v ∈ V) do d[v] := +∞; d[s] := 0; repeat u := arg min(d[v]|∀v ∈ V); {Lấy u là đỉnh có nhãn d[u] nhỏ nhất} if (u = f) or (d[u] = +∞) then Break; {Hoặc tìm ra đường đi ngắn

nhất từ s tới f, hoặc kết luận không có đường} for (∀v ∈ V: (u, v) ∈ E) do {Dùng u tối ưu nhãn những đỉnh v kề

với u} d[v] := min (d[v], d[u] + c[u, v]); until False;

1.2.3 Đường đi trong đồ thị không có chu trình.

Bây giờ ta xét trường hợp riêng thứ hai của bài toán tìm đường đi ngắn nhất, mà để giải nó có thể xây dựng thuật toán với độ phức tạp tính toán O(n2), đó là đồ thị không có

- Trang 13 -

Page 14: Bao Cao Thuc Tap Co s Thuat Toan Floyd

chu trình( còn trọng số trên các cung có thể là các số thực tuỳ ý). Trước hết ta chứng minh định lý sau:

Định lý: Giả sử G là đồ thị không có chu trình. Khi đó các đỉnh của nó có thể đánh số sao cho mỗi cung của đồ thị chỉ hướng từ đỉnh có chỉ số nhỏ hơn đến đỉnh có chỉ số lớn hơn , nghĩa là mỗi cung của nó có thể biểu diễn dưới dạng (v[i],v[j]), trong đó i<j .

Thí dụ: Đồ thị trong hình sau có các đỉnh được đánh số thỏa mãn điều kiện nêu trong định lý.

Hình 1.15 Đồ thị không có chu trình

Để chứng minh định lý ta mô tả thuật toán sau, cho phép tìm ra cách đánh số thỏa mãn điều kiện định lý.

Procedure Numbering;/* Đầu vào : Đồ thị có hướng G=(V,E) với n đỉnh không chứa chu trình được cho

bởi danh sách kề Ke(v),v∈ VĐầu ra: Với mỗi đỉnh v∈ V chỉ số NR[u] < NR[v]. */

BeginFor v∈ V do Vao[v]:=0;/* tinh Vao[v]=deg-(v) */For u∈ V doFor v∈Ke(u) do Vao[v]:=Vao[v] + 1;

QUEUE:=∅;For v∈ V doIf Vao[v]=0 then QUEUE ⇐ v ;Num :=0;

While QUEUE ¿∅ do Begin u⇐ QUEUE;Num :=num +1; NR[u] :=num;For v∈Ke(u) doBegin

- Trang 14 -

Page 15: Bao Cao Thuc Tap Co s Thuat Toan Floyd

Vao[v]:=Vao[v] - 1;If Vao[v]=0 then QUEUE ⇐ v ;

End; End;End;

Thuật toán được xây dựng dựa trên ý tưởng rất đơn giản sau: Rõ rang trong đồ thị không có chu trình bao giờ cũng tìm được đỉnh có bán bậc vào

bằng 0 ( không có cung đi vào ). Thực vậy, bắt đầu từ đỉnh v1 nếu có cung đi vào nó từ v2 thì ta lại chuyển sang xét đỉnh v2. Nếu có cung v3 đi vào v2, thì ta chuyển sang xét v3... Do đồ thị là không có chu trình nên sau một số hữu hạn lần chuyển như vậy ta phải đi đến đỉnh không có cung đi vào. Thoạt tiên, tìm các đỉnh như vậy của đồ thị. Rõ ràng ta có thể đáng số chúng theo một thứ tự tuỳ ý bắt đầu từ 1. Tiếp theo, loại bỏ khỏi đồ thị những đỉnh đã được đánh số cùng các cung đi ra khỏi chúng, ta thu được đồ thị mới cũng không có chu trình, và thủ tục được lặp lại với đồ thị mới này. Quá trình đó sẽ được tiếp tục cho đến khi tất cả các đinỉh của đồ thị được đánh số.

Do có thuật toán đánh số trên, nên khi xét đồ thị không có chu trình ta có thể giả thiết là các đỉnh của nó được đánh số sao cho mỗi cung chỉ đi từ đỉnh có chỉ số nhỏ đến đỉnh có chỉ số lớn hơn. Thuật toán tìm đường đi ngắn nhất trên đồ thị không có chu trình được mô tả trong sơ đồ sau đây :

Procedure Critical_Path;/* Tìm đường đi ngắn nhất từ đỉnh nguồn đến tất cả các đỉnh còn lại trên đồ thị không

có chu trình Đầu vào: Đồ thị G=(V,E) trong đó V= { v[1], v[2], ..., v[n] }

Đối với mỗi cung (v[i],v[j])∈E ta có i<j.Đồ thị được cho bởi danh sách kề Ke(v),v∈V.

Đầu ra: Khoảng cách từ v[1] đến tất cả các đỉnh còn lại được ghi trong mảng d[v[i] ], i=1,2,...,n */

Begin d[v[1]]:=0;

for j:=2 to n do d[v[j]]:=a[v[1]],v[j]];fo j:=2 to n do

for v∈Ke [v[j]] dod [v]:=min (d[v], d[v[j]] + a[v[j]], v );

end;Độ phức tạp của thuật toán là O(m)., do mỗi cung của đồ thị phải xét qua đúng một

lần.Các thuật toán mô tả ở trên thường được ứng dụng vào việc xây dựng những phương

pháp giải bài toán điều khiển việc thực hiện những dự án lớn, gọi tắt là PERT (Project Evaluation and Review Technique ) hay CMD ( Critical path method).

- Trang 15 -

Page 16: Bao Cao Thuc Tap Co s Thuat Toan Floyd

1.2.3 Đường đi ngắn nhất giữa tất cả các cặp đỉnh

Rõ ràng ta có thể giải bài toán tìm đường đi ngắn nhất giữa tất cả các cặp đỉnh của đồ thị bằng cách sử dụng n lần thuật toán mô tả ở mục trước, trong đó ta sẽ chọn s lần lượt là các đỉnh của đồ thị. Rõ ràng, khi đó ta thu được thuật toán với độ phức tạp là O(n 4) (nếu dùng tt Ford-Bellman) hoặc O(n3) đối với trường hợp trọng số không âm hoặc đồ thị không có chu trình. Trong trường hợp tổng quát, sử dụng thuật toán Ford-Bellman n lần không phải là cách làm tốt nhất. Ở đây ta sẽ mô tả thuật toán với độ phức tạp tính toán O(n3) : thuật toán Floyd được mô tả như sau:

Procedure Floyd;/* Tìm đường đi ngắn nhất giữa tất cả các cặp đỉnh

Đầu vào : Đồ thị cho bởi ma trận trọng số a[i,j], i,j=1,2,...,nĐầu ra : Ma trận đường đi ngắn nhất giữa các cặp đỉnh

d[i,j] i,j =1,2,...,ntrong đó d[i,j] cho độ dài đường di ngắn nhất từ i đến j.Ma trận ghi nhận đường đi

p[i,j], i, j=1,2,...,n.trong đó p[i,j] ghi nhận đỉnh đi trước j trong đường đi ngắn nhất từ i đến j.*/Begin

/* Khởi tạo */For i:=1 to n do

For j:=1 to n doBegin

d[i,j]:=a[i,j];p[i,j]:=i;

end;/* Bước lặp */

For k:=1 to n do For i:=1 to n do

For j:=1 to n doIf d[i,j]>d[i,k] + d[k,j] thenBegin

d[i,j]:= d[i,k] + d[k,j];p [i,j]:= p [k,j];

end;end;Rõ ràng độ phức tạp của thuật toán là O(n3).Khác biệt rõ ràng của thuật toán Floyd là khi cần tìm đường đi ngắn nhất giữa một

cặp đỉnh khác, chương trình chỉ việc in kết quả chứ không phải thực hiện lại thuật toán Floyd nữa.

- Trang 16 -

Page 17: Bao Cao Thuc Tap Co s Thuat Toan Floyd

NHẬN XÉT:

Bài toán đường đi dài nhất trên đồ thị trong một số trường hợp có thể giải quyết bằng cách đổi dấu trọng số tất cả các cung rồi tìm đường đi ngắn nhất, nhưng hãy cẩn thận, có thể xảy ra trường hợp có chu trình âm.

Trong tất cả các cài đặt trên, vì sử dụng ma trận trọng số chứ không sử dụng danh sách cạnh hay danh sách kề có trọng số, nên ta đều đưa về đồ thị đầy đủ và đem trọng số +∞ gán cho những cạnh không có trong đồ thị ban đầu. Trên máy tính thì không có khái niệm trừu tượng +∞ nên ta sẽ phải chọn một số dương đủ lớn để thay. Như thế nào là đủ lớn? số đó phải đủ lớn hơn tất cả trọng số của các đường đi cơ bản để cho dù đường đi thật có tồi tệ đến đâu vẫn tốt hơn đường đi trực tiếp theo cạnh tưởng tượng ra đó.

Xét về độ phức tạp tính toán, nếu cài đặt như trên, thuật toán Ford-Bellman có độ phức tạp là O(n3), thuật toán Dijkstra là O(n2), thuật toán Floyd là O(n3).

Khác với một bài toán đại số hay hình học có nhiều cách giải thì chỉ cần nắm vững một cách cũng có thể coi là đạt yêu cầu, những thuật toán tìm đường đi ngắn nhất bộc lộ rất rõ ưu, nhược điểm trong từng trường hợp cụ thể (Ví dụ như số đỉnh của đồ thị quá lớn làm cho không thể biểu diễn bằng ma trận trọng số thì thuật toán Floyd sẽ gặp khó khăn, hay thuật toán Ford-Bellman làm việc khá chậm). Vì vậy yêu cầu trước tiên là phải hiểu bản chất và thành thạo trong việc cài đặt tất cả các thuật toán trên để có thể sử dụng chúng một cách uyển chuyển trong từng trường hợp cụ thể. Những bài tập sau đây cho ta thấy rõ điều đó.

- Trang 17 -

Page 18: Bao Cao Thuc Tap Co s Thuat Toan Floyd

Chương II : THUẬT TOÁN FLOYD

2.1 Nội dung thuật toán Floyd:

Floyd là giải thuật tìm độ dài đường đi ngắn nhất giữa mọi cặp đỉnh trong đồ thị có hướng liên thông có trọng số.

+ Đầu vào: Đồ thị liên thông G = (V,E), V= {1, 2, ... , n}, có trọng số w(i,j) >0 với mọi cung (i,j).

+ Đầu ra: Ma trận D=[d(i,j)], trong đó d(i,j) là chiều dài đường đi ngắn nhất từ i đến j với mọi cặp (i,j).

Khái niệm trung tâm của F-W Algo. Là các đỉnh trung gian.

Định nghĩa: Ký hiệu p=(x1, x2,…, xk) là đường đi từ x1 đến xk thì mọi đỉnh x2,…,xk gọi là các đỉnh trung gian trên đường đi p từ x1 đến xk.

Ý tưởng chính của F-W Algo. là: Cho V={1, 2,…, n} là tập đỉnh của đồ thị và tập đỉnh U={1, 2,…, k}. Xét cặp đỉnh i,j và mọi đường đi có thể từ i đến j với các đỉnh trung gian chỉ là các đỉnh thuộc tập U. Gọi p là đường đi ngắn nhất từ i đến j với các đỉnh trung gian thuộc U. Khi đó ta có hai tình huống sau:

a. Nếu k không là đỉnh trung gian trên đường đi từ i đến j thì đường đi ngắn nhất từ i đến j có các đỉnh trung gian là {1, 2,…, k-1} cũng là đường đi ngắn nhất từ i đến j với các đỉnh trung gian là {1, 2,…, k}

b. Nếu k là một đỉnh trung gian trên đường đi từ i đến j thì ta tách đường đi p thành hai đoạn con là p1 đi từ i đến k và p2 đi từ k đến j. Các đoạn đường con p1, p2 là các đường đi ngắn nhất với các đỉnh trung gian là các đỉnh {1, 2,…, k-1}. Từ đó suy ra cách xác định độ dài của đường đi từ i đến j nhờ hệ thức sau:

Trong đó dij là độ dài đường đi ngắn nhất từ i đến j; wij là trọng số trên đường đi ij.

Từ hệ thức trên ta thấy: để xác định độ dài đường đi ngắn nhất wij{1..k} từ i đến j qua các đỉnh tập {1, 2,…, k} ta chỉ cần dựa vào dij{1..k-1} (đường đi ngắn nhất từ i đến j qua tập đỉnh 1… k-1).Î

- Trang 18 -

Page 19: Bao Cao Thuc Tap Co s Thuat Toan Floyd

Sau đây là các bước của thuật toán Floyd:

Bước 1: Khởi tạo: Ký hiệu D0 là ma trận xuất phát D0 = [d0(i,j)] trong đó: d0(i,j) = w(i,j) nếu tồn tại cung (i,j)

d0 (i,j) = +¥ nếu không tồn tại cung (i,j) (đặc biệt nếu không có khuyên tại i thì d0 (i,i) = +¥).Gán k:=0 Bước 2: Kiểm tra kết thúc: Nếu k = n, kết thúc. D = Dn là ma trận độ dài đường đi ngắn nhất. Ngược lại: k:=k+1® sang bước 3.Bước 3: Tính ma trận Dk theo Dk-1 Với mọi cặp (i,j), i=1..n, j=1..n thực hiện:Nếu dk-1(i,j) > dk-1(i,k) + dk-1(k,j) thì đặt dk (i,j) := dk-1(i,k) + dk-1(k,j) ngược lại đặt dk(i,j) := dk-1 (i,j)Quay lại bước 2.

Độ phức tạp của thuật toán Floyd là: O(n3).Định lý : Thuật toán Floyd là đúng.Hệ quả :(i) Nếu ma trận kết quả của thuật toán Floyd có phần tử hữu hạn trên đường chéo

chính thì đồ thị chứa chu trình.(ii) Nếu ma trận kết quả chứa phần tử +¥ ngoài đường chéo chính thì đồ thị không

liên thông mạnh.

- Trang 19 -

Page 20: Bao Cao Thuc Tap Co s Thuat Toan Floyd

VÍ DỤ:Xét đồ thị sau :

Hình 2.1

Áp dụng thuật toán Floyd:Ma trận khoảng cách xuất phát D0 là (các ô trống là ¥):

Bảng 2.1

- Trang 20 -

Page 21: Bao Cao Thuc Tap Co s Thuat Toan Floyd

Bảng 2.2

Bảng 2.3

Bảng 2.4

- Trang 21 -

Page 22: Bao Cao Thuc Tap Co s Thuat Toan Floyd

Bảng 2.5

Bảng 2.6

Cuối cùng, D là ma trận khoảng cách ngắn nhất giữa các đỉnh. Theo hệ quả ta thấy đồ thị liên thông mạnh và chứa chu trình:

Bảng 2.7

- Trang 22 -

Page 23: Bao Cao Thuc Tap Co s Thuat Toan Floyd

2.2 Ứng dụng của thuật toán Floyd-Warshall

Trong các ứng dụng thực tế, bài toán tìm đường đi ngắn nhất giữa hai đỉnh của một đồ thị liên thông có một ý nghĩa to lớn.

Ví dụ, bài toán chọn một hành trình tiết kiệm nhất (theo tiêu chuẩn hoặc khoảng cách hoặc thời gian hoặc chi phí) trên một mạng giao thông đường bộ, đường thủy hoặc đường không; bài toán chọn một phương pháp tiết kiệm nhất để đưa ra một hệ thống động lực từ trạng thái xuất phát đến trạng một trạng thái đích, bài toán lập lịch thi công các công các công đoạn trong một công trình thi công lớn, bài toán lựa chọn đường truyền tin với chi phí nhỏ nhất trong mạng thông tin, v.v… 

Các thuật toán Floyd-Warshall có thể được sử dụng để giải quyết các vấn đề sau đây:- Tìm đường đi ngắn nhất giữa mọi cặp đỉnh trong đồ thị có hướng.- Bài toán tìm bao đóng chuyển tiếp.- Tìm một biểu thức chính quy biểu thị các ngôn ngữ thông thường được chấp nhận

bởi một automaton hữu hạn.- Nghịch đảo của các ma trận thực.- Tối ưu định tuyến (Tìm kiếm các con đường với lưu lượng tối đa giữa hai đỉnh).- Kiểm tra đồ thị hai phía.- Tối đa băng thông...

- Trang 23 -

Page 24: Bao Cao Thuc Tap Co s Thuat Toan Floyd

Chương III : CHƯƠNG TRÌNH MÔ TẢ THUẬT TOÁN

3.1 Giao diện chính của chương trình

Hình 3.1 Giao diện chương trình

Chương trình được thiết kế nhằm mục đích thực hiện công việc mô tả thuật toán tìm đường đi ngắn nhất giữa mọi cặp đỉnh Floyd, nó được viết bằng công cụ lập trình Visual studio C# và gồm có một số chức năng chính sau: Nhập thông tin vào cho đồ thị cần xét bằng cách sử dụng công cụ thiết kế, các tùy chọn nút để chỉnh sửa đỉnh của đồ thị, và một số chức năng khác như: chọn điểm bắt đầu và điểm kết thúc, xóa cạnh mới nhất, xóa tất cả cạnh và xóa cả đồ thị.

3.2 Các bước thực hiện chương trình

Bước 1: Ban đầu ta cần nhập thông tin vào cho chương trình bằng cách sử dụng công cụ vẽ nằm phía dưới của chương trình để vẽ đồ thị, các thông tin về trọng số của 2 đỉnh sẽ không được nhập trực tiếp mà ta sẽ thực hiện bằng cách di chuyển các đỉnh ra xa nhau, chương trình sẽ tự động tăng trọng số nếu ta kéo 2 đỉnh ra xa (và ngược lại).

Bước 2: Sử dụng một số chức năng của chương trình để sửa, xóa, đổi mầu đỉnh đồ thị muốn xét.

- Trang 24 -

Page 25: Bao Cao Thuc Tap Co s Thuat Toan Floyd

Ngay khi đưa dữ liệu vào thì chương trình tự động tính toán và đưa ra kết quả là ma trận có trọng số là đường đi ngắn nhất giữa các đỉnh và hiện trên chương trình cho ta thấy.

Bước 3: Chọn đỉnh ban đầu và đỉnh kết thúc để chương trình đưa ra kết quả là đường đi ngắn nhất giữa 2 đỉnh đó. Đường đi sẽ được hiện màu xanh đoạn gạch đứt và có 1 chấm màu xanh đậm di chuyển từ điểm đầu đến điểm cuối.

3.3 Các chức năng chính của chương trình

Công cụ vẽ đồ thị:+ Di chuyển: Dùng để di chuyển

các đỉnh của đồ thị để chỉnh trọng số của các đỉnh.

Hình 3.2 Công cụ vẽ+ Vẽ đỉnh: Tạo các đỉnh cho đồ thị, chương trình sẽ tự động tạo đỉnh với tên theo thứ

thự alphabet. Do vậy ta không cần phải đặt tên cho từng đỉnh. + Vẽ cạnh: Tạo các cạnh cho đồ thị.+ Xóa: Xóa 1 đỉnh nào đó nếu ta nháy chuột vào.

Công cụ chỉnh sửa và hỗ trợ vẽ đồ thị:+ Xóa cạnh mới nhất: Xóa cạnh vừa mới tạo. + Xóa cạnh: Xóa toàn bộ cạnh của đồ thị.+ Xóa tất cả: Xóa toàn bộ đồ thị.+ Đồ thị vô hướng: Khi ta tích vào thì đồ thị chuyển thành đồ

thị vô hướng. Các cạnh của đồ thị hiện bên cạnh sẽ không còn mũi tên chỉ chiều nữa.

+ Xóa đỉnh: Xóa đỉnh hiện tại đang được chọn. + Đổi màu: Đổi màu cho đỉnh đang được chọn. Đổi màu để

đánh dấu các đỉnh, tùy vào mục đích của người dùng chương trình.

Hình 3.3

Truy xuất kết quả:+ Từ: Đỉnh ban đầu.+ Đến: Đỉnh kết thúc.+ Bắt đầu: Chương trình sẽ thực hiện tìm đường đi ngắn nhất

giữa đỉnh ban đầu và đỉnh kết thúc, sau đó đưa ra kết quả.

Hình 3.4

- Trang 25 -

Page 26: Bao Cao Thuc Tap Co s Thuat Toan Floyd

Sau khi chạy thì ta được kết quả hiện đường đi ngắn nhất giữa cặp đỉnh đã chọn :

Hình 3.5

3.4 Cài đặt – thử nghiệm

Chương trình được cài đặt bằng Visual studio C#. Ta sử dụng ma trận kề với giá trị data[i,j] = -1 để biểu diễn không có đường đi giữa hai đỉnh i và j. Sau đó tạo thêm một mảng 2 chiều FloydData để lưu kết quả sau quá trình thực hiện thuật toán Floyd.

public void Floyd(){    if (Data == null)        return;    int n = Data.GetLength(0);     FloydData = new MatrixCell[n, n];     for (int i = 0; i < n; i++)        for (int j = 0; j < n; j++)            FloydData[i, j] = new FloydCell(Data[i, j]);     for (int i = 0; i < n; i++)    {        for (int j = 0; j < n; j++)        {            if (FloydData[j, i].Value > 0)            {                for (int k = 0; k < n; k++)

- Trang 26 -

Page 27: Bao Cao Thuc Tap Co s Thuat Toan Floyd

                {                    if (FloydData[i, k].Value > 0){                        if (FloydData[j, k].Value < 0 || FloydData[j,

i].Value+ FloydData[i, k].Value < FloydData[j, k].Value)

                        { FloydData[j, k].Value = FloydData[j, i].Value + FloydData[i, k].Value;

                             FloydData[j, k].Previous = i;                        }                    }                }            }        }    }}

FloydCell là một cấu trúc được định nghĩa để lưu trữ giá trị trọng số của cạnh và đỉnh trung gian:

struct FloydCell{    public int Previous;    public int Value;     public FloydCell(int value)        : this(-1, value)    { }    public FloydCell(int previous, int value)    {        this.Previous = previous;        this.Value = value;    }}

Lý do ta cần phải lưu lại đỉnh trung gian là để lấy được đường đi qua các đỉnh từ đỉnh bắt đầu đến kết thúc.

Lấy đường đi ngắn nhất giữa hai đỉnh:List<Point> _path = new List<Point>();// […]void GetPath(int x,int y){    if(_matrix.FloydData[x,y].Value== -1)        return;    int i=_matrix.FloydData[x,y].Previous;    if(i== -1)    {

- Trang 27 -

Page 28: Bao Cao Thuc Tap Co s Thuat Toan Floyd

        _path.Add(new Point(x+1,y+1));        return;    }    else    {        GetPath(x,i);        _path.Add(new Point(_preNodeIndex+1,i+1));        _preNodeIndex=i;        GetPath(i,y);    }}

Phương thức GetPath() trên sẽ tạo ra đường đi giữa hai đỉnh x, y và lưu vào trong danh sách _path. Giá trị của FloydData[x,y].Previous sẽ trả về đỉnh trung gian giữa hai đỉnh x,y và nếu giá trị này bằng -1 tức là có một cạnh nối trực tiếp giữa hai đỉnh này. Ngược lại ta chia đường đi thành hai phần và thực hiện đệ quy để lấy đường đi của từng phần này.

Chạy thử nghiệm:Chạy thử nghiệm chương trình với bài toán như sau:

Hình 3.6 Bài toán thử nghiệmVới bài toán này, ta có ma trận trọng số như sau:

Bảng 3.1 Ma trận trọng số

- Trang 28 -

Page 29: Bao Cao Thuc Tap Co s Thuat Toan Floyd

- Tìm đường đi ngắn nhất từ đỉnh A đến đỉnh F:Kết quả chạy chương trình:

Hình 3.7 Kết quả chạy chương trình

Ta thấy kết quả là: A -> C -> D -> B -> FMa trận trọng số được tính lại và hiện lên như hình trên.

- Nếu ta thực hiện tìm đường đi ngắn nhất từ một đỉnh đến một đỉnh khác mà không có đường đi nào đến đỉnh đó thì chương trình sẽ hiển thị lên thông báo. VD: Đỉnh ban đầu là F, đỉnh đến là C thì chương trình sẽ đưa ra dòng thông báo:

Hình 3.8 Dòng thông báo

- Trang 29 -

Page 30: Bao Cao Thuc Tap Co s Thuat Toan Floyd

KẾT LUẬN

Qua đề tài đã thực hiện trong thời gian qua, em đã nắm bắt được cơ bản kiến thức về lý thuyết đồ thị, các thuật toán để giải quyết các vấn đề về tìm đường đi ngắn nhất. Nghiêm cứu về nguyên lý và cách mà thuật toán thực hiện, em hiểu thêm về tầm quan trọng của lý thuyết đồ thị đến việc áp dụng giải quyết các vấn đề thực tiễn.

Do hạn chế về thời gian nên kiến thức mà em tìm hiểu được còn thiết sót, cần được bổ sung và em mới tìm hiểu về đồ họa trong ngôn ngữ C# nên chưa thể thành thạo, chưa có kiến thức chuyên sâu được. Em rất mong nhận được sự góp ý, hướng dẫn của Thầy Cô để em có kiến thức hoàn thiện hơn.

Một lần nữa em xin chân thành cảm ơn cô DƯƠNG THỊ MAI THƯƠNG đã tận tình chỉ bảo em để em hoàn thành đề tài này.

Em xin chân thành cảm ơn!

Thái Nguyên, tháng 04, năm 2013Sinh viên thực hiện

Nguyễn Khương Duy

- Trang 30 -

Page 31: Bao Cao Thuc Tap Co s Thuat Toan Floyd

TÀI LIỆU THAM KHẢO

1. Toán rời rạc, tác giả: Nguyễn Đức Nghĩa, Nguyễn Tô Thành, NXB Giáo Dục2. Toán ứng dụng, Trường cao đẳng nghề CNTT iSPACE3. http://www. yinyangit.wordpress.com/ 2013/03/21/y2–visual-graph–minh-họa-việc-biểu-diễn-dồ-thị-bằng-gdi/

- Trang 31 -

Page 32: Bao Cao Thuc Tap Co s Thuat Toan Floyd

NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN

…………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………..…………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………..……………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………..…………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………..…………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………..…………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………..

Xác nhận của giáo viên hướng dẫn

- Trang 32 -