Upgrade to Pro — share decks privately, control downloads, hide ads and more …

極小頂点被覆列挙問題を解く

Avatar for kaityo256 kaityo256 PRO
February 01, 2018

 極小頂点被覆列挙問題を解く

逆探索アルゴリズムに基づいて極小頂点被覆(Minimal Hitting Set)を効率的に列挙する方法の紹介。

Avatar for kaityo256

kaityo256 PRO

February 01, 2018
Tweet

More Decks by kaityo256

Other Decks in Programming

Transcript

  1. 3/30 数独と頂点被覆列挙問題 (2/4) 16ヒントの数独で解が一意になるものは存在しない There is no 16-Clue Sudoku [arXiv:1201.0749]

    数独の16ヒント定理 証明方法 ・数独の「答え」は有限個(自明な変換を除いて5,472,730,538個) ・それぞれの答えについて16ヒント問題を作る ・その全てについて解が一意でないことを示す 極小頂点被覆列挙問題 スパコンを使っても16ヒント問題を全て尽くすのは不可能 解が一意になる可能性がある問題を効率的に列挙したい (いわゆる「エレファントな証明」)
  2. 4/30 最小頂点被覆問題(1/3) 学校の開校問題 国語、算数、理科、社会、英語の五教科を教える学校を開校したい 教師候補は以下の五人 教師名 担当可能科目 給料(コスト) Alice 理科

    2 Bob 国語、社会 5 Carol 理科、社会、英語 10 Dave 国語、算数 6 Eve 算数、英語 8 教師候補を何人か雇って、五教科全てを教えられるようにしたい ただし、給料の総和は最小化したい
  3. 6/30 最小頂点被覆問題(3/3) Alice Bob Carol Dave Eve 国語 算数 理科

    社会 英語 Carol + Dave = 16 Bob + Carol + Eve = 23 Alice + Bob + Eve = 15 これが求める答え 極小頂点被覆 これを列挙したい
  4. 7/30 頂点被覆問題のグラフ表現 (1/2) Alice Bob Carol Dave Eve A B

    C D E Bob Carol Dave Eve Alice C A B E D 教師: 頂点(Vertex) 科目: 辺(Edge) グラフに書き直すことができる A: 国語 B: 数学 C: 理科 D: 社会 E: 英語
  5. 8/30 頂点被覆問題のグラフ表現 (2/2) Bob Carol Dave Eve Alice C A

    B E D Bob Carol Dave Eve Alice C A B E D Bob Carol Dave Eve Alice C A B E D 頂点被覆 全ての辺が選ばれた頂点のいずれかに所属するような頂点集合 極小頂点被覆 どの頂点が欠けても頂点被覆でなくなるような頂点集合
  6. 9/30 ヒッティングセット Simple Graph Hyper Graph Vertices Edges Vertices Hyper

    Edges 辺は必ず二点を繋ぐ 三点以上をつなぐ辺が存在 ヒッティングセット グラフにおける頂点被覆問題の拡張
  7. 10/30 頂点被覆列挙のビット表現 (1/3) 00100100 00011000 00010001 00110000 10000010 00000101 00010010

    00100001 00001001 87654321 グラフのビット表現 ≠ Adjacency matrix 各ビット列は辺を表現 その辺につながる頂点のビットが立っている
  8. 11/30 頂点被覆列挙のビット表現 (2/3) 00100100 00011000 00010001 00110000 10000010 00000101 00010010

    00100001 00001001 頂点被覆のビット表現 87654321 00010111 87654321 00010111 頂点被覆の条件 → 全ての辺のビット列と論理積(AND)をとってゼロではない 極小性の条件 → ひとつでもビットがかけたら頂点被覆でなくなる
  9. 12/30 頂点被覆列挙のビット表現 (3/3) 極小頂点被覆列挙とは 00100100 00011000 00010001 00110000 10000010 00000101

    00010010 00100001 00001001 00010111 00111110 10010101 10111100 00101011 00110011 10110001 グラフ Minimal Hitting Sets このビット列を入力とし このビット列を出力する問題 典型的なNP完全問題 ビット表現
  10. 13/30 ナイーブな実装 (1/2) 1 2 3 011 110 000 001

    010 101 011 010 ・入力のビット列をひとつずつチェック ・現在の状態と重なりがないビット列が出現したら、ビットのひとつを立てて再帰 入力グラフ ビット表現 1. 000からスタート 2. 000は011と重なりがない 3. 001を立てて次へ 4. 001と110は重なりがない 5. 110のうち、010を立てて次へ 6. 得られた011は極小でない 1 2 3 4 011 110 5 6 極小でない解や、重複解が出現してしまう 極小でない
  11. 14/30 ナイーブな実装 (2/2) 1 2 3 101 011 110 000

    100 001 110 101 001 101 011 101 011 110 101 110 左の入力からナイーブな再帰をすると 出力が重複する 重複
  12. 15/30 逆探索アルゴリズム(1/4) 極小頂点被覆列挙をナイーブな再帰で実装すると ・ 極小でないものが出現 ・ 重複する解が出現 これを解決するのが「逆探索アルゴリズム」 逆探索の考え方 1.

    解に階層を導入する 2. 異なる解に属す解に「親子関係」を定義する ・ ある子ノードの親は一意に決まるように定める ・ 自分自身が祖先に出現しないようにする 3. 階層を上に行くと答えが単純になり、自明な解が根(root)になるようにする 4. 根から親子木を逆にたどると答えを得る 親子関係が木になる 参考:宇野 毅明: 極小集合被覆を列挙する実用的高速アルゴリズム http://id.nii.ac.jp/1001/00031992
  13. 16/30 逆探索アルゴリズム(2/4) 部分被覆 ・入力のビット列がn個とする ・その1つ目からk個目までの部分集合を考える ・そのk個のビット列に対して極小頂点被覆であるものを k-極小頂点被覆(Minimal Hitting Set, MHS)と呼ぶ

    ・0-MHSからひとつずつ対応ビット列を増やして行く ・n-MHSが求める答え = {1 , 2 ,…, } 入力(辺)全体の集合 = {1 , 2 ,…, } 入力の部分集合 k-HS: k 頂点被覆 k-MHS: k 極小頂点被覆 についての頂点被覆 についての極小頂点被覆
  14. 17/30 逆探索アルゴリズム (3/4) いま、tがk-MHSであるとする時、tの親を生成する操作R(t)を 以下で定める R(t) = t ^ (t

    & e[k]) Reduction操作 t tが(k-1)-MHSの場合 そうでない場合(※) tは(k-1)-MHSではないので、あるビットを削っても、 はカバーできる tからビットを削って(k-1)-MHSにしたものをR(t)とする tはk-MHSであったから、ビットを削ったR(t)はk-MHSではない R(t)はk-MHSではないので、e[k]と交わりを持たせるにはビットを追加する必要があるが、 追加は1ビットで十分である したがって、tとR(t)の違いは1ビットであり、それはt&e[k]で求められる 以上からR(t) = t ^ (t & e[k])となる k-MHSの親が(k-1)-MHSとなるように定める あるノードの親を作る操作をReductionと呼ぶ −1 ※ tが(k-1)-MHSでないときのR(t)の求め方
  15. 18/30 逆探索アルゴリズム(4/4) 頂点被覆における親子木の例 000 100 001 110 001 101 011

    110 Reduction 自明な解 レベル0 レベル1 レベル2 レベル3 欲しい解 Enumeration 親 子 各レベルkではk-MHSが列挙されている
  16. 19/30 逆探索アルゴリズムの実装 (1/2) 1 2 3 011 110 000 001

    010 101 011 010 011 110 k-MHSの子供は必ず(k+1)-MHSでなければならない → 再帰してビットを追加したときに極小でなければ枝刈り 極小被覆でない解が取り除かれた 枝刈り
  17. 20/30 逆探索アルゴリズムの実装 (2/2) 1 2 3 101 011 110 000

    100 001 110 101 001 101 011 101 011 110 101 110 0-MHS 1-MHS 2-MHS 3-MHS k-MHSの子供は必ず(k+1)-MHSでなければならない 重複解が取り除かれた 2-MHSではない 枝刈り
  18. 21/30 極小性判定(1/6) 1. tから1-bit取り除いてみる 2. E_k 全てと重なりチェック 3. 全てのビットについて1.2.を繰り返す 4.

    1-bit削除したものがE_k全てと重なりを持てば極小でない 再帰してビットを追加したとき、極小性を満たさない場合は枝刈りする → t が k-MHSであるかチェックする必要がある(極小性判定) tに含まれるbit数がBの時、計算量はO(kB) bool check_minimal(mybit t, int k, mybits &e) { mybit v = t; while (v) { mybit t2 = v & -v;mybit t3 = t ^ t2; bool flag = true; for (int i = 0; i < k; i++) { flag &= ((e[i] & t3) != 0);if(!flag)break; } if (flag) return false; v = v ^ t2; } return true; } ナイーブな実装
  19. 22/30 極小性判定(2/6) Critical Hyperedge もしk-MHSのあるビットを削除した時に、ある辺との重なりがなくなったら、 その辺をそのビットのCritical hyperedge (CH)と呼ぶ 101 011

    110 Hypeedges 101 101 110 011 MHS Critical Hyperedge of this bit Critical Hyperedge of this bit tが極小頂点被覆であるなら、どのビットを削ってもカバーできない辺が出現する → tの全てのビットに最低ひとつはCHが存在する
  20. 23/30 極小性判定(3/6) 00010010 01100110 10110100 11011000 01000111 01010011 01100110 01010010

    01100110 10110100 11011000 01000111 01010011 01100110 minimal not-minimal 極小性条件 tを構成する全てのビットが、最低一つのCHを持つ時に限り、t はMHSとなる critical hyperedgeを持たないbitを持つ場合、極小ではない
  21. 24/30 極小性判定(4/6) 極小性条件判定 tを構成する全てのビットが最低一つの(CH)を持つ CHを持つビットにフラグを立てていく tを構成する全てのビットにフラグが立てばtは極小である ビット演算による実装 1. tと辺の論理積をとり、たっているビット数の数を数える 2.

    もし1ビットならその辺はCHであるので、そのビット位置を覚えておく 3. CHとtの重なりビット全ての論理和(OR)をとり、それをt’とする 4. もしt’==tなら、全てのビットがCHを持つのであるからtは極小である 5. そうでないならtは極小ではない
  22. 25/30 極小性判定(5/6) 00010010 01100110 10110100 11011000 01000111 01010011 01100110 00000010

    00010000 00010000 00000010 00000010 00010010 = 01010010 01100110 10110100 11011000 01000111 01010011 01100110 00000010 00010000 00010000 00000010 00000010 00010010 ≠ 極小性チェック 1. tと辺の論理積(AND)をとったとき、たっているビット数が1ビットな 2. その辺全ての論理和(OR)をとる 3. 結果がtに等しいとき、tは極小である 計算量がO(Bk)からO(k)に落ちる t’ t
  23. 26/30 極小性判定(6/6) bool check_minimal2(mybit t, int k, mybits &e) {

    mybit t2 = 0; for (int i = 0; i < k; i++) { if (popcnt(t & e[i]) == 1) { t2 = t2 | (t & e[i]); } } return (t2 == t); } bool check_minimal(mybit t, int k, mybits &e) { mybit v = t; while (v) { mybit t2 = v & -v;mybit t3 = t ^ t2; bool flag = true; for (int i = 0; i < k; i++) { flag &= ((e[i] & t3) != 0);if(!flag)break; } if (flag) return false; v = v ^ t2; } return true; } 最初の実装 改良された実装 tと1ビット重なりを持つe[i]全ての 論理和がtに一致するか調べる tから1ビット削ってみて、極小 性条件を満たすか調べる
  24. 27/30 実行時間 入力データ 32-bitのうち、ランダムに10bit 立っている 200行 全部でMHSは1352805個存在する これを列挙するのにかかった時間を計測 01010000100001111000000100001100 01000010010010010101010001000010

    10000000100100000100010011001011 01111010001000010000000101000010 00001110010010000100000100001110 10000100010001000010001011110000 10000010001010101011000000100010 10100100100111100010000000100000 ... 結果 Naïve way: Improved way: 3.621 [s] 2.396 [s] ちょっとだけ早くなった
  25. 28/30 UA sets (size 4) 不可避集合 (Unavoidable Sets, UA) UA

    sets (size 6) もし不可避集合に属すヒントを全て取り除いた場合、解が一意でなくなる集合 000000000000000000000000000000000000101000000000000000000000000000000000101000000 000000000000000000110000000000000000000000000000000000000000000000000000110000000 ... 100001001010001001000000000110000000000000000110000000110000000110000000000000000 100000001011000001010000100010000100001000001000000000111000000000000000000000000 000000001000001110001010110001001001010000100100100000001001001010010000100100000 UA sets Solution 解は必ず全ての不可避集合のビットと重なりを持つ (必要条件) 数独と頂点被覆列挙問題 (3/4) 5と9を入れ替えても数独として成立 → この4つを全て抜くと解が2つ出現
  26. 29/30 数独と頂点被覆列挙問題 (4/4) 不可避集合の活用 数独の解の一意性判定はコストが高い 不可避集合は、「答え」を与えると一意に決まる 全ての解は不可避集合と重なりを持っている 不可避集合を「解の一意性判定」の前処理に用いる 不可避集合と解候補 解が一意である場合、必ず全ての不可避集合と重なりを持つ

    不可避集合から、解の候補を列挙する 極小頂点被覆列挙 16ヒント定理証明の手続き 1. 数独の答えから、不可避集合を作成する 2. 不可避集合全てと重なりを持つ解候補を作成する(極小頂点被覆列挙) 3. ビット数が17以上なら枝刈り 4. 残った「解候補」についてまじめに解の一意性判定を行う 5. 以上を全ての「答え」について行う