Tôi đã có một vấn đề tương tự và kết thúc giải quyết nó theo cách này:
cấu trúc dữ liệu của tôi được làm bằng dependends
từ điển, từ một node id vào một danh sách các nút phụ thuộc vào nó (tức là tín đồ của nó trong. DAG). Lưu ý rằng nó chỉ hoạt động đối với một DAG - đó là đồ thị theo hướng, tuần hoàn.
Tôi chưa tính độ phức tạp chính xác của nó, nhưng nó nuốt đồ thị của tôi vài nghìn lần trong một giây.
_transitive_closure_cache = {}
def transitive_closure(self, node_id):
"""returns a set of all the nodes (ids) reachable from given node(_id)"""
global _transitive_closure_cache
if node_id in _transitive_closure_cache:
return _transitive_closure_cache[node_id]
c = set(d.id for d in dependents[node_id])
for d in dependents[node_id]:
c.update(transitive_closure(d.id)) # for the non-pythonists - update is update self to Union result
_transitive_closure_cache[node_id] = c
return c
def can_reduce(self, source_id, dest_id):
"""returns True if the edge (source_id, dest_id) is redundant (can reach from source_id to dest_id without it)"""
for d in dependents[source_id]:
if d.id == dest_id:
continue
if dest_id in transitive_closure(d.id):
return True # the dest node can be reached in a less direct path, then this link is redundant
return False
# Reduce redundant edges:
for node in nodes:
dependents[node.id] = [d for d in dependents[node.id] if not can_reduce(node.id, d.id)]
Thay vào đó, chúng tôi có thể xem xét B ---> C để dự phòng không? –
Liệu dự phòng có nghĩa là "một cạnh X-> Y là dư thừa nếu có một đường dẫn không cạnh từ X đến Y" hay bạn chỉ đơn giản là tìm kiếm một cây bao trùm? –
@ Zach: Không, B-> C không thừa, vì nếu nó bị xóa, không có đường dẫn nào trong biểu đồ kết quả từ B đến C. – ShreevatsaR