より単純なパスの数発見アルゴリズム


34

G=(V,E)ststG
tP Z V P S R Y のV V S R Y VのP O Vstこれが他のパスのサブパスである場合、DFSもこのサブパスを再度通過します。たとえば、からまでのパスの数を見つける必要がある隣接リストを考えます。 ここで、DFSはで始まり、 DFSが正常に実行されないため、ます。 pathは。これはに遭遇するため、頂点色を灰色に変更しないためです。pv

poszorsvsrryyvvwzwz
ppzvpsryvvs,r,y,vpovの色ので、パスwhite.Thenまだの色ので白色であり、同様に、パスのカウンタ.Alsoとき増分取得れ維持される検出されます。p o s r y v s p o r y v vvposryvsporyvv

私のアルゴリズムは正しいですか?そうでない場合、それを修正するためにどのような修正が必要か、または他のアプローチが大いに評価されます。

:ここでは、コーメンによるアルゴリズムの紹介」という本に記載されているDFSアルゴリズムを検討しました。このアルゴリズムでは、ノードをそのステータスに応じて色付けします。ノードが未訪問、未探索、探索の場合、色は白になり、それぞれグレーと黒。他のすべては標準です。



4
有向非巡回グラフのすべてのパスは必然的に単純であることに注意してください(非巡回性のため)。
ノルドリン

回答:


37

現在の実装では、DAGの正しいパス数が計算されます。ただし、パスをマークしないと、指数関数的な時間がかかります。たとえば、次の図では、DAGの各段階でパスの合計数が3の倍数増加します。この指数関数的な成長は、動的プログラミングで処理できます。

ダグ

多くのコンピューティング - Tの DAGのパスが再発によって与えられる、 パスU = { 1の場合  、U = T Σ U Vst

Paths(u)={1if u=t(u,v)EPaths(v)otherwise.

DFSの簡単な修正により、次のように計算されます。

def dfs(u, t):
    if u == t:
        return 1
    else:
        if not u.npaths:
            # assume sum returns 0 if u has no children
            u.npaths = sum(dfs(c, t) for c in u.children)
        return u.npaths

各エッジが1回だけ参照されること、つまりランタイムを確認することは難しくありません。O(V+E)


私はあなたのアルゴリズムを理解しており、同じ再帰呼び出しが何度も呼び出されるため、動的プログラミングを使用することで効率を上げることができます。
サウラブ

1
@SaurabhHota、動的プログラミングを使用しています。頂点が最初検出され、それはパスの数計算しなければならないTは。これはu.npathsに保存されます。uへの以降の各呼び出しは、そのパスの数を再計算せず、単にu.npathsを返します。utu
ニコラスマンクーソ

1
そのようなグラフの場合、m ^ nだけの答えではありません。mは列内のノードの数(ここでは3)、nはs、tを除く列の数(ここでは4)です。出力は、グラフの例では3 ^ 4 = 81です。
-saadtaame

@saadtaame、確かに; ただし、私の意図は、グラフの「長さ」が大きくなるにつれて指数関数的な増加を示すことだけでした。もちろん、高度に構造化されたグラフについては、リストされたアルゴリズムがすべてのグラフで機能する間、閉じた形で数えることができます。
ニコラスマンクーソ

3
の時間を実行しているあなたは、一定時間内に必要な追加を行うことができることを前提としていますが、追加されている数字は持つことができΘ V 最悪の場合のビットを。パスの正確な数が必要場合、実行時間(ビット操作のカウント)は実際にはO V E です。O(V+E)Θ(V)O(VE)
-JeffE

15

1つのノードからターゲットノードへのパスの数は、その子からターゲットへのパスの数の合計であることに注意する必要があります。グラフにサイクルがないため、このアルゴリズムは常に停止することがわかっています。

ノードを訪問するときに、1つのノードからターゲットまでのパスの数を保存すると、時間の複雑さは頂点の数で線形になり、メモリはノードの数で線形になります。


0

DAGの2つの頂点間のパスの数は、隣接行列表現を使用して見つけることができます。

AがGの隣接行列であると仮定します。恒等行列を追加した後にAのK乗を取得すると、長さ<= Kのパスの数が得られます。

DAGの単純なパスの最大長は| V | -1であるため、| V | -1乗を計算すると、すべての頂点のペア間のパスの数が得られます。

| V | -1のべき乗の計算は、各TCのlog(| V | -1)の複製を実行することで実行できます:| V | ^ 2。


質問は線形時間アルゴリズムを要求します。あなたのアルゴリズムはそれよりも遅いです。
DW

@Vivekはあなたの答えに定理の参照を言及できますか?
ハミデ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.