極小集合被覆を列挙する
実用的高速アルゴリズム
宇野 毅明
国立情報学研究所
2002年3月 アルゴリズム研究会
極小集合被覆とは
・ E : 台集合
・ F ⊆ 2E : 集合族
・ C ⊆ F が F の集合被覆 ⇔ ∀e ∈ E , ∃S∈ C, e ∈ S
極小集合被覆 : 他の集合被覆を含まない集合被覆
E = {1,2,3,4,5,6}
F = {{1,2,3} , {1,4,5,6}, {1,3,5}, {2,4}, {5,6}}
集合被覆:
{1,2,3
},
{1, 3, 5 },
{ 2, 4 },
{
5,6}
極小集合被覆:
{1,2,3
}
{1, 4,5,6}
極小集合被覆列挙問題
問題: 与えられた E , F ⊆ 2E に対して, F の極小集合被覆
を全て出力せよ
・ #P-complete である
・ 出力多項式のアルゴリズムがあるかどうか不明
・ 他のいろいろな問題と等価
(hypergraph dualization, minimal hitting set の列挙)
・ いろいろな人がチャレンジしている
・ 現在, 計算量の意味での最速なものは O(出力数 log 出力数)
・ 実用上高速なアルゴリズムを作る研究も行われている
( Kavvadias & Stavropoulos ’99)
今回の研究: ↑のアルゴリズムを高速化
どうやって列挙するか?
・ 一般に良く使われる列挙法 : 分割法
解集合を2分割し, 各々を子問題として再帰的に解く
ただし
・ 空集合と全体集合, という分割をしないこと
(子問題の解の存在性をチェックできること)
・ 再帰的に子問題が作成できること
簡単に,
「 ある S を含む極小集合被覆」
「 ある S を含まない極小集合被覆」
と分割すると, 前者が子問題として
表現できない(あるいは重なる)
.
.
.
.
無駄な出力の回数を解析  現在の計算量最速アルゴリズム
他のアプローチ
台集合 E = {e1,…,en} を限定した問題を逐次解く方法
・ 最初 E1 = {e1} として問題を解く
・ 得られた解集合から, E2 = {e1,e2} の解集合を得る
・ 逐次 E を大きくしていき, 解集合を更新し, En={e1,…,en}
の解集合を得る
…
E1 ={e1}
E2 ={e1,e2} ,…, En-1 ={e1,…,en-1} E ={e1,…,en}
問題点 : メモリを沢山消費
Kavvadias & Stavropoulos はメモリを使わないように改良
逆探索
Kavvadias & Stavropoulos の方法は, 逆探索として捉えら
れる
・ (特別なある一つの要素以外の)任意の解に, 親(他の
解)を定義
・ ただし, 各解が自分自身の真の先祖にならないこと
・ 親子関係から木(列挙木)が得られる
列挙木を深さ優先探索
・ 解を列挙するには, 列挙木を深さ優先探索すればよい
・ 列挙木全体を記憶しなくても, 現在の解の子供を列挙する
アルゴリズムがあれば十分
・ 入力多項式のメモリしかいらない(木の高さが入力多項式
なら)
(・ さらに, 子供に順序付けをして, 与えられた子供の次の子
供を見つけるアルゴリズムがあると, 木の深さもメモリに
影響しない)
極小集合被覆間の親子関係
E0 ,…, En のすべての極小集合被覆に定義
( Ei の極小集合被覆 C を ( i ,C ) と表記する)
( E0 の極小集合被覆は( 0, φ) のみとする)
・極小集合被覆 ( i ,C ) に対して,
1. C がEi-1 の極小集合被覆ならば, ( i-1 ,C ) を親とする
2. そうでないなら, C から( ei を含む集合) を取り除いたもの
を C’ として, ( i-1 ,C’ ) を親とする
i=6
{1,2
},
{ 3, 5 },
{ 2, 4, 6},
{1,2,3
}
{1, 4,5 }
{1, 3, 5,6}
親子関係の妥当性
集合被覆 C がEi の極小集合被覆である ⇔ C の各集合 S に対
して, Ei の要素で S にしか覆われていないものが存在する
(S のクリティカル要素と呼ぶ)
極小集合被覆 ( i ,C ) に対して, C がEi-1 の極小集合被覆でない
 C のある集合 S のクリティカル要素は ei のみであり, C の他の
集合のクリティカル要素は eiではない
 C から S を除くと極小集合被覆になる
{1,2,3
}
{
3, 5 }
{ 2, 4, 6}
{1,2,3
}
{1, 4,5 }
{1, 3, 5,6}
親から子供を得るには
・ 親の定義の逆をすればよい
・ 任意の ( i ,C ) に対して,
1. もし C がEi+1 の極小集合被覆ならば, ( i +1,C ) は子供
⇔ ( C はEi の極小集合被覆なので ( i ,C ) は( i +1,C ) の親 )
2. C がEi+1 の極小集合被覆でないときは,
C ∪{ S’ =( ei+1 を含む集合)} が Ei+1 の極小集合被覆ならば,
( i +1, C ∪{ S’ } ) は子供
⇔ ( C ∪{ S’ } はEi の極小集合被覆でないので
S’ を取り除いて得られる ( i ,C ) が親 )
・ 子供は最大 |F| 人. 必ずいるとは限らない
計算量は押さえられない
・ 1反復は入力多項式時間. 反復の総数は,
(全ての Ei 上の, 極小集合被覆数の総和)
・ 出力数多項式時間にはならない
・ En 上の解集合に比べて
Ei 上の解集合が極端に大きくなるとは考えにくい
 たぶん, 実際はかなり速い(出力数多項式)だろう
