Bạn có thể thử tạo một phiên bản Floyd-Warshall nhanh hơn trên các ma trận thưa thớt.
Đầu tiên, chúng ta hãy nhớ lại những gì thuật toán này làm:
Gọi là ma trận khoảng cách. Khi bắt đầu thuật toán M i , j là trọng số của cạnh i → j . Nếu cạnh này không tồn tại sau đó M i , j = ∞ .MMi,ji→jMi,j=∞
Thuật toán có bước. Trong bước k của thuật toán, với mỗi cặp nút i , j chúng ta đặtVki,j
Mi,j←min{Mi,j,Mi,k+Mk,j}.
Rõ ràng nếu hoặc M k , j = ∞ thì không cần cập nhật. Do đó, trong các bước đầu tiên của thuật toán, chúng ta chỉ cần thực hiện khoảng d e g i n ( k ) ⋅ d e g o u t ( k ) so sánh trong đó d e g i n ( k ) và d e g o u t (Mi,k=∞Mk,j=∞degin(k)⋅degout(k)degin(k) biểu thị số lượng các cạnh đến và đi củanút thứ k tương ứng. Khi thuật toán tiến triển, ngày càng có nhiều mục nhập của ma trận M được điền vào. Do đó, các bước cuối cùng có thể mất nhiều thời gian hơn.degout(k)kM
Lưu ý rằng chúng ta cần một cách hiệu quả để chỉ lặp lại trên các ô không vô hạn trong hàng thứ và cột của ma trận. Điều này có thể được thực hiện bằng cách giữ một tập hợp các cạnh đến và đi cho mỗi nút.k
Dường như các bước đầu tiên của thuật toán có thể được hưởng lợi rất nhiều từ sự thưa thớt. Ví dụ, một biểu đồ được xây dựng ngẫu nhiên với cho thấy rằng lần lặp đầu tiên ( k = 0 ) chỉ là các bước O ( 1 ) . Nếu đồ thị được chia thành nhiều thành phần được kết nối thì ma trận M sẽ vẫn tương đối thưa thớt trong suốt thuật toán và tổng thời gian chạy có thể thấp bằng O ( V ) . Mặt khác, nếu đồ thị chỉ chứa một thành phần được kết nối, thì lần lặp cuối k = | V |E= =O(V)k = 0Ô ( 1 )MÔ ( V)k = | V|dự kiến sẽ thực hiện các bước . Trong trường hợp này, tổng thời gian chạy có thể là O ( V 3 ) . Lớn như phiên bản không thưa thớt.Ô ( V2)O(V3)