Thuật toán Dijkstra so với chiều rộng tìm kiếm đầu tiên cho đường đi ngắn nhất trong biểu đồ


11

Tôi đã hỏi câu hỏi này trong StackOverflow. Tôi đã được yêu cầu chuyển đến đây. vì vậy đây là:

Tôi cần một số giải thích và đầu vào liên quan đến thuật toán của Dijkstra so với tìm kiếm đầu tiên trong các biểu đồ có hướng, nếu những điều này là chính xác.

Thuật toán của Dijkstra tìm thấy con đường ngắn nhất từ ​​Node Ađến Node Ftrong một biểu đồ có trọng số bất kể có chu kỳ hay không (miễn là không có trọng số âm)

nhưng vì thế, tất cả các đường dẫn từ Ađến tất cả các Nút khác trong biểu đồ đều được tính toán và chúng tôi lấy đường dẫn từ Ađến Fbằng cách đảo ngược chuỗi của các nút trong prev.

BFS: tìm đường đi ngắn nhất từ ​​nút này Asang nút khác Ftrong đồ thị không có trọng số, nhưng nếu thất bại nếu phát hiện một chu kỳ.

tuy nhiên, BFS chỉ tính toán đường dẫn từ Nút A đến Nút F và không nhất thiết là tất cả đường dẫn từ Nút A. nếu Node F đến sớm, nó chỉ trả về đường dẫn.

biểu đồ ví dụ

Câu trả lời:


17
  1. BFS không thất bại nếu một chu kỳ được phát hiện. http://en.wikipedia.org/wiki/Breadth-first_search

  2. Dijkstra's cũng không tính toán tất cả các đường dẫn từ A đến F. Nó dừng lại khi tìm thấy con đường ngắn nhất từ ​​A đến F.

  3. Trong biểu đồ không có trọng số, bạn có thể sử dụng BFS để tìm kiếm con đường ngắn nhất từ ​​A đến tất cả các nút khác trong cùng một lần chạy! (chỉ không làm cho nó dừng lại ngay khi nó tìm thấy F)

  4. Bạn có thể sử dụng thuật toán loại BFS để tìm đường đi ngắn nhất nếu bạn biết tất cả các độ dài là số nguyên nhỏ hơn số 'nhỏ' k trong O (k (v + e)) bằng cách thay thế mọi cạnh (u, w) có độ dài n với đường dẫn của các nút n-1 giữa u và w, độ dài của mỗi cạnh trong đường dẫn là 1.

Hi vọng điêu nay co ich.


bạn có thể giải thích điểm 4
user1988876

@ User1988876: Như một nhận xét chung, nếu bạn quan tâm đến câu trả lời của Aditya, tôi thực sự khuyên bạn nên nêu lên câu trả lời của anh ấy (như tôi thực sự đã làm). Đó thường là một ý tưởng tốt trong một trang web như thế này.
Carlos Linares López

1
Xin lỗi vì hồi âm muộn. Lấy bất kỳ cạnh nào của đồ thị có trọng số nhỏ (nhỏ hơn k) số nguyên (u, v) trọng lượng, giả sử, 5. Thay thế uv cạnh bằng đường dẫn aa như sau u-uv1-uv2-uv3-uv4-v ( uv1 đến uv5 là các nút mới) với trọng số của mỗi cạnh ở giữa là 1. Làm điều này cho mọi cạnh. Bây giờ tất cả các trọng số của biểu đồ kết quả là 1, bạn có thể nghĩ về nó như một biểu đồ vô hướng với <= k | v | đỉnh và <= k | e | cạnh. Sử dụng BFS để tìm đường đi ngắn nhất. Nhìn chung, điều này không tốt hơn Dijkstra vì các trọng số có thể lớn tùy ý và không tách rời trong biểu đồ.
Aditya

6

Trong khi phản hồi của Aditya là tốt, tôi muốn làm rõ một vài điểm.

Bề rộng-Tìm kiếm đầu tiên

Breadth-First Search (BFS) chỉ sử dụng hàng đợi để đẩy và bật các nút bật / tắt. Điều này có nghĩa là nó truy cập các nút theo thứ tự độ sâu của chúng.

