Cả hai đều có thể được triển khai bằng cách sử dụng chính xác cùng một thuật toán chung như sau:
Inputs:
G: Graph
s: Starting vertex (any for Prim, source for Dijkstra)
f: a function that takes vertices u and v, returns a number
Generic(G, s, f)
Q = Enqueue all V with key = infinity, parent = null
s.key = 0
While Q is not empty
u = dequeue Q
For each v in adj(u)
if v is in Q and v.key > f(u,v)
v.key = f(u,v)
v.parent = u
Đối với Prim, vượt qua f = w(u, v)
và đối với Dijkstra vượt qua f = u.key + w(u, v)
.
Một điều thú vị khác là ở trên Generic cũng có thể triển khai Tìm kiếm đầu tiên theo chiều rộng (BFS) mặc dù nó sẽ quá mức cần thiết vì hàng đợi ưu tiên đắt tiền không thực sự bắt buộc. Để chuyển thuật toán Chung ở trên sang BFS, hãy chuyển f = u.key + 1
nó giống như việc thực thi tất cả các trọng số thành 1 (tức là BFS cung cấp số cạnh tối thiểu cần thiết để đi ngang từ điểm A đến B).
Trực giác
Đây là một cách hay để suy nghĩ về thuật toán chung ở trên: Chúng ta bắt đầu với hai nhóm A và B. Ban đầu, hãy đặt tất cả các đỉnh của bạn vào B để nhóm A trống. Sau đó, chúng ta di chuyển một đỉnh từ B sang A. Bây giờ hãy xem tất cả các cạnh từ đỉnh ở A đi qua đỉnh ở B. Chúng ta đã chọn một cạnh bằng cách sử dụng một số tiêu chí từ các cạnh chéo này và di chuyển đỉnh tương ứng từ B sang A. Lặp lại quá trình này cho đến khi B trống.
Một cách brute force để thực hiện ý tưởng này là duy trì một hàng đợi ưu tiên của các cạnh cho các đỉnh trong A giao với B. Rõ ràng là sẽ rất rắc rối nếu đồ thị không thưa thớt. Vì vậy, câu hỏi sẽ là chúng ta có thể duy trì hàng đợi ưu tiên của các đỉnh không? Trên thực tế, điều này chúng ta có thể quyết định cuối cùng là chọn đỉnh nào từ B.
Bối cảnh lịch sử
Thật thú vị là phiên bản chung của kỹ thuật đằng sau cả hai thuật toán về mặt khái niệm đã cũ từ năm 1930 ngay cả khi chưa có máy tính điện tử.
Câu chuyện bắt đầu với Otakar Borůvka, người cần một thuật toán cho một người bạn của gia đình đang cố gắng tìm ra cách kết nối các thành phố ở đất nước Moravia (nay là một phần của Cộng hòa Séc) với những đường dây điện chi phí tối thiểu. Ông đã công bố thuật toán của mình vào năm 1926 trên một tạp chí liên quan đến toán học, vì Khoa học Máy tính chưa tồn tại khi đó. Điều này thu hút sự chú ý của Vojtěch Jarník, người đã nghĩ ra một cải tiến cho thuật toán của Borůvka và xuất bản nó vào năm 1930. Thực tế, ông đã phát hiện ra cùng một thuật toán mà ngày nay chúng ta biết là thuật toán của Prim, người đã phát hiện lại nó vào năm 1957.
Không phụ thuộc vào tất cả những thứ này, vào năm 1956, Dijkstra cần viết một chương trình để chứng minh khả năng của một máy tính mới mà viện của ông đã phát triển. Anh nghĩ sẽ rất tuyệt nếu có máy tính tìm kết nối để đi lại giữa hai thành phố của Hà Lan. Anh ấy đã thiết kế thuật toán trong 20 phút. Ông đã tạo một biểu đồ của 64 thành phố với một số đơn giản hóa (vì máy tính của ông là 6-bit) và viết mã cho chiếc máy tính năm 1956 này. Tuy nhiên, ông đã không công bố thuật toán của mình vì chủ yếu không có tạp chí khoa học máy tính và ông nghĩ điều này có thể không quan trọng lắm. Năm tiếp theo, ông đã tìm hiểu về vấn đề kết nối các thiết bị đầu cuối của máy tính mới sao cho chiều dài của dây được giảm thiểu. Anh ấy suy nghĩ về vấn đề này và phát hiện lại Jarník / Prim ' thuật toán s sử dụng kỹ thuật tương tự như thuật toán đường đi ngắn nhất mà anh ta đã phát hiện ra một năm trước. Anh tađã đề cập rằng cả hai thuật toán của ông đều được thiết kế mà không sử dụng bút hoặc giấy. Năm 1959, ông xuất bản cả hai thuật toán trong một bài báo dài chỉ 2 trang rưỡi.