Có cách tiếp cận nào tốt hơn để tìm đường đi ngắn nhất trong mạng lưới giao thông (xe cộ) không?


8

Các bạn lập trình viên thân mến,

Chúng tôi đang phát triển phần mềm mô phỏng lưu lượng xe cộ. Một phần của quá trình gọi là "chuyển nhượng" liên quan đến việc chỉ định phương tiện cho các tuyến đường của họ và phải sử dụng một số loại thuật toán tìm đường đi ngắn nhất.

Theo truyền thống, mọi người làm điều này với Dijkstra, và một số tài liệu khoa học nhất định dường như chỉ ra rằng A * và các lựa chọn thay thế khác không mang lại bất kỳ cải thiện đáng kể nào, có lẽ là do bản chất của biểu đồ.

Do đó, chúng tôi cũng đang sử dụng Dijkstra. Một vấn đề nhỏ nảy sinh ở chỗ, nếu bạn coi các liên kết giao thông (đoạn đường giữa các giao lộ) là các cạnh và nút giao là nút, bạn không thể có được biểu đồ đơn hướng cổ điển: khi tiếp cận giao lộ, nơi bạn có thể rẽ thường xuyên bạn đến từ đâu, trong khi trong một biểu đồ truyền thống, bạn có thể lấy bất kỳ cạnh nào từ một nút.

Chúng tôi đã giải quyết vấn đề này khá dễ dàng bằng cách biểu diễn một cặp giao cắt liên kết (gọi nó là "lath") như một nút. Vì bạn cần phải đi qua một liên kết để đến bất kỳ "lath" tiếp theo hoặc điểm lựa chọn nào, nên một cạnh sẽ được xác định là đường ngang này và bạn có được một biểu đồ điển hình.

Các kết quả sau đó được lưu trữ trong một bảng đơn giản, N x N, trong đó N là số lượng "máy tiện".

Đây là nhược điểm (không thể tránh khỏi?). Nếu một mạng điển hình cho mô phỏng của chúng tôi có thể có 2000 giao lộ, thì nó sẽ có khoảng 6000 liên kết, tức là N = 3V. Rõ ràng, nếu được tính theo các giao điểm (V), giờ đây chúng ta đã lên đến O (log (3V) * (3V + E)).

Bạn có thể lập luận rằng 3 (hoặc 9) là một yếu tố không đổi, nhưng từ quan điểm thực tế, nó làm mọi thứ chậm lại một chút và tăng không gian lưu trữ lên 3V x 3V.

Có ai có ý tưởng làm thế nào chúng ta có thể cơ cấu lại điều này để cải thiện hiệu suất? Không nhất thiết là bất kỳ thuật toán thay thế nào, có lẽ định hình lại cấu trúc dữ liệu để phù hợp với biểu đồ theo một cách khác?


Tôi không rõ N và V là gì. V có phải là số đỉnh (giao điểm) và N là số cung giữa các đỉnh không? Ngoài ra, E là gì?
Mike Dunlavey

Bạn đã đọc những tài nguyên nào? IIRC, A * được chứng minh là tìm ra con đường tối ưu trong khoảng thời gian ít nhất cho một heuristic bi quan. Trong thực tế, A * hồi quy vào Dijkstra với một heuristic trống / 0.
Steven Evers

Ngoài ra, bạn đang sử dụng biểu đồ nào? Các đồ thị đơn hướng với các danh sách kề sẽ dễ dàng cho phép các đường như các cạnh / giao điểm là các nút (thực tế, ngay cả một ma trận kề, nhưng rõ ràng nó phải là một ma trận đầy đủ thay vì hình tam giác trên / dưới). TBH: Tôi muốn đề xuất rất nhiều tài liệu lập trình trò chơi, đó là một vấn đề rất hiệu quả trong lĩnh vực đó và có cùng một hạn chế hiệu suất nghiêm ngặt hơn như bạn đang đề cập.
Steven Evers

1
@SnOrfus: có, nhưng bạn không thể luôn biểu thị một giao lộ duy nhất dưới dạng một nút, ví dụ: giao lộ cho phép bạn rẽ trái hoặc đi thẳng nhưng không rẽ phải, ma trận kề đơn giản sẽ không thể biểu thị điều đó ( tệ hơn nếu bạn có bùng binh).
Lie Ryan

@LieRyan: Có thể tôi đang hiểu nhầm bạn nhưng điều đó không khác gì một giao lộ nơi không có ngã rẽ phải và nên được thể hiện theo cùng một cách.
Steven Evers

Câu trả lời:


6

Dijkstra tìm thấy con đường ngắn nhất giữa một nút nhất định và tất cả các nút khác, vì vậy tôi hy vọng nó sẽ đắt hơn A *. Tuy nhiên, có vẻ như bạn đang cố gắng tính toán trước chi phí & đường dẫn từ bất kỳ nút nào đến bất kỳ nút nào khác? Sau đó, Dijkstra là con đường để đi.

Đối với một đại diện đơn giản hơn, một vài điều đến với tâm trí:

