que tenía un problema similar y terminó resolviendo de esta manera:
Mi estructura de datos se hace de dependends
diccionario, de un identificador de nodo a una lista de nodos que dependen de él (es decir, sus seguidores en el. TROZO DE CUERO). Tenga en cuenta que funciona solo para un DAG, es decir, gráfico acíclico dirigido.
No he calculado la complejidad exacta de la misma, pero se tragó mi gráfico de varios miles en una fracción de segundo.
_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)]
¿Podemos considerar B ---> C como redundante? –
¿Significa redundante "un borde X-> Y es redundante si hay una ruta sin borde de X a Y" o simplemente está buscando un árbol de expansión? –
@Zach: No, B-> C no es redundante, porque si se elimina no hay ninguna ruta en el gráfico resultante de B a C. – ShreevatsaR