再帰的擬似コードでは、2^nアルゴリズムは
GenerateAndTest(verticesNotYetConsidered, subsetSoFar):
if verticesNotYetConsidered is empty:
yield subsetSoFar if it induces a connected subgraph
else:
choose a vertex v in verticesNotYetConsidered
GenerateAndTest(verticesNotYetConsidered - {v}, subsetSoFar)
GenerateAndTest(verticesNotYetConsidered - {v}, subsetSoFar union {v})
どの頂点vが選択されているかは関係ありません。2つの兄弟呼び出しで異なる方法を選択することもできます。この自由度を利用して、再帰ツリーを枝刈りすることにより、ほぼ線形時間のアルゴリズム(解の数のn倍)を取得します。
が空の場合subsetSoFar
、選択肢はまだ制約されていません。v
それ以外の場合は、の頂点の1つに隣接することを選択しますsubsetSoFar
。そのようなものが存在しない場合、このサブツリーには他のソリューションがないため、v
降伏して戻ります。subsetSoFar
常に接続されている新しい不変条件に注意してくださいsubsetSoFar
。これにより、明示的な接続テストを排除できます。再帰ツリーの各ノードでO(n)作業を行います(単純にO(n ^ 2)ですが、隣接する頂点のセットを段階的に維持できます)。これは完全なバイナリであり、それぞれの葉が正確に1つの解を生成するため、合計作業は主張どおりです(内部ノードの数はリーフの数より1つ少ないことを思い出してください)。
新しい不変量のため、切断されたサブグラフは生成されません。
接続された各サブグラフが生成されます。接続された部分グラフを誘導する頂点Sのセットについては、Sに一致する分岐をたどります。Sの適切なサブセットが残りのSに隣接しないことは不可能であるため、Sは剪定されません。
新しい擬似コードは次のとおりです。N(v)
のネイバーのセットを示しv
ます。
GenerateConnectedSubgraphs(verticesNotYetConsidered, subsetSoFar, neighbors):
if subsetSoFar is empty:
let candidates = verticesNotYetConsidered
else
let candidates = verticesNotYetConsidered intersect neighbors
if candidates is empty:
yield subsetSoFar
else:
choose a vertex v from candidates
GenerateConnectedSubgraphs(verticesNotYetConsidered - {v},
subsetSoFar,
neighbors)
GenerateConnectedSubgraphs(verticesNotYetConsidered - {v},
subsetSoFar union {v},
neighbors union N(v))
編集:最大次数O(1)のグラフの場合verticesNotYetConsidered intersect neighbors
、明確にするために私がしなかったを維持することによって、これを真に線形な時間にすることができます。グラフを隣接行列として表現することで単語の並列処理を活用する場合、この最適化はおそらくあまり価値がありません。隣接行列では、各行が1語または2語のビットマップとして格納されます。