900 likes | 1.42k Views
フロンティア法 - 組合せ問題の解を列挙索引化する ZDD 構築アルゴリズム. 川原 純. 科学技術振興機構 ERATO 湊離散構造処理系プロジェクト. 北海道大学 情報科学研究科. 講義 の目標. パスの数え上げアルゴリズムを理解する 大規模データを扱うためのデータ構造の 1 つ 「 ZDD 」 についてより詳しく知る 大規模データの保存、 活用 様々な対象を表現する ZDD を高速に構築する手法 「フロンティア法」 アルゴリズムを理解する 適用事例について知る. ZDD: 集合の集合を表現するデータ構造.
E N D
フロンティア法 - 組合せ問題の解を列挙索引化するZDD構築アルゴリズム 川原 純 科学技術振興機構 ERATO湊離散構造処理系プロジェクト 北海道大学 情報科学研究科
講義の目標 • パスの数え上げアルゴリズムを理解する • 大規模データを扱うためのデータ構造の1つ 「ZDD」 についてより詳しく知る • 大規模データの保存、活用 • 様々な対象を表現するZDDを高速に構築する手法 「フロンティア法」 アルゴリズムを理解する • 適用事例について知る
ZDD: 集合の集合を表現するデータ構造 (Zero-suppressed Binary Decision Diagram) [S.Minato 93] e5 e5 e2 e1 e4 e2 { } { } { { } , , e5 e4 e5 e3 e3 e5 { } { } } { } , , e5 e3 e4 e2 e1 0 1 集合の集合 0 1 ZDD
ZDD: 集合の集合を表現するデータ構造 e5 e5 e2 e1 e4 e2 { } { } { { } , , e5 e4 e5 e3 e3 e5 { } { } } { } , , e5 e4 e3 e2 e1 0 1 集合の集合 0 1 0 1 : 0 終端 それぞれ1つずつもつ : 1 終端 ZDD e1 e5 ei ~ : ノード いずれかのラベル , e5 , e2 e1 ,… の順序
ZDD: 集合の集合を表現するデータ構造 ノードは0枝と1枝を1つずつもつ e5 e5 e2 e1 e4 e2 { } { } { { } , , e5 e4 e5 e3 e3 e5 { } { } } { } , , e5 e4 e3 e2 e1 0 1 集合の集合 0 1 0 1 : 0 終端 それぞれ1つずつもつ : 1 終端 ZDD e1 e5 ei ~ : ノード いずれかのラベル , e5 , e2 e1 ,… の順序
ZDD: 集合の集合を表現するデータ構造 ノードは0枝と1枝を1つずつもつ e5 e5 e2 e1 e4 e2 { } { } { { } , , e5 e4 e5 e3 e3 e5 { } { } } { } , , e5 e4 e3 e2 e1 0 1 集合の集合 1 0 1 0 1つの集合が、 top から までの1本のパスに対応 1 ZDD : 0 終端 それぞれ1つずつもつ : 1 終端 ei e1 e5 : ノード ~ いずれかのラベル
ZDD: 集合の集合を表現するデータ構造 ノードは0枝と1枝を1つずつもつ e5 e5 e2 e1 e4 e2 { } { } { { } , , e5 e4 e5 e3 e3 e5 { } { } } { } , , e5 e4 e3 e2 e1 0 1 集合の集合 1 0 1 0 1つの集合が、 top から までの1本のパスに対応 1 ZDD : 0 終端 それぞれ1つずつもつ : 1 終端 ei e1 e5 : ノード ~ いずれかのラベル
ZDD: 集合の集合を表現するデータ構造 ノードは0枝と1枝を1つずつもつ e5 e5 e2 e1 e4 e2 { } { } { { } , , e5 e4 e5 e3 e3 e5 { } { } } { } , , e5 e4 e3 e2 e1 0 1 集合の集合 1 0 1 0 1つの集合が、 top から までの1本のパスに対応 1 ZDD : 0 終端 それぞれ1つずつもつ : 1 終端 ei e1 e5 : ノード ~ いずれかのラベル
ZDDの性質 0 1 0 1 e5 e5 e4 e3 e4 e3 e2 e2 e2 e1 e1 0 1 1 0 等価な2つのノードは必ず共有される
パスは辺の集合で表現できる e1 e4 s t e3 e2 e5 e1 e1 e4 e4 s s t t e3 e3 {e1,e4} {e2,e5} e2 e2 e5 e5 e1 e1 e4 e4 s t s t e3 e3 {e2,e3 ,e4} {e1,e3 ,e5} e2 e2 e5 e5
パスは辺の集合で表現できる e1 e4 全ての s-t パスを列挙して、 s t e3 辺集合の集合で表す e2 e5 e1 e1 e4 e4 s s t t e3 e3 {e1,e4} {e2,e5} e2 e2 e5 e5 e1 e1 e4 e4 s t s t e3 e3 {e2,e3 ,e4} {e1,e3 ,e5} e2 e2 e5 e5
パスは辺の集合で表現できる e1 e4 全ての s-t パスを列挙して、 s t e3 辺集合の集合で表す e2 e5 {e2,e3 ,e4}} {e2,e5}, {e1,e3 ,e5}, {{e1,e4}, all s-t path = e1 e1 e4 e4 s s t t e3 e3 {e1,e4} {e2,e5} e2 e2 e5 e5 e1 e1 e4 e4 s t s t e3 e3 {e2,e3 ,e4} {e1,e3 ,e5} e2 e2 e5 e5
Knuth のパス列挙アルゴリズム 全 s-t パスを表現する ZDD をトップダウン的に構築 ZDD
パス列挙(ZDD構築)アルゴリズム [Knuth 08] e1 e4 e1= 1 e1= 0 s t e3 e2= 0 e2= 1 e2= 1 e2= 0 e2 e5 1 0 1. 辺に順番を付ける (例えば、s から幅優先) e4 e2 e2 e3 e3 e3 e3 e1 e5 (もっと良い方法もあり) 2. ZDDを構築 s-t パスになっている 辺 e1,e2,… の順に処理 e1 e4 各辺変数ei に対し、 ei = 0 or 1 を決めていく 1 s t e3 e2 e5 ei = 1 である辺が s-t パスになっているか?
パス列挙(ZDD構築)アルゴリズム [Knuth 08] e1 e4 e1= 1 e1= 0 s t e3 e2= 0 e2= 1 e2= 1 e2= 0 e2 e5 1 0 1. 辺に順番を付ける (例えば、s から幅優先) e4 e2 e3 e3 e1 e3 e2 e3 e5 (もっと良い方法もあり) 2. ZDDを構築 s-t パスに なっていない s-t パス + 余分な辺 辺 e1,e2,… の順に処理 e1 e1 e4 e4 各辺変数ei に対し、 ei = 0 or 1 を決めていく 0 0 s s t t e3 e3 e2 e2 e5 e5 ei = 1 である辺が s-t パスになっているか?
パス列挙(ZDD構築)アルゴリズム [Knuth 08] e1 e4 e1= 1 e1= 0 s t e3 e2= 0 e2= 1 e2= 1 e2= 0 e2 e5 1 0 1. 辺に順番を付ける (例えば、s から幅優先) e4 e2 e1 e3 e3 e2 e3 e3 e5 (もっと良い方法もあり) 2. ZDDを構築 1 他は0 辺 e1,e2,… の順に処理 各辺変数ei に対し、 ei = 0 or 1 を決めていく が1つのパスに対応 1 1 1 1
パス列挙(ZDD構築)アルゴリズム [Knuth 08] e1 e3 e1= 1 e1= 0 t s e2= 0 e2= 1 e2= 1 e2= 0 e4 e2 e2 e2 e3 e3 e1 e3 1 1 0 1 0 1 0 0
パス列挙(ZDD構築)アルゴリズム [Knuth 08] e1 e3 e1= 1 e1= 0 t s e2= 0 e2= 1 e2= 1 e2= 0 e4 e2 e3 e2 e1 e3 e2 e3 0 1 1 0 1 0 1 0 ノードを共有できるときは共有したい ただし、子DAGを作成せずに、共有可能か判定を行う
e1 e3 パス列挙(ZDD構築)アルゴリズム [Knuth 08] t s e4 e2 e1= 1 e1= 1 e1= 0 e1= 0 e2= 0 e2= 0 e2= 1 e2= 1 ? 途中の経路は分からないが s につながっていることは分かっている
パス列挙(ZDD構築)アルゴリズム [Knuth 08] … … t s 未処理辺 処理済み辺 t フロンティア
パス列挙(ZDD構築)アルゴリズム [Knuth 08] d a f c b h g … … t s f f d d d d a a s s t t s s f f c c t b b h h g g
パス列挙(ZDD構築)アルゴリズム [Knuth 08] d f a d d f a s c t b s h f g c b h g … … t s f f d d d d a a s s t t s s f f c c t b b h h g g
パス列挙(ZDD構築)アルゴリズム [Knuth 08] 接続情報の記憶法 d 頂点がパスの端 a … a t 逆端の頂点 s f b s c … b h 頂点がパスの途中 g 0 頂点がいずれの パスにも含まれない a b v d f g v 自身の頂点 mate[v] mate[v] a 0 f d s mate 配列
a パス列挙(ZDD構築)アルゴリズム [Knuth 08] e1 e5 s t e3 e2 mate 値 a s e6 b e4 s a c a a b s s b a b a s s 0 s 0 b a s s 0 s s c s c
a パス列挙(ZDD構築)アルゴリズム [Knuth 08] e1 e5 s t e3 e2 mate 値 a s e6 b e4 s a c a a b s s b a b a s s 0 s 0 b a s 0 s s s c
a パス列挙(ZDD構築)アルゴリズム [Knuth 08] e1 e5 s t e3 e2 e6 b e4 c 0 s a s c s 0 a t c s s
a パス列挙(ZDD構築)アルゴリズム [Knuth 08] e1 e5 s t e3 e2 e6 b e4 c 0 s a s c s 0 a t 1 c s s 1 1
a パス列挙(ZDD構築)アルゴリズム [Knuth 08] e1 e5 s t e3 e2 e6 b e4 c 0 s a 根から までの 1つの経路が 1つのs-t パスに 対応する s c s 0 a t 1 c s s 1 1 1
パス列挙(ZDD構築)アルゴリズム [Knuth 08] mate 配列の更新例 a a g g b b s s c c d d f f a b c d f v a b c d f g v mate[v] c 0 a d s mate[v] 0 0 g d s c
パス列挙(ZDD構築)アルゴリズム [Knuth 08] mate 配列の更新 一般に a b c d c d a b a b c d 0 0 d c 最大4か所書きかえれば更新できる a c d b
枝刈り a a g g b b s s c c d d f f 0
枝刈り a a g g b b s s c c d d f f 0
枝刈り a a g g b b s s c c d d t t f f 0
枝刈り a a g g b b s s c c d d t t f f 1
終端判定条件 p 辺 e を処理する前の判定 q if x = 1 if GetDegree(p) = 2 or GetDegree(q) = 2 終端 if (p = s or p = t) and GetDegree(p) = 1 終端 GetDegree(v) if (q = s or q = t) and GetDegree(q) = 1 if mate[v] == v 終端 return 0 if mate[p] = q and mate[q] = p if mate[v] == 0 終端 return 2 if mate[p] = s and mate[q] = t or else mate[p] = t and mate[q] = s return 1 for each vertex v in the frontier if v != s or v != t or v!= p or v!= q if GetDegree(v) = 1 終端 end for 0 1 0 0 0 0 終端 end if
辺 e を処理した後の判定 for each v such that v がフロンティアから外れる if v = s or v = t if GetDegree(v) = 0 GetDegree(v) 終端 if mate[v] == v return 0 else if GetDegree(v) = 1 if mate[v] == 0 return 2 終端 else return 1 a a g g b b s s c c 0 0 d d f f
e1 e3 s 12 パスの数え上げ e5 e2 e4 e8 e6 6 6 e10 e9 e7 6 6 t e11 e12 4 3 3 2 4 3 3 2 4 3 3 2 1 1 1 2 2 2 2 1 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
s 実験結果 n ×n グリッド t 頂点の数 (n + 1) ×(n + 1) ・・・ The On-Line Encyclopedia of Integer Sequence (OEIS) : 数列大辞典 ・・・ http://oeis.org/A007764 ・・・ ・・・ ・・・ ・・・ ・・・
s 実験結果 n ×n グリッド t 頂点の数 (n + 1) ×(n + 1) ・・・ The On-Line Encyclopedia of Integer Sequence (OEIS) : 数列大辞典 ・・・ http://oeis.org/A007764 ・・・ ・・・ ・・・ ・・・ ・・・
s 実験結果 n ×n グリッド t 頂点の数 (n + 1) ×(n + 1) ・・・ ・・・ ・・・ ・・・ ・・・ ・・・ ・・・ Thanks to 岩下洋哲氏
実験結果 日本地図グラフ 北海道から鹿児島までの全パス 14797272518 本 5039760385115189594214594926092397238616064 本 (= 503正9760澗3851溝1518穣9594杼2145垓9492京6092兆3972億3861万6064)
講義の目標 • パスの数え上げアルゴリズムを理解する • 大規模データを扱うためのデータ構造の1つ 「ZDD」 についてより詳しく知る • 大規模データの保存、活用 • 様々な対象を表現するZDDを高速に構築する手法 「フロンティア法」 アルゴリズムを理解する • 適用事例について知る
ZDD と集合族 集合の集合(集合族)は ZDD で効率よく保持できる 1 0 b c c d d c b a d {{a, b, c, d}, {a, c}, {b, d}, {b, c, d}} 1 1 1 0 1 は省略
ZDD と集合族 集合族への操作例: a を含む集合だけを取り出し、a を消去する {{b, c, d}, {c}} {{a, b, c, d}, {a, c}, {b, d}, {b, c, d}} a を含まない集合だけ 取り出すなら、LO 枝側を もってこればよい 1 0 c b c d c a d d b c d c b 1 1 1 1 1 1 トップの要素なら簡単にできる
ZDD と集合族 集合族への操作例: c を含む集合だけを取り出し、c を消去する {{a, b, d}, {a}, {b, d}} {{a, b, c, d}, {a, c}, {b, d}, {b, c, d}} 1 0 1 0 c d b c d a b c a b d b d d c c c 1 1 1 1 1 1 1 d 1 トップでなければ、その変数の深さまで潜って、 枝の付け替えを行う
ZDD と集合族 集合族への操作例: c を含む集合だけを取り出し、c を消去する {{a, b, d}, {a}, {b, d}} {{a, b, c, d}, {a, c}, {b, d}, {b, c, d}} c を含まない集合だけ 取り出すなら、LO 枝の 方に付け替えればよい 1 0 1 0 c d b c c a d d b b d a b c c c 1 1 1 1 1 d d 1 1 1 トップでなければ、その変数の深さまで潜って、 枝の付け替えを行う
ZDD と集合族 集合族への操作例: 集合族 F から要素 xを含む集合だけを取り出し、x を消去する F / x 集合族 F から要素 xを含まない集合だけを取り出し、x を消去する F % x {{a, b, c, d}, {a, c}, {b, d}, {b, c, d}} abcd + ac + bd + bcd = (abd + a + bd) c + bd c を含む集合だけを取り出し、c を消去する (abcd + ac + bd + bcd ) / c = abd + a + bd c を含む集合だけを取り出し、c を消去する (abcd + ac + bd + bcd ) % c = bd
ZDD と集合族 集合族への操作例: aを各要素に追加する {{a, b, c, d, e}, {a, b, d}, {a, c, e}, {a, c, d}} {{b, c, d, e}, {b, d}, {c, e}, {c, d}} c c b c d e d e d d a e e b c d e e d 1 0 1 1 1 1 1 1 1 1 トップに加える場合