Thuậttoán Floyd – Warshall và bài toán tìm đƣờng đi ngắn nhất giữa mọ

Một phần của tài liệu Nghiên cứu về xử lý song song trong GIS và xây dựng ứng dụng song song hóa thuật toán định dòng chảy trên bề mặt (Trang 49 - 52)

cặp đỉnh trên đồ thị

Thuật toán Floyd – Warshall hay còn gọi là Floyd, Roy – Floyd là thuật toán tìm đƣờng đi ngắn nhất giữa mọi cặp đỉnh trên đồ thị sau một lần chạy thuật toán. Một tính chất nữa là Floyd – Warshall có thể chạy trên đồ thị có các cạnh có trọng số có thể âm. Tuy nhiên lƣu ý là đồ thị không đƣợc có vòng (cycle) nào có tổng các cạnh là âm, nếu có vòng nhƣ vậy ta không thể tìm đƣờng đi ngắn nhất (mỗi lần đi qua vòng này, độ dài quãng đƣờng lại giảm, nên ta có thể đi vô hạn lần).

Thuật toán Floyd – Warshall so sánh tất cả các đƣờng đi có thể giữa từng cặp đỉnh. Nó là một dạng của quy hoạch động (Dynamic Programming). Nếu đặt hàm adj(i, j, k) là đƣờng đi ngắn nhất từ i đến j, chỉ dùng đến các đỉnh trong tập {1, 2, 3, ..., k}. Giả sử muốn tính adj(i, j, k + 1). Với mỗi cặp đỉnh i và j, đƣờng đi ngắn nhất có thể là: (1) đƣờng đi chỉ sử dụng các đỉnh trong tập {1,..., k} hoặc (2) đƣờng đi từ i đến k + 1 rồi từ k + 1 đến j, cũng chỉ sử dụng các đỉnh trong tập {1, ...., k}. Do vậy:

Trƣờng hợp cơ bản: adj(i, j, 0) = w(i, j);

Đệ quy: adj(i,j,k+1) = min{adj(i,j,k), adj(i,k+1, k) + adj(k+1, j, k)}

for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) {

adj[i][j] = min(adj[i][j], adj[i][k] + adj[k][j]); }

} }

Độ phức tạp của thuật toán Floyd là O(n3).

Đầu vào của thuật toán là đồ thị liên thông G = (V, E), V = {1, 2, 3, .... ,n}, có trọng số w(i, j) > 0 với mọi cung (i, j). Đầu ra của thuật toán là ma trận D = [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).

Dựa vào thuật toán trên, tôi áp dụng vào thuật toán tìm dòng tích lũy cho bài toán của mình. Phƣơng pháp của tôi nhƣ sau:

Phƣơng pháp:

Bƣớc 1: Khởi tạo ma trận xuất phát (D0): D0 = [D0(i, j)] Trong đó:

- d0 (i, j) = w(i, j) nếu tồn tại cung (i, j). Cụ thể nếu tồn tại hƣớng (p, q) bằng 1 trong 8 hƣớng có thể chảy là hƣớng số 1, 2, 4, 8 , 16, 32, 64, 128 thì trƣờng hợp này hƣớng (p, q) ta gán bằng 1.

- d0 (i, j) = +∞ nếu không tồn tại cung (i, j). Ngƣợc lại với trƣờng hợp trên thì hƣớng (q, p) ta gán bằng +∞.

Đặc biệt nếu không có khuyên tại i thì d0(i, i) cũng bằng +∞. Gán k = 0;

Bƣớc 2: Kiểm tra kết thúc: Nếu k = n thì kết thúc. D = Dn là ma trận chứa vị trí tích lũy. Ta chỉ cần chia vị trí lấy tọa độ: (i / số cột) là tọa độ dòng và chia lấy dƣ (i % số

cột) để lấy tọa độ cột. sau đó ta chỉ cần đếm lại số ô để lấy kết quả tích lũy. 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).

PHẦN 3. DỮ LIỆU, NỘI DUNG VÀ PHƢƠNG PHÁP NGHIÊN CỨU

Một phần của tài liệu Nghiên cứu về xử lý song song trong GIS và xây dựng ứng dụng song song hóa thuật toán định dòng chảy trên bề mặt (Trang 49 - 52)