私は networkx を使用しており、グラフ内の長さ 3 のすべてのウォーク、特に 3 つのエッジを持つパスを見つけようとしています。networkx のドキュメントでアルゴリズムに関する情報を見つけようとしましたが、グラフ内の最短パスのアルゴリズムしか見つけることができませんでした。最短パスが 14 -> 15 -> 16 の場合、特定のノードを通過するパスの長さを見つけることはできますか? たとえば、ノード 14 -> 11 -> 12 -> 16 を通過するパスは? 例のグラフのイメージを次に示します。
11185 次
1 に答える
15
最も単純なバージョン(別のバージョンはそれ以下で、より高速だと思います):
def findPaths(G,u,n):
if n==0:
return [[u]]
paths = [[u]+path for neighbor in G.neighbors(u) for path in findPaths(G,neighbor,n-1) if u not in path]
return paths
これはネットワークG
とノードu
と長さを取りますn
。長さ n-1 のすべてのパスを、 をu
含まない隣接パスから開始して再帰的に検索しますu
。次に、そのような各パスの先頭に固執u
し、それらのパスのリストを返します。
各パスは順序付きリストであることに注意してください。それらはすべて指定されたノードから始まります。したがって、必要に応じて、これをループでラップするだけです。
allpaths = []
for node in G:
allpaths.extend(findPaths(G,node,3))
これには、任意のa-b-c-d
パスと逆のd-c-b-a
パスがあることに注意してください。
「リスト内包表記」を解釈するのが難しい場合は、同等のオプションを次に示します。
def findPathsNoLC(G,u,n):
if n==0:
return [[u]]
paths = []
for neighbor in G.neighbors(u):
for path in findPathsNoLC(G,neighbor,n-1):
if u not in path:
paths.append([u]+path)
return paths
これを最適化するために、特にサイクルが多い場合は、許可されていないノードのセットを送信する価値があるかもしれません。ネストされた呼び出しごとに、再帰に上位のノードを含めないことがわかります。これはif u not in path
チェックの代わりに機能します。コードを理解するのは少し難しくなりますが、実行速度は速くなります。
def findPaths2(G,u,n,excludeSet = None):
if excludeSet == None:
excludeSet = set([u])
else:
excludeSet.add(u)
if n==0:
return [[u]]
paths = [[u]+path for neighbor in G.neighbors(u) if neighbor not in excludeSet for path in findPaths2(G,neighbor,n-1,excludeSet)]
excludeSet.remove(u)
return paths
再帰呼び出しの前に追加u
してから、戻る前に削除する必要があることに注意してください。excludeSet
于 2015-01-23T05:41:24.437 に答える