高速化をして、実際どの程度速くなるか検証する
反復の高速化(改良1)
・ C ∪ {S’} の極小性チェックに時間がかかっている
・ 各反復で, 極小集合被覆 C に対し,
各 S∈C に対し, S のクリティカル要素 ( S しか覆ってない要素
の集合) c(S) を記憶
c(S) ⊆ S’ となる S ∈C が存在しなければ, C ∪ {S’} は極小
{ 1, 2, 3,7 }, { 1, 2, 4 }, { 5,6 }
・ { 3,5,7,8 } は加えられない
・{ 1,2,3,5,8 } は加えられる
普通にチェック O(|E||F|)  この方法 O(|E|)
( 計算結果から推測するに, Kavvadias & Stavropoulos は普通
にチェック、の方法を用いているようだ)
反復の高速化(改良2)
c(S) ⊆ S’ となる S ∈C が存在しなければ, C ∪ {S’} は極小
 チェックは c(S) に含まれる部分だけでよい
(計算結果を見ると、 各 S に含まれるクリティカル要素は, 通常
とても少ない(定数個)のようなので )
/ の要素で, いずれかの c(S), S ∈C に含まれるものを保
各 S’ ∈C
持
(反復の操作ごとに変更, 更新する. O(|F|) 時間程度)
順番を入れ替えて高速化
・ E = { e1,…, en } の添え字を各要素を含む集合の数でソー
トする
小さい順

反復数が減るだろう
大きい順

各反復の計算時間が減るだろう
さて, どっちが速い?
計算機実験
環境 : Pentium Ⅲ 500MHz, linux, 普通の C でプログ
ラムを作り, gcc でコンパイルした
問題生成法 : 各要素が, 各集合に含まれる確率が3割
として生成
※ 解が100万以上のときは100万個出力したところで打
ち切る
実験結果の概略
計算時間/出力数
改良1: O(|E|) より少々大きい
改良2: O(|E|) 程度
前の論文の結果: O(|E|2) より小さい程度
・ 集合族の大きさは少ししか計算時間に関係しないようだ
※ 各反復で, 子供候補のうち, だいたい一定割合が子供になって
いるのだろう
※ 深い反復での, 各集合が含むクリティカル要素数は, ほぼ定数
であったので, 改良2が速いのだろう
・ ランダム:小さい順:大きい順 = (およそ) 1 : 0.7 : 2.0
※ 各集合の大きさの偏りを増やすと, この比は大きくなる
 反復数を減らしたほうが効果は高いようだ
700
600
500
400
300
200
100
0
集合族の大きさを固定
396
425
455
486
274
304
335
365
243
182
212
350
300
250
200
150
100
50
0
台集合の大きさ
台集合の大きさを固定
455
396
335
274
212
151
90
改良1|E|=50
改良1|E|=500
改良2|E|=50
改良2|E|=500
30
計算時間
前の論文:
|E|=50,
|F|=50
で
500秒
程度
121
151
改良1|F|=50
改良1|F|=500
改良2|F|=50
改良2|F|=500
30
60
90
計算時間
改良 1 と改良 1+2 の比較
集合族の大きさ
添え字の順序を並び替えた場合
1000
集合族の大きさを固定
少ない順
多い順
ランダム
600
400
200
455
396
335
274
212
151
90
0
台集合の大きさ
100
台集合の大きさを固定
80
少ない順
多い順
ランダム
60
40
20
455
396
335
274
212
151
90
0
30
計算時間
30
計算時間
800
集合族の数
48214
44562
37257
40909
29952
33604
22647
26299
15342
18994
11689
4384
8037
7000
6000
5000
4000
3000
2000
1000
0
732
計算時間
さらに大きな台集合で
前の論文: |E| = 1000 で 20000秒くらい
台集合の
大きさ
まとめと今後の課題
・ 極小集合被覆列挙問題に対して, 実験的に高速なアルゴリズ
ムを提案した
・ ランダム問題に対する計算実験の結果, 入力 E , F ⊆ 2E に対
する計算時間は, 1つあたりおよそ O(|E|) であった
・ 添え字の付け方を工夫すると, 出力数多項式オーダーになるか
もしれない
( ・実は, もうひとつ改良を試してみたのだが, 速くならなかった)
・ 解1つあたり O(1) 程度の時間にできるかどうかが今後の課題
ダウンロード

power point