Tại nhiều ngã tư, bạn có thể đến và để lại bất kỳ cách nào bạn muốn. Đó chỉ là một tập hợp con mà bạn có các hạn chế như "không rẽ trái." Vì vậy, bạn chỉ có thể sử dụng "máy tiện" cho các giao lộ nơi bạn thực sự cần chúng. Điều đó sẽ làm giảm đáng kể kích thước ngay tại đó.

Bạn có thể làm điều này tự động bằng cách tìm kiếm "máy tiện tương đương" và kết hợp chúng. Hai máy tiện là tương đương nếu tất cả các liên kết đi ra là như nhau. Ví dụ: nếu "Giao lộ X đến từ phương Tây" và "Giao lộ X đến từ miền Nam" đều dẫn đến cùng một tập hợp các nút khác, với cùng một chi phí, sau đó chỉ cần hợp nhất chúng vào một nút.

Bạn có chắc chắn cần / muốn tính toán trước đường dẫn tốt nhất, thay vì tính toán trực tuyến? Trò chơi video thường tính toán những thứ này trực tuyến.

Ngoài ra, làm thế nào bạn đại diện cho các con đường? Trong ma trận của bạn, bạn chỉ cần thể hiện liên kết đầu tiên trong đường dẫn. Ví dụ: để đi từ nhà của Bob đến công việc của Bob, bạn chỉ cần biết liên kết đầu tiên, vì khi họ đến đó, bây giờ bạn có thể xem ma trận của mình để biết cách lấy từ liên kết đầu tiên đến công việc của Bob, nơi sẽ cung cấp cho bạn liên kết thứ hai, vv


Kết hợp "máy tiện" thực sự là một ý tưởng thú vị. Bạn nói đúng, chúng tôi đang tìm đường đi ngắn nhất giữa mỗi cặp nút và sau đó tạo đường dẫn. Trong một mô phỏng giao thông điển hình, hầu như không có con đường nào không bao giờ được sử dụng (tại sao thậm chí sẽ có một con đường ở đó ngay từ đầu, phải không?). Khi bạn nói "trực tuyến", bạn có nghĩa là trong thời gian thực? Tất cả những gì chúng ta thực sự có thể làm là tính toán những con đường ngắn nhất "dự kiến", vì chúng ta không thực sự biết chính xác những điều kiện sẽ xảy ra trên một số liên kết khi chiếc xe thực sự đến đó. Chúng tôi cập nhật ma trận đường dẫn ngắn nhất dựa trên các điều kiện hiện tại.
Greg Kramida

Vâng, bằng cách "trực tuyến", ý tôi là trong thời gian thực, tức là khi Bob rời khỏi nhà và muốn đi làm, hãy làm A *.
Martin C. Martin

Tùy thuộc vào tần suất ma trận đường dẫn ngắn nhất cần được cập nhật, bạn có thể thực hiện rất nhiều công việc để cập nhật và không kết thúc việc sử dụng hầu hết các ô trước khi thực hiện lại cập nhật. Tôi không biết chi tiết về trường hợp sử dụng của bạn, nhưng từ bên ngoài, có vẻ như A * ít nhất là đáng để thử. Ngoài ra, trong khi tất cả các nút N được sử dụng tại một số điểm, điều đó không có nghĩa là tất cả các cặp N ^ 2 sẽ được sử dụng tại một số điểm. Những người trong khối của Bob, họ có bao nhiêu điểm đến độc đáo?
Martin C. Martin

Vâng, tôi đồng tình, A * có lẽ đáng để thử. Đối với một số mô phỏng, chúng tôi định tuyến một số phần của phương tiện tại mỗi điểm đến gần như tất cả các điểm đến, nhưng cho đến nay không phải trong mọi trường hợp. Tôi đã tìm thấy một vài bài viết về những người sử dụng các phương pháp phỏng đoán khác nhau dành riêng cho các mạng lưu lượng, tôi sẽ thử chúng. Cảm ơn sự giúp đỡ của bạn, Martin.
Greg Kramida

1

Bạn có đồ thị lớn và bạn đã làm cho nó thậm chí còn lớn hơn. Martinc C. Martin khuyên chỉ nên sử dụng máy tiện khi cần thiết, vì vậy tôi sẽ không đi sâu vào vấn đề này.

Một trong những điều có thể giúp bạn, là chuyển biểu đồ của bạn thành các biểu đồ nhỏ hơn.

Đơn giản hóa đầu tiên đã giúp tôi rất nhiều (tôi đã làm việc với các mạng lưới đường bộ của các quốc gia châu Âu) là "loại bỏ" các nút với digree 1 và 2 theo cách đệ quy. Bằng cách này, bạn không có đường cụt và giao lộ T (ban đầu là cấp 3) trở thành mức 2 và điều đó không thú vị, nếu bạn không đi đến nút hoặc nút đó trong cull de sac.

Sau đó, bạn có thể thử chia biểu đồ của mình thành các phần có số lượng lớn các nút và cạnh bên trong, nhưng có kết nối tối thiểu với các phần khác. Để tìm ra chúng, tôi đã sử dụng đường cắt tối thiểu trong đó bồn rửa và nguồn nằm cách xa nhau (ở các cạnh) và các cạnh gần chúng có dung lượng rất lớn và các cạnh ở đâu đó ở giữa nhỏ.

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.