graphlib --- Chức năng hoạt động với các cấu trúc giống như đồ thị¶
Source code: Lib/graphlib.py
- class graphlib.TopologicalSorter(graph=None)¶
Cung cấp chức năng sắp xếp theo cấu trúc liên kết biểu đồ của các nút hashable.
Thứ tự tôpô là thứ tự tuyến tính của các đỉnh trong đồ thị sao cho với mọi cạnh có hướng u -> v từ đỉnh u đến đỉnh v, đỉnh u xuất hiện trước đỉnh v theo thứ tự. Ví dụ: các đỉnh của biểu đồ có thể biểu thị các nhiệm vụ cần thực hiện và các cạnh có thể biểu thị các ràng buộc mà một nhiệm vụ phải được thực hiện trước một nhiệm vụ khác; trong ví dụ này, thứ tự tôpô chỉ là một chuỗi hợp lệ cho các tác vụ. Có thể sắp xếp thứ tự tôpô hoàn chỉnh khi và chỉ khi đồ thị không có chu trình có hướng, nghĩa là nếu nó là đồ thị không có chu trình có hướng.
Nếu đối số graph tùy chọn được cung cấp thì đó phải là một từ điển biểu thị biểu đồ tuần hoàn có hướng trong đó các khóa là các nút và các giá trị là các giá trị có thể lặp lại của tất cả các nút trước của nút đó trong biểu đồ (các nút có các cạnh trỏ đến giá trị trong khóa). Các nút bổ sung có thể được thêm vào biểu đồ bằng phương pháp
add().Trong trường hợp chung, các bước cần thiết để thực hiện sắp xếp một biểu đồ đã cho như sau:
Tạo một phiên bản của
TopologicalSortervới biểu đồ ban đầu tùy chọn.Thêm các nút bổ sung vào biểu đồ.
Gọi
prepare()trên đồ thị.Trong khi
is_active()làTrue, hãy lặp lại các nút đượcget_ready()trả về và xử lý chúng. Gọidone()trên mỗi nút khi nó xử lý xong.
Trong trường hợp chỉ cần sắp xếp ngay lập tức các nút trong biểu đồ và không liên quan đến tính song song, phương thức tiện lợi
TopologicalSorter.static_order()có thể được sử dụng trực tiếp:>>> đồ thị = {"D": {"B", "C"}, "C": {"A"}, "B": {"A"}} >>> ts = TopologicalSorter(đồ thị) >>> bộ dữ liệu(ts.static_order()) ('A', 'C', 'B', 'D')
Lớp này được thiết kế để dễ dàng hỗ trợ xử lý song song các nút khi chúng sẵn sàng. Ví dụ:
topological_sorter=TopologicalSorter() các nút # Add thành 'topological_sorter'... topo_sorter.prepare() trong khi topological_sorter.is_active(): cho nút trong topological_sorter.get_ready(): các luồng hoặc quy trình # Worker yêu cầu các nút hoạt động ngoài # hàng đợi 'task_queue'. task_queue.put(nút) # When công việc của một nút đã hoàn tất, công nhân đã đưa nút vào # 'finalized_tasks_queue' để chúng tôi có thể có thêm nút để làm việc. Định nghĩa # The của 'is_active()' đảm bảo rằng, tại thời điểm này, tại # least một nút đã được đặt trên 'task_queue' nhưng vẫn chưa # been được chuyển tới 'done()', vì vậy việc chặn 'get()' này phải (cuối cùng) # succeed. Sau khi gọi 'done()', chúng ta lặp lại để gọi 'get_ready()' # again, vì vậy hãy đặt các nút mới được giải phóng vào 'task_queue' ngay khi # logically có thể. nút = Finalized_tasks_queue.get() topo_sorter.done(nút)
- add(node, *predecessors)¶
Thêm một nút mới và các nút trước đó vào biểu đồ. Cả node và tất cả các phần tử trong predecessors đều phải là hashable.
Nếu được gọi nhiều lần với cùng một đối số nút, tập hợp các phần phụ thuộc sẽ là tập hợp của tất cả các phần phụ thuộc được truyền vào.
Có thể thêm một nút không có phần phụ thuộc (predecessors không được cung cấp) hoặc cung cấp phần phụ thuộc hai lần. Nếu một nút chưa được cung cấp trước đó được bao gồm trong predecessors, nó sẽ tự động được thêm vào biểu đồ mà không có nút trước đó.
Tăng
ValueErrornếu được gọi sauprepare().
- prepare()¶
Đánh dấu biểu đồ là đã hoàn thành và kiểm tra các chu kỳ trong biểu đồ. Nếu phát hiện bất kỳ chu kỳ nào,
CycleErrorsẽ được tăng lên, nhưngget_ready()vẫn có thể được sử dụng để thu được càng nhiều nút càng tốt cho đến khi các chu kỳ chặn nhiều tiến trình hơn. Sau khi gọi hàm này, biểu đồ không thể được sửa đổi và do đó không thể thêm nút nào nữa bằngadd().Một
ValueErrorsẽ được nâng lên nếu việc sắp xếp được bắt đầu bởistatic_order()hoặcget_ready().Thay đổi trong phiên bản 3.14:
prepare()bây giờ có thể được gọi nhiều lần miễn là việc sắp xếp chưa bắt đầu. Trước đây điều này đã gây raValueError.
- is_active()¶
Trả về
Truenếu có thể thực hiện được nhiều tiến bộ hơn và trả vềFalsenếu ngược lại. Tiến trình có thể được thực hiện nếu các chu kỳ không chặn độ phân giải và vẫn còn các nút sẵn sàng chưa đượcTopologicalSorter.get_ready()trả về hoặc số nút được đánh dấuTopologicalSorter.done()ít hơn số đượcTopologicalSorter.get_ready()trả về.Phương thức
__bool__()của lớp này trì hoãn chức năng này, vì vậy thay vìnếu ts.is_active(): ...
có thể chỉ cần làm:
nếu ts: ...
Tăng
ValueErrornếu được gọi mà không gọiprepare()trước đó.
- done(*nodes)¶
Đánh dấu một tập hợp các nút được
TopologicalSorter.get_ready()trả về là đã được xử lý, bỏ chặn mọi nút kế thừa của mỗi nút trong nodes để được trả về trong tương lai bằng lệnh gọi tớiTopologicalSorter.get_ready().Tăng
ValueErrornếu bất kỳ nút nào trong nodes đã được đánh dấu là đã được xử lý bằng lệnh gọi trước đó tới phương thức này hoặc nếu một nút không được thêm vào biểu đồ bằng cách sử dụngTopologicalSorter.add(), nếu được gọi mà không gọiprepare()hoặc nếu nút chưa đượcget_ready()trả về.
- get_ready()¶
Trả về
tuplevới tất cả các nút đã sẵn sàng. Ban đầu, nó trả về tất cả các nút không có nút trước đó và khi các nút đó được đánh dấu là đã xử lý bằng cách gọiTopologicalSorter.done(), các lệnh gọi tiếp theo sẽ trả về tất cả các nút mới có tất cả các nút trước đó đã được xử lý. Khi không thể thực hiện được tiến trình nào nữa, các bộ dữ liệu trống sẽ được trả về.Tăng
ValueErrornếu được gọi mà không gọiprepare()trước đó.
- static_order()¶
Trả về một đối tượng iterator sẽ lặp qua các nút theo thứ tự tôpô. Khi sử dụng phương pháp này, không nên gọi
prepare()vàdone(). Phương pháp này tương đương với:def static_order(tự): tự.prepare() trong khi self.is_active(): node_group = self.get_ready() lợi nhuận từ node_group self.done(*node_group)
Thứ tự cụ thể được trả về có thể phụ thuộc vào thứ tự cụ thể mà các mục được chèn vào biểu đồ. Ví dụ:
>>> ts = TopologicalSorter() >>> ts.add(3, 2, 1) >>> ts.add(1, 0) >>> print([*ts.static_order()]) [2, 0, 1, 3] >>> ts2 = TopologicalSorter() >>> ts2.add(1, 0) >>> ts2.add(3, 2, 1) >>> print([*ts2.static_order()]) [0, 2, 1, 3]
Điều này là do thực tế là "0" và "2" ở cùng cấp độ trong biểu đồ (chúng sẽ được trả về trong cùng một lệnh gọi tới
get_ready()) và thứ tự giữa chúng được xác định theo thứ tự chèn.Nếu phát hiện bất kỳ chu kỳ nào,
CycleErrorsẽ được nâng lên.
Added in version 3.9.
Ngoại lệ¶
Mô-đun graphlib xác định các lớp ngoại lệ sau:
- exception graphlib.CycleError¶
Lớp con của
ValueErrorđược tạo ra bởiTopologicalSorter.prepare()nếu tồn tại các chu trình trong biểu đồ đang hoạt động. Nếu có nhiều chu kỳ tồn tại, chỉ một lựa chọn không xác định trong số đó sẽ được báo cáo và đưa vào ngoại lệ.Chu trình được phát hiện có thể được truy cập thông qua phần tử thứ hai trong thuộc tính
argscủa phiên bản ngoại lệ và bao gồm một danh sách các nút, sao cho mỗi nút, trong biểu đồ, là tiền thân trực tiếp của nút tiếp theo trong danh sách. Trong danh sách được báo cáo, nút đầu tiên và nút cuối cùng sẽ giống nhau, để làm rõ rằng nó có tính tuần hoàn.