Jeremiah Willcockの答えは正しいですが、詳細はわかりません。DAG の線形時間アルゴリズムを次に示します。
for each node v, initialize num_paths[v] = 0
let t be the destination and set num_paths[t] = 1
for each node v in reverse topological order (sinks before sources):
for each successor w of v:
set num_paths[v] = num_paths[v] + num_paths[w]
let s be the origin and return num_paths[s]
一般的な有向グラフの問題は#P-completeであると確信していますが、数分間の検索では、 cstheory に関するソースのない質問を除いて何も見つかりませんでした。
さて、ここにいくつかの擬似コードがあります。以前のアルゴリズムの内容をトポロジカル ソートに統合し、いくつかのサイクル検出ロジックを追加しました。s
との間のサイクルの場合t
、 の値は不正確になる可能性がありますが、が到達可能num_paths
かどうかによってゼロ以外の値になります。t
サイクル内のすべてのノードがin_cycle
true に設定されるわけではありませんが、すべての SCC ルート (Tarjan の SCC アルゴリズムの意味で) が true に設定されるため、s と t の間にサイクルがある場合にのみ早期終了をトリガーするのに十分です。
REVISED ALGORITHM
let the origin be s
let the destination be t
for each node v, initialize
color[v] = WHITE
num_paths[v] = 0
in_cycle[v] = FALSE
num_paths[t] = 1
let P be an empty stack
push (ENTER, s) onto P
while P is not empty:
pop (op, v) from P
if op == ENTER:
if color[v] == WHITE:
color[v] = GRAY
push (LEAVE, v) onto P
for each successor w of v:
push (ENTER, w) onto P
else if color[v] == GRAY:
in_cycle[v] = TRUE
else: # op == LEAVE
color[v] = BLACK
for each successor w of v:
set num_paths[v] = num_paths[v] + num_paths[w]
if num_paths[v] > 0 and in_cycle[v]:
return infinity
return num_paths[s]