# Incremental Connected Components

この章は、無向グラフの連結成分を計算するために一緒に機能する関数とクラスの 一群を記述する。ここで用いられているアルゴリズムは、グラフが増大 (辺が付け加えられる) し、連結成分情報が繰り返し更新される必要がある ような状況に使うとよい方法である、素集合 (高速 union-find) データ構造 [8,27] に基づくものである。 この方法はグラフに辺が追加され、かつグラフから辺が削除されるような状況を 扱わない。それゆえ incremental[42] (そして完全に 動的ではない) と呼ばれる。素集合クラスは Disjoint Sets 節の中で 述べられている。

次に述べる 5つの操作は、連結成分を計算し、維持するために用いる主要な関数 である。ここで使われているオブジェクトは、グラフ `g`、素集合構造 `ds`、そして頂点 `u` と `v` である。

- `initialize_incremental_components(g, ds)`
  素集合構造の基礎初期化。グラフ `g` 中の各頂点はそれ自身の集合の中に 入る。
- `incremental_components(g, ds)`
  連結成分はグラフ `g` 中の辺に基づいて計算され、情報は `ds` に挿入される。
- `ds.find_set(v)`
  頂点 `v` の成分情報を素集合から取り出す。
- `ds.union_set(u, v)`
  辺 (u,v) がグラフに追加された時に素集合を更新する。

### Complexity

全ての処理の時間複雑性は E が処理終了時のグラフ中の全辺数で、 Vが頂点数である時 O(V + E alpha(E,V)) である。 alpha は爆発的再帰的に指数的増加をするアッカーマン関数の逆関数である。 それゆえこの逆関数はとてもゆっくり増加する。全ての現実的な目的にとって alpha(m,n) <= 4 であり、これは時間複雑性が O(V + E) より わずかに大きいだけである事を意味する。

### Example

素集合データ構造を使いながら辺を付け加える間、グラフの連結成分を維持する。 これの完全なソース・コードは `examples/incremental_components.cpp` にある。

      // グラフを作成する
      typedef adjacency_list <vecS, vecS, undirectedS> Graph;
      typedef Graph::vertex_descriptor Vertex;
      const int N = 6;
      Graph G(N);
      add_edge(0, 1, G);
      add_edge(1, 4, G);

      // 素集合構造を作成する。これはランクと、
      // 親頂点プロパティを必要とする。
      std::vector<Vertex> rank(num_vertices(G));
      std::vector<Vertex> parent(num_vertices(G));
      typedef std::vector<Graph::size_type>::iterator Rank;
      typedef std::vector<Vertex>::iterator Parent;
      disjoint_sets<Rank, Parent> ds(rank.begin(), parent.begin());

      // 連結成分を決定する。
      // 結果は素集合構造の中に挿入される。
      initialize_incremental_components(G, ds);
      incremental_components(G, ds);

      Graph::edge_descriptor e;
      bool flag;

      // 2、3個の辺を付け加え、素集合を更新する。
      tie(e,flag) = add_edge(4, 0, G);
      ds.union_set(4,0);

      tie(e,flag) = add_edge(2, 5, G);
      ds.union_set(2,5);

      cout << "An undirected graph:" << endl;
      print_graph(G, get(vertex_index, G));
      cout << endl;

      Graph::vertex_iterator i,end;
      for (tie(i,end) = vertices(G); i != end; ++i)
        cout << "representative[" << *i << "] = " <<
          ds.find_set(*i) << endl;;
      cout << endl;

      typedef component_index<int> Components;
      Components components(parent.begin(), parent.end());

      for (Components::size_type i = 0; i < components.size(); ++i) {
        cout << "component " << i << " contains: ";
        Components::value_type::iterator
          j = components[i].begin(),
          jend = components[i].end();
        for ( ; j != jend; ++j)
          cout << *j << " ";
        cout << endl;
      }

## `initialize_incremental_components`

グラフ: | 無向
プロパティ: | ランク、親 (素集合中の)
複雑性: |

    template <class VertexListGraph, class DisjointSets>
    void initialize_incremental_components(VertexListGraph& G, DisjointSets& ds)

これはグラフ中の各頂点をそれ自身の成分または集合のメンバにする 増分連結成分アルゴリズムのための素集合データ構造を用意する。

### Where Defined

`boost/graph/incremental_components.hpp`

## `incremental_components`

グラフ: | 無向
プロパティ: | ランク、親 (素集合中の)
複雑性: | O(E)

    template <class EdgeListGraph, class DisjointSets>
    void incremental_components(EdgeListGraph& g, DisjointSets& ds)

この関数はグラフの連結成分を、結果を素集合データ構造の中に挿入しながら 計算する。

### Where Defined

`boost/graph/incremental_components.hpp`

### Requirements on Types

- グラフの型は EdgeListGraph のモデルで なければならない。

## `same_component`

プロパティ: | ランク、親 (素集合中の)
複雑性: | O(alpha(E,V))

    template <class Vertex, class DisjointSet>
    bool same_component(Vertex u, Vertex v, DisjointSet& ds)

この関数は `u` と `v` が同じ成分中にあるかどうか決定する。

### Where Defined

`boost/graph/incremental_components.hpp`

### Requirements on Types

- `Vertex` はランク及び `DisjointSets` データ構造の親プロパティ・ マップと互換性がなければならない。

## `component_index`

    component_index<Index>

これはグラフの成分に STL コンテナに似た外観を提供するクラスである。 各成分はコンテナに似たオブジェクトで、`component_index` オブジェクトは `operator[]` による成分オブジェクトへのアクセスを提供する。 `component_index` オブジェクトは `incremental_components()` 関数 から計算される素集合中の親プロパティによって初期化される。

### Where Defined

`boost/graph/incremental_components.hpp`

### Members

メンバ | 説明
--- | ---
`size_type` | 成分数を表現するための型。
`value_type` | 成分オブジェクトのための型。成分の型は以下のメンバを持つ。
`value_type::value_type` | 成分オブジェクトの値型は頂点IDである。
`value_type::iterator` | このイテレータは成分中の頂点の全てを一巡するのに使える。このイテレータは 頂点IDを与える参照外しをする。
`value_type::const_iterator` | constイテレータ。
`value_type::iterator value_type::begin() const` | 成分中の最初の頂点を指すイテレータを返す。
`value_type::iterator value_type::end() const` | 成分中の最後の頂点の末尾の直後 (訳注: past-the-end) を指すイテレータを返す。
`template <class ComponentsContainer> component_index(const ComponentsContainer& c)` | `connected_components_on_edgelist` の実行結果である成分コンテナ `c` からの情報を用いて `component_index` を構築する。
`value_type operator[](size_type i)` | グラフ中の `i` 番目の成分を返す。
`size_type component_index::size()` | グラフ中の成分数を返す。

Copyright © 2000-2001 | Jeremy Siek, Indiana University (jsiek@osl.iu.edu) Lie-Quan Lee, Indiana University (llee@cs.indiana.edu) Andrew Lumsdaine, Indiana University (lums@osl.iu.edu)

Japanese Translation Copyright © 2003 Takashi Itou
オリジナルの、及びこの著作権表示が全ての複製の中に現れる限り、この文書の複製、利用、変更、販売そして配布を認める。このドキュメントは「あるがまま」に提供されており、いかなる明示的、暗黙的保証も行わない。また、いかなる目的に対しても、その利用が適していることを関知しない。

このドキュメントの対象: Boost Version 1.30.0
最新版ドキュメント (英語)