Nếu điều đó xảy ra là chi phí của tất cả các nhà khai thác là như nhau (để chúng được coi là bằng 1), thì nó được đảm bảo để tìm ra một giải pháp tối ưu.

Do đó, lưu ý những điều sau:

  1. Nó chỉ liệt kê các đường dẫn cho đến khi giải pháp cuối cùng được tìm thấy. Không thể nói rằng thuật toán này tính toán đường dẫn ngắn nhất từ ​​nút nguồn đến nút mục tiêu (period!). Nó chỉ tính khoảng cách đến tất cả các con đường mà nó gặp trên đường tới mục tiêu. Nói cách khác, bất cứ điều gì được nói về đường dẫn mà nó tìm thấy cho nút mục tiêu đều có thể được nói như nhau về bất kỳ đường dẫn nào khác được phát hiện bởi nó.

  2. Không có gì ngăn cản BFS được áp dụng cho các biểu đồ với chi phí tùy ý. Điểm duy nhất cần nhớ là thuật toán duy trì tính đầy đủ (để nó được đảm bảo tìm ra giải pháp) mặc dù khả năng chấp nhận bị mất (nghĩa là nó không đảm bảo giải pháp được tìm thấy là tối ưu).

  3. Ban đầu, BFS không xem xét danh sách ĐÓNG để lưu trữ tất cả các nút được mở rộng để bạn có thể đúng khi bạn nói rằng nó có thể rơi vào một chu kỳ. Tuy nhiên, vì nó lưu trữ rõ ràng tất cả các nút trong bộ nhớ và lớp yêu cầu bộ nhớ nhiều hơn luôn luôn là lớp mới nhất, BFS thường được mở rộng với danh sách ĐÓNG lưu trữ tất cả các nút được mở rộng trước đó. Nếu gặp phải một chuyển vị trước khi mở rộng một nút, nó có thể được bỏ qua một cách an toàn.

Thuật toán của Dijkstra

Trong thực tế, nếu bạn thêm danh sách ĐÓNG vào BFS như được đề xuất ở điểm 3 ở trên và cũng sắp xếp các nút trong ngăn xếp (danh sách được gọi là MỞ) theo thứ tự tăng dần của g(n) (nghĩa là chi phí của đường dẫn từ trạng thái bắt đầu đến n) sau đó bạn có thuật toán của Dijkstra (tốt, cũng có một sự khác biệt rất quan trọng khác, trong khi BFS dừng khi tạo nút mục tiêu, Dijkstra dừng lại khi mở rộng nó).

Vì thế:

  1. Một lần nữa, thuật toán này chỉ liệt kê các đường dẫn cho đến khi giải pháp cuối cùng được tìm thấy. Không đúng khi nó truy cập tất cả các nút trong không gian trạng thái và thực tế, thuật toán của Dijkstra đã được biết là hoàn chỉnh (nghĩa là nó đảm bảo rằng một giải pháp sẽ được tìm thấy nếu có tồn tại) ngay cả khi đồ thị bên dưới là vô hạn.

  2. Bạn có thể áp dụng thuật toán của Dijkstra một cách an toàn khi các hoạt động có chi phí tùy ý. Thật vậy, đó là lý do tại sao bạn thay thế hàng đợi bằng một đống trong đó các nút được chèn theo thứ tự tăng dần của chi phí của chúng.

  3. Edgar Dijkstra ban đầu xem xét sử dụng danh sách ĐÓNG (bạn có thể kiểm tra giấy của anh ấy, nó chỉ dài vài trang và rất dễ đọc) để các chu kỳ được xem xét đúng.

Hy vọng điều này sẽ giúp, có thể cần một lời giải thích chi tiết hơn về các thuật toán này. Nếu vậy, đừng ngần ngại yêu cầu họ

Chúc mừng


1
BFS sử dụng hàng đợi không phải là ngăn xếp.
nbro

@nbro: Đúng vậy! Cảm ơn đã chỉ ra rằng! Tôi chỉnh sửa và sửa đổi phản ứng của tôi cho phù hợp!
Carlos Linares López
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.