このDAGをトポロジカルソートして、ノードの順序を確立します。各ノードの値は、先行するすべてのノードからの発信エッジの数から、先行するすべてのノードと現在のノードへの着信エッジの数を引いたものになります。「ドミネーター」ノードの値は常にゼロです。
一部のノードが「削除済み」とマークされたら、その先行ノードと後続ノードを優先キューに入れます。優先度はトポロジカルソート順で決まります。「削除された」ノードに続いて、すべてのノードの値を更新します(着信ノードの数を加算し、このノードの発信ノードの数を減算します)。同時に(同じ順序で)優先キュー内の先行ノードと「削除済み」ノードの間の各ノードの値をデクリメントし、優先キュー内の後続ノードから開始して各ノードの値をインクリメントします。一部のノードの値がゼロにデクリメントされたら停止します。これは新しい「ドミネーター」ノードです。すべての「ドミネーター」ノードが必要な場合は、グラフの最後まで続行します。
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
複数のソースの場合、同じアルゴリズムを使用できますが、ノードごとに「値」のリストを保持し、ソースごとに1つの値を保持します。アルゴリズムの複雑さはO(Nodes * Sources)
、各ソースでの独立した検索の場合と同じです。ただし、ベクトル化を使用すると、プログラムがより効率的になる可能性があります。「値」はSIMD命令と並行して処理できます。最近のコンパイラは、これを実現するために自動ベクトル化を行う場合があります。