2010-01-14 39 views
5

Cho một danh sách các lớp kế thừa từ cơ sở này:Thuật toán sạch để sắp xếp một đối tượng theo các phụ thuộc được xác định?

class Plugin(object): 
    run_after_plugins =() 
    run_before_plugins =() 

... và các quy tắc sau:

  • Plugins có thể cung cấp một danh sách các plugin rằng họ phải chạy sau.
  • Plugin có thể cung cấp danh sách plugin mà họ phải chạy trước đó.
  • Danh sách các plugin có thể chứa hoặc không chứa tất cả các plugin đã được chỉ định trong các ràng buộc đặt hàng.

Có ai có thể cung cấp thuật toán sạch đẹp để đặt hàng danh sách plugin không? Nó sẽ cần phải phát hiện phụ thuộc vòng tròn cũng ....

def order_plugins(plugins): 
     pass 

Tôi đã đưa ra một vài phiên bản nhưng không particuarlly gọn gàng: Tôi chắc chắn một số bạn Art of Computer Programming loại sẽ thích thử thách :)

[lưu ý: câu hỏi được đưa ra bằng Python nhưng rõ ràng không chỉ là một câu hỏi Python: mã giả trong bất kỳ ngôn ngữ nào sẽ làm]

Trả lời

8

Điều này được gọi là topological sorting.

Việc áp dụng kinh điển của sắp xếp tô pô (topo theo thứ tự) là trong lịch một chuỗi các công việc hoặc nhiệm vụ; phân loại topo thuật toán lần đầu tiên được nghiên cứu trong các năm đầu thập niên 1960 trong bối cảnh của kỹ thuật PERT để lên lịch trong quản lý dự án (Jarnagin 1960). Các công việc được thể hiện bằng các đỉnh và có là một cạnh từ x đến y nếu công việc x phải hoàn thành trước khi công việc y có thể được bắt đầu (ví dụ: khi giặt quần áo , máy giặt phải hoàn thành trước khi chúng tôi đặt quần áo đến khô). Sau đó, một loại topo cung cấp cho một đơn đặt hàng để thực hiện công việc.

+0

@Eli: Tôi đã tìm thấy câu hỏi này (http://stackoverflow.com/questions/952302/how-to-sort-based-on-dependencies) đã đề cập đến loại sắp xếp đó ngay bây giờ nhưng ví dụ đã cho không có hai loại phụ thuộc riêng biệt cần được sắp xếp: có thể xử lý được trường hợp này không? – jkp

+2

@jkp: nó có thể được chuyển đổi thành biểu diễn đó. tức là A nói rằng B phải chạy trước nó, nhưng C sau đó. Vì vậy, chỉ với các ràng buộc "sau", chúng tôi nói rằng A là sau B và C là sau A. –

+0

@Eli: haha! vâng, tôi đoán khi bạn bật nó lên đầu của nó như thế nó được áp dụng một cách sạch sẽ. A trước khi ràng buộc trên một plugin chỉ là một ràng buộc sau cho một plugin khác :) – jkp

1

Điều này được gọi là topological sorting.

Thực hiện việc này liên quan đến một số bước:

Đầu tiên xây dựng biểu đồ tất cả các plugin được chọn làm đỉnh và phụ thuộc của chúng làm cạnh. Chạy trước/sau khi cạn xuống đến cùng một loại cạnh.

Tiếp theo xây dựng thân tàu quá cảnh: Xem tất cả các plugin và thêm tất cả các phụ thuộc bị thiếu. Lặp lại điều này cho đến khi thiết lập không thay đổi nữa.

Bước cuối cùng: Chọn một đỉnh mà không có các cạnh đến và thực hiện tìm kiếm DFS (hoặc BFS). Thuật toán này có thể được làm giàu bằng phát hiện chu kỳ.

0

Nếu bạn xác định __lt__ và các phương pháp được liên kết trên Plugin dựa trên việc có nên chạy trước hoặc sau khi có thể tìm thấy một yêu cầu lành mạnh với sorted(). Chu kỳ vẫn sẽ là một vấn đề mặc dù.

0

Nếu bạn muốn đưa ra chẩn đoán tốt cho trường hợp có chu kỳ, hãy xem http://en.wikipedia.org/wiki/Strongly_connected_component. Tôi nghĩ rằng nếu bạn sử dụng một phiên bản của một thành phần được kết nối mạnh mẽ như một phiên bản được nêu trong http://www.cs.sunysb.edu/~skiena/373/notes/lecture16/lecture16.html bạn có thể làm cho nó in ra các thành phần được kết nối mạnh mẽ theo thứ tự sắp xếp topo.

2

Here là mã Python phân loại topo.

+0

@ ΤΖΩΤΖΙΟΥ: Vâng, tôi cũng thấy điều đó. Đó là một chút dài cho những gì tôi muốn: phiên bản của tôi chặt chẽ phù hợp với ví dụ được đưa ra trong bài tôi liên kết trong ý kiến ​​của Eli. Tôi đã học được một mẹo mới anyways đó là điều chính :) – jkp

Các vấn đề liên quan