zdd を用いたパスの列挙と索引生成
DESCRIPTION
ZDD を用いたパスの列挙と索引生成. (JST ERATO 研究員 ) (JST ERATO 研究員 ) (JST ERATO 研究員 ). 川原 純 斎藤 寿樹 湊 真一 吉仲 亮. ○. ( 北海道大学・ JST ERATO 総括 ). (50 音順 ). 他、関わっている人. 井上 武 (ERATO) 、 岩下 洋哲 (ERATO ) 、 鈴木 拡(北海道大学)、 鶴間 浩二 (ERATO). パスの列挙. 入力:グラフ G =( V , E ) , 2 頂点 s , t 出力: s から t へ の 全て のパス. s. - PowerPoint PPT PresentationTRANSCRIPT
ZDD を用いたパスの列挙と索引生成
○ 川原 純 斎藤 寿樹 湊 真一 吉仲 亮
(JST ERATO 研究員 )(JST ERATO 研究員 )
(JST ERATO 研究員 )( 北海道大学・ JST ERATO 総括 )
他、関わっている人井上 武 (ERATO) 、岩下 洋哲 (ERATO) 、鈴木 拡(北海道大学)、鶴間 浩二 (ERATO)
(50 音順 )
応用• 地理情報処理
• ネットワークや論理回路の信頼性評価
• ソフトウェアのフローチャートを網羅するテストケース作成
• Fisher’s Exact Test (統計の分野)
(故障検査)
他にもたくさん
既存研究と関連研究• 既存研究– バックトラックを用いたアルゴリズム
• 一つあたり O(|V| + |E|) 時間 [Read and Tarjan, 75]
• 関連研究– パスの数え上げ
• #P 完全問題• Bax のアルゴリズム [Bax, 94]• BDD を用いたパスのカウンティング [Sekine and Imai, 97]
(以下、 Read のアルゴリズムと呼ぶ)
これまでの研究の流れ (1)
• 2010 年 10 月– The Art of Computer Programming 4-1 を読む輪講で ZDD を用いたパスの列挙アルゴリズムが紹介される
• 次の週、川原が C# で実装• 2010 年 11 月
– ZDD の代数演算のみで列挙するシンプルな 手法を考える(遅い)
• ERATO 合宿で発表• 2011 年 1 月
– 改良手法を考える 2 月に冬の LA シンポジウムで発表
3 月にアルゴリズム研究会
これまでの研究の流れ (2)• 2010 年 10 月 輪講で紹介• 2010 年 11 月 ZDD の代数演算のみの手法• 2011 年 1 月 ↑の改良
• 2011 年 3 月 パス列挙技法をパズルに応用– ゲーム・パズル研究集会で発表
• 2011 年 4 月 ネットワークの信頼性評価への応用を検討– 既存手法で Knuth の Alg. に似た手法が見つかる
発表の内容• Knuth のアルゴリズム Simpath の紹介• ZDD の代数演算のみを用いた手法( Mate-ZDD )の
紹介• 両者の中間の手法( Hybrid )の紹介• 実験• ネットワーク信頼性評価への応用
se1
t
Knuth によるアルゴリズム Simpath
1. 枝に順番を付ける(例えば、 s から幅優先)
e2
e3
e4
e5
枝 e1, e2,… の順に処理
2. 2 分木を構築
e1e1 = 0e2
e2 = 0
e4
e2e2 = 1 e2 = 0 e2 = 1
e1 = 1
e5
各枝変数 ei に対し、
ei = 0 or 1 を決めていく
(もっと良い方法もあり)
e3 e3 e3 e30 1
s e1 t
e2
e3
e4
e5
ei = 1 である枝が s-t パスになっているか?
s-t パスになっている1
se1
t
Knuth によるアルゴリズム Simpath
1. 枝に順番を付ける(例えば、 s から幅優先)
e2
e3
e4
e5
枝 e1, e2,… の順に処理
2. 2 分木を構築
e1e1 = 0e2
e2 = 0
e4
e2e2 = 1 e2 = 0 e2 = 1
e1 = 1
e5
各枝変数 ei に対し、
ei = 0 or 1 を決めていく
(もっと良い方法もあり)
e3 e3 e3 e30 1
s e1 t
e2
e3
e4
e5
ei = 1 である枝が s-t パスになっているか?
s-t パスになっていない0
s e1 t
e2
e3
e4
e5
s-t パス +余分な枝
0
se1
t
Knuth によるアルゴリズム Simpath
1. 枝に順番を付ける(例えば、 s から幅優先)
e2
e3
e4
e5
枝 e1, e2,… の順に処理
2. 2 分木を構築
e1e1 = 0e2
e2 = 0
e4
e2e2 = 1 e2 = 0 e2 = 1
e1 = 1
e5
各枝変数 ei に対し、
ei = 0 or 1 を決めていく
(もっと良い方法もあり)
e3 e3 e3 e30 1
11 他は 011
が 1 つのパスに対応1
2 分木は全パスを保持している
Knuth によるアルゴリズム Simpath
se1
t
e2
e3
e4
e5
木の枝刈りe1e1 = 0
e2e2 = 0
e2
e1 = 1
0
e1 = 0 かつ e2 = 0 ならs-t パスができることはない
Knuth によるアルゴリズム Simpath
se1
t
e2
e3
e4
e5
木の枝刈りe1e1 = 0
e2e2 = 0
e2e2 = 1 e2 = 0
e1 = 1
0
e1 = 0 かつ e2 = 0 ならs-t パスができることはない
e30 1
e40 1
e1 = 1 かつ e3 = 1 かつ e4 = 1なら s-t パスができることはない
0
(分岐が生じる)
1
… …
…
…木の枝刈りを行っても場合の数は指数爆発
Knuth によるアルゴリズム Simpath
e8
e90
0 e10
0e11
0 1
s e1 t
e2
e4
e3 e10
e5
e6e7
e9
e8
e11 e8s t
e11
e9
e10
e8s t
e11
e9
e10
e8
e90
0 e10
0e11
0 1
e8
st
e11
e9
e10
以下の 2 つからは同じ木が生成される
Knuth によるアルゴリズム Simpath
e8
e90
0 e10
0e11
0 1
s e1 t
e2
e4
e3 e10
e5
e6e7
e9
e8
e11
e8
e90
0 e10
0e11
0 1
e7
…
……
…
e7
…
…
…
e8
st
e11
e9
e10
Knuth によるアルゴリズム Simpath
e8
e90
0 e10
e11
0 1
s e1 t
e2
e4
e3 e10
e5
e6e7
e9
e8
e11
e8
e90
0 e10
0e11
0 1
e7
…
……
…
e7
…
…
…
同じ形をもつ子は共有したい
…
e8
st
e11
e9
e10
Knuth によるアルゴリズム Simpath
s e1 t
e2
e4
e3 e10
e5
e6e7
e9
e8
e11
e7
…
……
…
e7
…
…
…
e8s t
e11
e9
e10
e8s t
e11
e9
e10
e8
76
e8s t
e11
e9
e10
56 は s とつながっている5 は 7 とつながっている
e7 = 0 e7 = 1
e8
76
5
76
5
共有する
e7 e7
Knuth によるアルゴリズム Simpath
76
s t5
接続情報の記憶法
12
3
48
9
mate 配列
頂点がパスの端
1 2 3 4 5 6 7 8 9imate[i]
逆端の番号
自身の番号頂点がいずれのパスにも含まれない
頂点がパスの途中 0
6 0 0 0 7 1 5 8 9
Knuth によるアルゴリズム Simpath
7
s t
6
5
接続情報の記憶法
12
3
48
9
mate 配列
頂点がパスの端
1 2 3 4 5 6 7 8 96 0 0 0 7 1 5 8 9
imate[i]
逆端の番号
自身の番号頂点がいずれのパスにも含まれない
頂点がパスの途中 0
どの頂点の接続情報を覚えればよいか?ei枝 i を処理するとき、
枝 i に接続している頂点を「訪れた」と表現するF := {訪れたことのある頂点 } { 二度と訪れない頂点 }
F を frontier という。 frontier 頂点の接続情報を覚える
frontier
この部分のみ記憶
e8e8
Knuth によるアルゴリズム Simpath
s e1 t
e2
e4
e3 e10
e5
e6e7
e9
e8
e11
e7
…
……
…
e7
…
…
…
e8s t
e11
e9
e10
e8s t
e11
e9
e10
76
e8s t
e11
e9
e10
5
e7 = 0 e7 = 1
76
5
76
5e7 e7
5 6 7imate[i] 7 1 5
5 6 7imate[i] 7 1 5
frontier の部分のmate が同じなら共有する
Knuth によるアルゴリズム Simpath
s e1 t
e2
e4
e3 e10
e5
e6e7
e9
e8
e11
e1
…
1
1
e2 e2
1 2
1 2
1 2
2 1
0 e3
1 2 3
3 2 1
1
2
3
45
6
7
e3 0
1 2 3
2 1 3
e4
1 2 3 4
4 0 3 1一般に
ex
ex+1
c
d
a
b ex
a b c dc d a b
mate の更新
a b c d0 0 d c
最大 4 か所書きかえれば更新できる
忘れてよい
Simpath では、(既約とは限らない) ZDD を構築している→ 既約化アルゴリズムによって、節点サイズに比例する時間で既約化できる
したがって、パスの列挙だけでなく、・ 列挙した結果を圧縮して保持・ 列挙したパスの索引生成・ 列挙した結果から条件を満たすパスを得るもできたことになる
e7
e80
0 e9
0e10
e6
…
… e6
…
e7
e80
0 e9
0e10
e1e1 = 0e2
e2 = 0 e2 = 10 …
節点の削除 節点の共有
s
t4
5
6
e1
e3
e4
1
2 3
7
8
各頂点のペア (i, j) ごとに変数 mi, j を用意する
m14 = 1, m56 = 1, m77 = 1,…
m11 = 0, m12 = 0,…
i, j が 1本のパスの両端なら mi, j = 1
そうでないなら mi, j = 0
e6
ZDD の代数演算のみを用いて、 ZDD を構築できないか?Mate-ZDD 法(提案手法)
s
t4
5
6
e1
e3
e4
1
2 3
7
8
i, j が 1本のパスの両端なら mi, j = 1
選ばれた枝+ mate を集合として表す
{e1, e3, e4, m14, m56, m33,…}
e6
Mate-ZDD 法(提案手法)
Mate-ZDD 法(提案手法)
s
t4
5
6
e1
e3
e4
1
2 3
7
8
e6 まで処理済み、次は e7
{e1, e3, e4, m14, m56, m33,…}
e6
e7 = 0 なら mate は変化なしe7 = 1 なら m14 → m17
{e1, e3, e4, e7, m17, m56, m33,…}
e7 s
t4
5
6
e1
e3
e4
1
2 3
7
8e6
e7
e7 = 1
e6 の処理が終わった時点での全状態を集めたものを考える
s
t4
5
6
e1
e3
e4
1
2 3
7
8e6
{e1, e3, e4,
m14, m56, m33,…}
s
t4
5
6
e1
e3
e4
1
2 3
7
8e6
{e1, e3,
m14, m25, m33,…}これらの全状態に対して、先ほどの操作を行いたい
s
t4
5
6
e1
e3
e4
1
2 3
7
8e6
{e2, e3,
m15, m44,…}
…
…
Mate-ZDD 法(提案手法)
集合の集合(集合族)は ZDD で効率よく保持できる
{{a, b, c, d}, {a, c}, {b, c}, {b, d}}
a0 1
b
c
d
1
0 は省略
c
1
b
c
1d
1
ZDD と集合族
a を含む集合だけを取り出し、 a を消去する
ZDD と集合族
{{a, b, c, d}, {a, c}, {b, c}, {b, d}} {{b, c, d}, {c}}
a0 1
b
c
d
1
c
1
b
c
d
1
トップの要素なら簡単にできる
b
c
d
1
c
1
集合族への操作例:
a を含まない集合だけ取り出すなら、 LO 枝側をもってこればよい
1
ZDD と集合族
c を含む集合だけを取り出し、 c を消去する{{a, b, c, d}, {a, c}, {b, c}, {b, d}} {{a, b, d}, {a}, {b}}
a0 1
b
c
d
1
c
1
b
c
1d
1
トップでなければ、その変数の深さまで潜って、枝の付け替えを行う
a0 1
b
c
d
1
c
1
b
c
1d
1
集合族への操作例:
ZDD と集合族
c を含む集合だけを取り出し、 c を消去する{{a, b, c, d}, {a, c}, {b, c}, {b, d}} {{a, b, d}, {a}, {b}}
a0 1
b
c
d
1
c
1
b
c
d
1
トップでなければ、その変数の深さまで潜って、枝の付け替えを行う
a0 1
b
cc
b
c
d
1
1
集合族への操作例:
c を含まない集合だけ取り出すなら、 LO 枝の方に付け替えればよい
d
1
11 0 0
ZDD と集合族
e を各要素に追加する{{a, b, c, d}, {a, c}, {b, c}, {b, d}}
集合族への操作例:
{{a, b, c, d, e}, {a, c, e}, {b, c, e}, {b, d, e}}
a0 1
b
c
d
1
c
1
b
c
1d
1
a
b
c
d
1
c
1
b
c
1d
1
e
トップに加える場合
ZDD と集合族
e を各要素に追加する{{a, b, c, d}, {a, c}, {b, c}, {b, d}}
集合族への操作例:
{{a, b, c, d, e}, {a, c, e}, {b, c, e}, {b, d, e}}
a0 1
b
c
d
1
c
1
b
c
d
1
a
b
c
d
1
c
1
b
c
1d
1
e
間に加える場合
e e e
1
ZDD と集合族
{{a, b, c, d}, {a, c}, {b, c}, {b, d}}
集合族を積と和で表現すると見やすい
abcd + ac + bc + bd
e を各要素に追加する (abcd + ac + bc + bd) × e= abcde + ace + bce + bde
a を含む集合だけを取り出し、a を消去する
(abcd + ac + bc + bd) = a(bcd + c) + bc + bd
なので、
a を含まない集合だけを取り出し、a を消去する
(abcd + ac + bc + bd) / a = bcd + c (abcd + ac + bc + bd) % a = bc + bd (多項式の除算、剰余算)
Mate-ZDD 法(提案手法)
e6 の処理が終わった時点での全状態を集めたものを考える
s
t4
5
6
e1
e3
e4
1
2 3
7
8e6
f = e1e3e4m14m56m33 +
s
t4
5
6
e1
e3
e4
1
2 3
7
8e6
e1e3m14m25m33 +
これらの全状態に対して、先ほどの操作を行いたい
s
t4
5
6
e1
e3
e4
1
2 3
7
8e6
e2e3m15m44 +
…
…
集合族を ZDD で表したものを f とする
Mate-ZDD 法(提案手法)
e6 の処理が終わった時点での全状態を集めたものを考える
これらの全状態に対して、先ほどの操作を行いたい
f = f + f / m14 × e7 × m17
e7 を追加m17 を追加
m14 を含むものを取り出し、m14 を削除
m14 → m17 の付け替え演算
f = e1e3e4m14m56m33 + e1e3m14m25m33 + e2e3m15m44 +…
初期値 f = m11 × m22 × m33 × ...
f = f + f × e / mik / mjl × mkl
frontier の中の各頂点 k,l について
頂点 p を二度と訪れないならば 各 k = p について f = f % mpk ( 頂点 p の次数が 1 の項は削除 )
f = f / mpp + f % mpp (mpp 変数の除去 )最後に f = f / mst
各枝 e = {i, j} についてfrontier を計算
Mate-ZDD 法(提案手法)アルゴリズム
e
ik
jl
pk
e
ik
jl
変数は ZDD のトップに追加する方が計算が早いので、Mate-ZDD 法では、先に処理した枝変数をZDD の下にするのがよい
m11
m 変数は頻繁に操作されるので、 e 変数の上にするのがよい
m22
…
e1 処理 m11
m12
…
m11
e1e1
e2 処理m11
m12
…
m11
e1e1
e2e2
(ボトムアップ的)(Simpath はトップダウン的 )
Mate-ZDD 法の変数順
Mate-ZDD 法の変数順
…
e1
e2
…
e 変数
m 変数{e1, e3, e4, m14, m56, m33}
m56
m33
m14
e4
e3
e1
1
上段で m 変数の集合、すなわち mate を表している。ある mate 値をもつ e 変数の集合がぶら下がっている
…
…
e1
e2
…
e 変数
{e1, e3, e4, m14, m56, m33}
e4
e3
e1
1
mate の管理に、 m 変数ではなく、( Simpath で使われている)配列を用いる
4 0 3 1 6 5 7 8 9 10 11 12
速度は Simpath と Mate-ZDD 法の中間くらいになる(と期待される)
Hybrid 法
Hybrid 法のメリット
…
e1
e2
…e 変数
{e1, e3, e4, m14, m56, m33}
e4
e3
e1
1
枝に制約条件を加えて、列挙を行うことが容易になる。
4 0 3 1 6 5 7 8 9 10 11 12
例えば、 e3 と e4 の少なくとも一方の枝を使うという条件ならF = F / e3 × e3 + F / e4 × e4
の演算を e4 の処理時に全体に施せばよい。mate 配列に所属する e 変数がなくなれば、 mate 配列を削除できる
0
頂点数 CyPath Simpath Mate-ZDD HybridMate-ZDD 法のZDDノード数 パスの数
日本地図 47 > 1000 0.02 <0.01 <0.01 951 1.4 × 1010
2重化 94 > 1000 40.64 248.72 340.77 18,971,787 5.0 × 1044
(単位:秒)
CyPath: Read ‘75 の alg.Simpath: Knuth の alg.Mate-ZDD: 提案手法Hybrid: 提案手法
14797272518 本
5039760385115189594214594926092397238616064 本( = 503正 9760澗 3851溝 1518穣 9594杼 2145垓 9492京 6092兆 3972億 3861万 6064 )
実験結果日本地図グラフ北海道から鹿児島までの全パス
日本地図グラフの頂点を2倍に増やしたグラフ
L 頂点数 CyPath Simpath Mate-ZDD HybridMate-ZDD 法のZDDノード数 パスの数
8 64 > 1000 0.17 0.28 0.11 3.1 × 104 7.8 × 1011
9 81 > 1000 0.48 1.58 0.32 1.1 × 105 3.2 × 1015
10 100 > 1000 1.40 5.69 1.75 3.7 × 105 4.1 × 1019
11 121 > 1000 3.50 24.49 8.37 1.2 × 106 1.5 × 1024
12 144 > 1000 10.29 92.96 30.77 4.2 × 106 1.8 × 1029
L × L グリッド
・・・
・・・
・・・
・ ・ ・
・ ・ ・
・ ・ ・
・・・
L
L
(単位:秒)
実験結果
s
t
CyPath: Read ‘75 の alg.Simpath: Knuth の alg.Mate-ZDD: 提案手法Hybrid: 提案手法
n CyPath Simpath Mate-ZDDMate-ZDD 法のZDDノード数 パスの数
10 < 0.01 < 0.01 < 0.01 4.7 × 102 5.8 × 102
15 0.42 < 0.01 0.16 1.6 × 104 1.1 × 105
16 49.61 1.30 23.28 1.1 × 105 5.3 × 107
17 > 1000 2.42 70.10 2.3 × 106 8.1 × 107
18 > 1000 6.48 213.94 8.1 × 106 7.1 × 108
n 頂点ランダムグラフ、枝の生成確率 0.5
(単位:秒)
実験結果 CyPath: Read ‘75 の alg.Simpath: Knuth の alg.Mate-ZDD: 提案手法Hybrid: 提案手法
マルチパスの列挙
s1
t2
s2
t1
s1 - t1 パスs2 - t2 パス
の組を全列挙交差しない
ms1t1 と ms2t2 と ms3t3 を含む集合を残せばよいs3
t3s3 - t3 パス
1e1
e2
e3
e4 f = f + f / e4 % e3 % e2 % e1) * e4 + (f % e4 / e3 % e2 % e1) * e3 + (f % e4 % e3 / e2 % e1) * e2 + (f % e4 % e3 % e2 / e1) * e1
条件付きパス(サイクル)の列挙
連結部分グラフの列挙
se1
te2
e3
e4e10
e5e6
e7
e8 e9
s と t が連結になるような部分グラフを列挙→ ネットワーク信頼性評価への応用
s
t4
5
6
e1
e3
e4
1
2 3
7
8e6
e74 は 1 と同じ連結成分5 は 6 と同じ連結成分