Ordinare topologicamente questo DAG per stabilire un ordine per i suoi nodi. Per ogni nodo, il suo valore sarebbe il numero di bordi in uscita da tutti i nodi precedenti meno il numero di fronti in entrata per tutti i nodi precedenti e il nodo corrente. Il valore per il nodo "Dominator" è sempre zero.
Dopo che un nodo è contrassegnato come "eliminato", inserire i suoi predecessori e successori nella coda di priorità. La priorità è determinata dall'ordinamento topologico. Aggiorna i valori per tutti i nodi, seguendo il nodo "eliminato" (aggiungi il numero di nodi in ingresso e sottrai il numero di nodi in uscita per questo nodo). Allo stesso tempo (nello stesso ordine) il valore di decremento per ciascun nodo tra il nodo predecessore nella coda di priorità e il nodo "cancellato" e il valore di incremento per ciascun nodo, a partire dal nodo successore nella coda di priorità. Interrompi quando il valore di qualche nodo è decrementato a zero. Questo è un nuovo nodo "dominatore". Se tutti i nodi "dominatori" sono necessari, continuare fino alla fine del grafico.
delete(delNode):
for each predecessor in delNode.predecessors: queue.add(predecessor)
for each successor in delNode.successors: queue.add(successor)
for each node in DAG:
if queue.top.priority == node.priority > delNode.priority:
++accumulator
node.value += accumulator
if node.value == 0: dominatorDetected(node)
if node.priority == delNode.priority:
accumulator += (delNode.predecessors.size - delNode.successors.size)
node.value = -1
if queue.top.priority == node.priority:
queue.pop()
if node.priority < delNode.priority:
--accumulator
if queue.empty: stop
per il caso di più fonti, è possibile utilizzare lo stesso algoritmo, ma mantenere una lista di "valori" per ogni nodo, un valore per ciascuna sorgente. La complessità dell'algoritmo è O(Nodes * Sources)
, lo stesso che per la ricerca indipendente su ciascuna delle fonti. Ma il programma può essere reso più efficiente se si utilizza la vettorizzazione. "valori" possono essere elaborati in parallelo con le istruzioni SIMD. I compilatori moderni possono fare la vettorizzazione automatica per ottenerlo.
fonte
2012-02-06 16:08:50
Ciò significa che si desidera determinare in modo incrementale il taglio in un grafico che cambia? E hai bisogno di tutti questi nodi (tutti i tagli) o ne basta uno? – jpalecek
Sì, questo è un altro modo di dirlo: rilevare un taglio appena prima che accada (cioè, appena prima che l'ultimo nodo venga cancellato, ciò porterebbe a un taglio). – Jules
Ri: modifica: preferibilmente tutti questi tagli, ma un taglio sarebbe anche abbastanza buono. I tagli dovrebbero accadere relativamente di rado, quindi se dovesse accadere non sarebbe un grosso problema gestire un algoritmo lento per trovare gli altri tagli. – Jules