DEPARTMENT OF SURGERY KANSAI MEDICAL … training 3rd.pdf第1ステップ: 肝臓の挙上 課題 直針で肝円索を釣り上げ、肝臓をペンローズで挙上する 方法
フロンティア法 組合せ問題の解を列挙 索引化す...
Transcript of フロンティア法 組合せ問題の解を列挙 索引化す...
フロンティア法 - 組合せ問題の解を列挙索引化するZDD構築アルゴリズム
川原 純
科学技術振興機構 ERATO湊離散構造処理系プロジェクト
北海道大学 情報科学研究科
講義の目標
• パスの数え上げアルゴリズムを理解する
• 大規模データを扱うためのデータ構造の1つ
「ZDD」 についてより詳しく知る
– 大規模データの保存、活用
• 様々な対象を表現するZDDを高速に構築する手法
「フロンティア法」 アルゴリズムを理解する
– 適用事例について知る
ZDD: 集合の集合を表現するデータ構造
{
}
e1 e2 e4 e2
e5 e4 e3
,
, e3
,
0 1
1 0
e1
e2
e3
e4
e5
e5
e5 e5
e5 ,
{ } { } { }
{ } { } { }
ZDD
集合の集合
(Zero-suppressed Binary Decision Diagram) [S.Minato 93]
ZDD: 集合の集合を表現するデータ構造
{
}
e1 e2 e4 e2
e5 e4 e3
,
, e3
,
0 1
1 0
e1
e2
e3
e4
e5
e5
e5 e5
e5 ,
{ } { } { }
{ } { } { }
集合の集合
ZDD
0 : 0 終端
1 : 1 終端 それぞれ1つずつもつ
ei : ノード e1 e5 ~ いずれかのラベル
e1 , e2 ,… , e5 の順序
ZDD: 集合の集合を表現するデータ構造
{
}
e1 e2 e4 e2
e5 e4 e3
,
, e3
,
0 1
1 0
e1
e2
e3
e4
e5
e5
e5 e5
e5 ,
{ } { } { }
{ } { } { }
集合の集合
ZDD
0 : 0 終端
1 : 1 終端 それぞれ1つずつもつ
ei : ノード e1 e5 ~ いずれかのラベル
e1 , e2 ,… , e5 の順序
ノードは0枝と1枝を1つずつもつ
ZDD: 集合の集合を表現するデータ構造
{
}
e1 e2 e4 e2
e5 e4 e3
,
, e3
,
0 1
1 0
e1
e2
e3
e4
e5
e5
e5 e5
e5 ,
{ } { } { }
{ } { } { }
集合の集合
ZDD 0 : 0 終端
1 : 1 終端 それぞれ1つずつもつ
ei : ノード e1 e5 ~ いずれかのラベル
ノードは0枝と1枝を1つずつもつ
1つの集合が、 top から までの1本のパスに対応 1
ZDD: 集合の集合を表現するデータ構造
{
}
e1 e2 e4 e2
e5 e4 e3
,
, e3
,
0 1
1 0
e1
e2
e3
e4
e5
e5
e5 e5
e5 ,
{ } { } { }
{ } { } { }
集合の集合
ZDD 0 : 0 終端
1 : 1 終端 それぞれ1つずつもつ
ei : ノード e1 e5 ~ いずれかのラベル
ノードは0枝と1枝を1つずつもつ
1つの集合が、 top から までの1本のパスに対応 1
ZDD: 集合の集合を表現するデータ構造
{
}
e1 e2 e4 e2
e5 e4 e3
,
, e3
,
0 1
1 0
e1
e2
e3
e4
e5
e5
e5 e5
e5 ,
{ } { } { }
{ } { } { }
集合の集合
ZDD 0 : 0 終端
1 : 1 終端 それぞれ1つずつもつ
ei : ノード e1 e5 ~ いずれかのラベル
ノードは0枝と1枝を1つずつもつ
1つの集合が、 top から までの1本のパスに対応 1
0 1
1 0
e1
e2
e3
e4
e5
e2
等価な2つのノードは必ず共有される
0 1
1 0
e1
e2
e3
e4
e5
ZDDの性質
s e1 t
e2
e3
e4
e5
パスは辺の集合で表現できる
s e1 t
e2
e3
e4
e5
s e1 t
e2
e3
e4
e5
s e1 t
e2
e3
e4
e5
s e1 t
e2
e3
e4
e5
{e1, e4} {e2, e5}
{e1, e3 ,e5} {e2, e3 ,e4}
s e1 t
e2
e3
e4
e5
パスは辺の集合で表現できる
s e1 t
e2
e3
e4
e5
s e1 t
e2
e3
e4
e5
s e1 t
e2
e3
e4
e5
s e1 t
e2
e3
e4
e5
{e1, e4} {e2, e5}
{e1, e3 ,e5} {e2, e3 ,e4}
全ての s-t パスを列挙して、
辺集合の集合で表す
s e1 t
e2
e3
e4
e5
パスは辺の集合で表現できる
s e1 t
e2
e3
e4
e5
s e1 t
e2
e3
e4
e5
s e1 t
e2
e3
e4
e5
s e1 t
e2
e3
e4
e5
{e1, e4} {e2, e5}
{e1, e3 ,e5} {e2, e3 ,e4}
全ての s-t パスを列挙して、
辺集合の集合で表す
{{e1, e4}, {e2, e5}, {e1, e3 ,e5}, {e2, e3 ,e4}} all s-t path =
Knuth のパス列挙アルゴリズム
全 s-t パスを表現する ZDD をトップダウン的に構築
ZDD
s e1
t
パス列挙(ZDD構築)アルゴリズム [Knuth 08]
1. 辺に順番を付ける (例えば、s から幅優先)
e2
e3
e4
e5
辺 e1, e2,… の順に処理
2. ZDDを構築
e1 e1 = 0
e2 e2 = 0
e4
e2 e2 = 1 e2 = 0 e2 = 1
e1 = 1
e5
各辺変数 ei に対し、 ei = 0 or 1 を決めていく
(もっと良い方法もあり)
e3 e3 e3 e3 0 1
s e1 t
e2
e3
e4
e5
ei = 1 である辺が s-t パスになっているか?
s-t パスになっている 1
s e1
t
1. 辺に順番を付ける (例えば、s から幅優先)
e2
e3
e4
e5
辺 e1, e2,… の順に処理
2. ZDDを構築
e1 e1 = 0
e2 e2 = 0
e4
e2 e2 = 1 e2 = 0 e2 = 1
e1 = 1
e5
各辺変数 ei に対し、 ei = 0 or 1 を決めていく
(もっと良い方法もあり)
e3 e3 e3 e3 0 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
パス列挙(ZDD構築)アルゴリズム [Knuth 08]
s e1
t
1. 辺に順番を付ける (例えば、s から幅優先)
e2
e3
e4
e5
辺 e1, e2,… の順に処理
2. ZDDを構築
e1 e1 = 0
e2 e2 = 0
e4
e2 e2 = 1 e2 = 0 e2 = 1
e1 = 1
e5
各辺変数 ei に対し、 ei = 0 or 1 を決めていく
(もっと良い方法もあり)
e3 e3 e3 e3 0 1
1 1 他は0 1 1
が1つのパスに対応 1
パス列挙(ZDD構築)アルゴリズム [Knuth 08]
パス列挙(ZDD構築)アルゴリズム [Knuth 08]
s e1
t
e2
e3
e4
e1 e1 = 0
e2 e2 = 0
e2 e2 = 1 e2 = 0 e2 = 1
e1 = 1
e3 e3 e3
1 0 1 0 1 0 1 0
パス列挙(ZDD構築)アルゴリズム [Knuth 08]
e1 e1 = 0
e2 e2 = 0
e2 e2 = 1 e2 = 0 e2 = 1
e1 = 1
e3 e3
1 0 1 0
ノードを共有できるときは共有したい
ただし、子DAGを作成せずに、共有可能か判定を行う
s e1
t
e2
e3
e4 e3
1 0 1 0
パス列挙(ZDD構築)アルゴリズム [Knuth 08]
e1 = 0 e1 = 1
e2 = 0 e2 = 1
e1 = 0 e1 = 1
e2 = 0 e2 = 1
?
s e1
t
e2
e3
e4
途中の経路は分からないが s につながっていることは分かっている
パス列挙(ZDD構築)アルゴリズム [Knuth 08]
s t
… …
t
フロンティア
処理済み辺 未処理辺
パス列挙(ZDD構築)アルゴリズム [Knuth 08]
s t
… …
t
a
b c
d
h
f
g
f d
s a
b c
d
h
f
g
s t
a
b c
d
h
f
g
s t
f d
s
パス列挙(ZDD構築)アルゴリズム [Knuth 08]
s t
… …
t
a
b c
d
h
f
g
f d
s a
b c
d
h
f
g
s t
a
b c
d
h
f
g
s t
f d
s
f d
s a
b c
d
h
f
g
s t
接続情報の記憶法
mate 配列
頂点がパスの端
d f g v
mate[v]
逆端の頂点
自身の頂点
頂点がいずれの パスにも含まれない
頂点がパスの途中
0
f d s
パス列挙(ZDD構築)アルゴリズム [Knuth 08]
a
b c
d
h
f
g
s t
s
a
b
…
…
a b v
mate[v] a 0
パス列挙(ZDD構築)アルゴリズム [Knuth 08] a
b
c
s t
e1
e2 e3
e4
e5
e6 s a
a s
b
a
s
a
b
s
a
b
s
a s
0 b
s 0
s
s
a
c
s
c
s
s
0
mate 値
パス列挙(ZDD構築)アルゴリズム [Knuth 08] a
b
c
s t
e1
e2 e3
e4
e5
e6 mate 値
s a
a s
b
a
s
a
b
s
a
b
s
a s
0 b
s 0
s
s
a
c
s
s
0
パス列挙(ZDD構築)アルゴリズム [Knuth 08] a
b
c
s t
e1
e2 e3
e4
e5
e6
s
a
c
s
s
0
s
a
c
t
s
0
パス列挙(ZDD構築)アルゴリズム [Knuth 08] a
b
c
s t
e1
e2 e3
e4
e5
e6
s
a
c
s
s
0
s
a
c
t
s
0
1
1
1
パス列挙(ZDD構築)アルゴリズム [Knuth 08] a
b
c
s t
e1
e2 e3
e4
e5
e6
s
a
c
s
s
0
s
a
c
t
s
0
1
1
1
根から までの 1つの経路が 1 つのs-t パスに 対応する
1
a b c d f v
mate[v] c 0 a d s
a
b
c s
g
d
f
a
b
c s
g
d
f
a b c d f g v
mate[v] 0 0 g d s c
パス列挙(ZDD構築)アルゴリズム [Knuth 08]
mate 配列の更新例
一般に
c
d
a
b
a b c d
c d a b
a b c d
0 0 d c
最大4か所書きかえれば更新できる
mate 配列の更新
パス列挙(ZDD構築)アルゴリズム [Knuth 08]
パス列挙アルゴリズム [Knuth 08]
枝刈り
a
b
c s
g
d
f
a
b
c s
g
d
f
0
枝刈り
a
b
c s
g
d
f
a
b
c s
g
d
f
0
枝刈り
a
b
c s
g
d
f t
a
b
c s
g
d
f t
0
枝刈り
a
b
c s
g
d
f t
a
b
c s
g
d
f t
1
パス列挙アルゴリズム [Knuth 08]
終端判定条件
p q if x = 1
if GetDegree(p) = 2 or GetDegree(q) = 2
GetDegree(v)
if mate[v] == v
return 0
if mate[v] == 0
return 2
else
return 1
辺 e を処理する前の判定
終端 0
if (p = s or p = t) and GetDegree(p) = 1
終端 0
if (q = s or q = t) and GetDegree(q) = 1
終端 0
if mate[p] = q and mate[q] = p
終端 0
if mate[p] = s and mate[q] = t
mate[p] = t and mate[q] = s
or
for each vertex v in the frontier
if v != s or v != t or v!= p or v!= q
if GetDegree(v) = 1
終端 0
終端 1
end for
end if
for each v such that v がフロンティアから外れる
if v = s or v = t
if GetDegree(v) = 0
辺 e を処理した後の判定
終端 0
else
if GetDegree(v) = 1
終端 0
GetDegree(v)
if mate[v] == v
return 0
if mate[v] == 0
return 2
else
return 1
a
b
c s
g
d
f
a
b
c s
g
d
f
1
1 1 1
1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 2
1
2 2
1
1 1
1 2 2 2
4
1 2
3 3 2
4 3 3 2
4 3 3 2
6 6
6 6
12 パスの数え上げ s
t
e1
e2
e3
e4 e5 e6
e11
e10 e7 e9
e8
e12
実験結果
n × n グリッド ・・・
・・・
・・・
・ ・ ・
・ ・ ・
・ ・ ・ s
t 頂点の数 (n + 1) × (n + 1)
The On-Line Encyclopedia of Integer Sequence (OEIS) : 数列大辞典
http://oeis.org/A007764
実験結果
n × n グリッド ・・・
・・・
・・・
・ ・ ・
・ ・ ・
・ ・ ・ s
t 頂点の数 (n + 1) × (n + 1)
The On-Line Encyclopedia of Integer Sequence (OEIS) : 数列大辞典
http://oeis.org/A007764
n time(秒)
15 206.0
16 701.9
17 2326.0
18 7607.1
19 28279.2
20 91944.1
21 284117.0
実験結果
n × n グリッド
Thanks to 岩下洋哲氏
・・・
・・・
・・・
・ ・ ・
・ ・ ・
・ ・ ・ s
t 頂点の数 (n + 1) × (n + 1)
頂点数 計算時間 ZDDノード数 パスの数
日本地図 47 0.01秒 951 1.4 × 1010
2重化 94 248.72秒 18,971,787 5.0 × 1044
14797272518 本
5039760385115189594214594926092397238616064 本 (= 503正9760澗3851溝1518穣9594杼2145垓9492京6092兆3972億3861万6064)
実験結果
日本地図グラフ
北海道から鹿児島までの全パス
講義の目標
• パスの数え上げアルゴリズムを理解する
• 大規模データを扱うためのデータ構造の1つ
「ZDD」 についてより詳しく知る
– 大規模データの保存、活用
• 様々な対象を表現するZDDを高速に構築する手法
「フロンティア法」 アルゴリズムを理解する
– 適用事例について知る
ZDD と集合族
集合の集合(集合族)は ZDD で効率よく保持できる
{{a, b, c, d}, {a, c}, {b, d}, {b, c, d}}
a 0 1
b
c
d
1
0 は省略
c
1
b
c
d
1
d
1
a を含む集合だけを取り出し、a を消去する
ZDD と集合族
{{a, b, c, d}, {a, c}, {b, d}, {b, c, d}} {{b, c, d}, {c}}
a 0 1
b
c
d
1
c
1
b
c
d
1
d
1
トップの要素なら簡単にできる
b
c
d
1
c
1
集合族への操作例:
a を含まない集合だけ 取り出すなら、LO 枝側を もってこればよい
ZDD と集合族
c を含む集合だけを取り出し、c を消去する
{{a, b, d}, {a}, {b, d}}
a 0 1
b
c
d
1
c
1
b
c
d
1
d
1
トップでなければ、その変数の深さまで潜って、 枝の付け替えを行う
a 0 1
b
c
d
1
c
1
b
c
d
1
d
1
集合族への操作例:
{{a, b, c, d}, {a, c}, {b, d}, {b, c, d}}
ZDD と集合族
c を含む集合だけを取り出し、c を消去する
a 0 1
b
c
d
1
c
1
b
c
d
1
d
1
トップでなければ、その変数の深さまで潜って、 枝の付け替えを行う
a 0 1
b
c c
b
c
d
1
d
1
集合族への操作例:
c を含まない集合だけ 取り出すなら、LO 枝の 方に付け替えればよい
d
1
1
{{a, b, d}, {a}, {b, d}} {{a, b, c, d}, {a, c}, {b, d}, {b, c, d}}
集合族 F から要素 x を含む集合だけを取り出し、x を消去する
集合族への操作例:
ZDD と集合族
F / x
{{a, b, c, d}, {a, c}, {b, d}, {b, c, d}}
abcd + ac + bd + bcd = (abd + a + bd) c + bd
(abcd + ac + bd + bcd ) / c = abd + a + bd
(abcd + ac + bd + bcd ) % c = bd
c を含む集合だけを取り出し、c を消去する
c を含む集合だけを取り出し、c を消去する
集合族 F から要素 x を含まない集合だけを取り出し、x を消去する
F % x
ZDD と集合族
a を各要素に追加する
{{b, c, d, e}, {b, d}, {c, e}, {c, d}}
集合族への操作例:
{{a, b, c, d, e}, {a, b, d}, {a, c, e}, {a, c, d}}
b 0 1
c
d
e
1
d
1
c
d
e
1
e
1
b
c
d
e
1
d
1
c
d
e
1
e
1
a
トップに加える場合
ZDD と集合族
d を各要素に追加する
{{a, b, c, e}, {a, c}, {b, e}, {b, c}}
集合族への操作例:
{{a, b, c, d, e}, {a, c, d}, {b, d, e}, {b, c, d}}
a 0 1
b
c
e
1
c
1
b
c
e
1
e
1
a
b
c
e
1
c
1
b
c
e
1
e
1
d
間に加える場合
d d
d
d が1つも 含まれない場合
d を各要素に追加する
{{a, b, c, e}, {a, d}, {b, e}, {b, d}}
集合族への操作例:
{{a, b, c, d, e}, {a, d}, {b, d, e}, {b, d}}
{d} ∪ {d} = {d} である それほど簡単ではない(省略)
d が含まれる場合
ZDD と集合族
集合族 F の各要素に x を加える
集合族への操作例:
ZDD と集合族
F * x
abce + ad + be + bd
各要素に d を加える
{{a, b, c, e}, {a, d}, {b, e}, {b, d}}
(abce + ad + be + bd) * d = abcde + add + bde + bdd
= abcde + ad + bde + bd
集合族 F から要素 x を含む集合だけを取り出す(x は消去しない)
(F / x) * x
{{a, b, c, d}, {a, c}, {b, d}, {b, c, d}}
abcd + ac + bd + bcd = (abd + a + bd) c + bd
c を含む集合だけを取り出す(c は消去しない)
ZDD と集合族
((abcd + ac + bd + bcd ) / c) * c = (abd + a + bd) * c
= abcd + ac + bcd
ZDD と集合族
F ∪ G = { {c}, {b, c} , {a}, {a, b}, {a, b, c}, {b} }
a 0 1
b
c
1
b
c c
F = { {c}, {b, c} , {a}, {a, b}, {a, b, c} }
c + bc + a + ab + abc
G = { {b}, {b, c}, {a, b} }
b + bc + ab
a 0 1
b
1
b
c
a 0 1
b
c
1
b
c c
F = { {c}, {b, c} , {a}, {a, b}, {a, b, c} }
c + bc + a + ab + abc
(c + bc) + a(ε + b + bc)
G = { {b}, {b, c}, {a, b} }
b + bc + ab
a 0 1
b
1
b
c
(b + bc) + a(b)
F ∪ G = (c + bc) ∪ (c + bc) + a((ε + b + bc) ∪(b))
a 0 1 a 0 1
F
F0 F1 G0 G1
G
一般に F = F0 ∪ a * F1 G = G0 ∪ a * G1 のとき F ∪ G = (F0 ∪ G0) ∪ a * (F1 ∪ G1)
a 0 1 a 0 1
F
F0 F1 G0 G1
G
一般に F = F0 ∪ a * F1 G = G0 ∪ a * G1 のとき F ∪ G = (F0 ∪ G0) ∪ a * (F1 ∪ G1)
apply (F, G, ∪) = make_node(a, apply (F0, G0, ∪), apply (F1, G1, ∪))
a 0 1
F0 ∪ G0
F ∪ G
F1 ∪ G1
apply (F, {}, ∪) = F など ∩ や Δ (対称差) なども同様
(ノード飛び越しがあると もっと複雑)
a 0 1 a 0 1
F
F0 F1 G0 G1
G
a 0 1
F0 ∪ G0
F ∪ G
F1 ∪ G1
最悪計算量は (F のノード数) * (G のノード数) 演算をキャッシュすると高速化できる (実用的には出力ZDDのノード数に線形のことが多い)
s
t
e1
e2
e3
e4 e5 e6
e11
e10 e7 e9
e8
e12
F: 全s-t パスを表すZDD
e9 を必ず通る s-t パスの集合は?
(F / e9) * e9
e9 を必ず通らない s-t パスの集合は?
(F % e9) * e9
a 0 1
b
c
1
b
c c
a, b, c, d のうち、 ちょうど3個の要素からなる集合の集合 を表すZDD
{ {a, b, c}, {a, b, d}, {a, c, d}, {b, c, d} }
d d d d
R(3, 4) と表記する
0 0 0 0
s
t
e1
e2
e3
e4 e5 e6
e11
e10 e7 e9
e8
e12
F: 全s-t パスを表すZDD
e9 を必ず通る長さが 8 の s-t パスの集合は?
((F / e9) * e9) ∩ R(8, 12)
(必ずしも効率的とは限らない。 フロンティア法で直接作る方が速いことも)
条件付きパス(サイクル)の列挙
1 e1
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
条件付きパス(サイクル)の列挙
一様ランダムサンプリング
a 0 1
b
c c
b
c
d
0
d
1
{d}, {c}, {c, d}, {b}, {b, d}, {b, c, d}, {a}, {a, d}, {a, c, d}, {a, b}, {a, b, c}, {a, b, d}, {a, b, c, d}
1 2
3 3 4
6 7
13 a
b b
6 7
13 確率
6
13
7
13
確率
一様ランダムサンプリング
a 0 1
b
c c
b
c
d
0
d
1
{d}, {c}, {c, d}, {b}, {b, d}, {b, c, d}, {a}, {a, d}, {a, c, d}, {a, b}, {a, b, c}, {a, b, d}, {a, b, c, d}
1 2
3 3 4
6 7
13
b
c c
3 3
6 確率
3
6
確率 3
6
一様ランダムサンプリング
a 0 1
b
c c
b
c
d
0
d
1
{d}, {c}, {c, d}, {b}, {b, d}, {b, c, d}, {a}, {a, d}, {a, c, d}, {a, b}, {a, b, c}, {a, b, d}, {a, b, c, d}
1 2
3 3 4
6 7
13 {b, d}
講義の目標
• パスの数え上げアルゴリズムを理解する
• 大規模データを扱うためのデータ構造の1つ
「ZDD」 についてより詳しく知る
– 大規模データの保存、活用
• 様々な対象を表現するZDDを高速に構築する手法
「フロンティア法」 アルゴリズムを理解する
– 適用事例について知る
フロンティア法とは
トップダウンにZDDを構築する技法
e1 e1 = 0
e2 e2 = 0
e2 e2 = 1 e2 = 0 e2 = 1
e1 = 1
e3 e3
1 0 1 0
ノードを共有できるときは共有したい
s t
b c
a
フロンティア
a b c v
mate[v] 0 s c
各ノードについて、 フロンティア上に 何らかの情報を持たせて、 共有可能性と枝刈りを判定
一般化して configuration と呼ぶ
パス列挙アルゴリズム [Knuth 08]
(a), (b), (c) がs-tパスの場合の固有の処理
ハミルトンパス
for each v such that v がフロンティアから外れる
if v = s or v = t
if GetDegree(v) = 0
辺 e を処理した後の判定
終端 0
else
if GetDegree(v) = 1
終端 0
or GetDegree(v) = 0
(全点を通る s-t パス)
複数終端対パス
s1
t2
s2
t1
s1 - t1 パス
s2 - t2 パス の組を全列挙 交差しない
s3
t3 s3 - t3 パス
(si , ti) をヒントペアという
si や ti をヒント頂点、
複数終端対パス 終端判定条件
p q if x = 1
if GetDegree(p) = 2 or GetDegree(q) = 2
GetDegree(v)
if mate[v] == v
return 0
if mate[v] == 0
return 2
else
return 1
辺 e を処理する前の判定
終端 0
if (p がヒント頂点) and GetDegree(p) = 1
終端 0
if (q がヒント頂点) and GetDegree(q) = 1
終端 0
if mate[p] = q and mate[q] = p
終端 0
if (mate[p] と mate[q] がともにヒント頂点)
(mate[p], mate[q]) も (mate[q], mate[p]) もヒントペアではない
終端 0
for each v such that v がフロンティアから外れる
if v がヒント頂点
if GetDegree(v) = 0
辺 e を処理した後の判定
終端 0
else
if GetDegree(v) = 1
終端 0
GetDegree(v)
if mate[v] == v
return 0
if mate[v] == 0
return 2
else
return 1
複数終端対パス 終端判定条件
1 最後の辺を処理し終えて、 終端でなければ 終端 0
サイクルが生じてはいけない 連結成分が2つ以上 生じてはいけない
全域木 (本質的には [K.Sekine, H.Imai 95])
フロンティア法(再掲)
configuration の設計
枝刈り の設計
全域木 (本質的には [K.Sekine, H.Imai 95])
a b c v
mate[v] A A B
a b c v
mate[v] A A B
b
c
b
c
等価
a a
configuration として、各頂点が属する 連結成分のIDを記憶
A A
B B
configuration の設計
同じ連結成分に属しているなら同じID 異なる連結成分に属しているなら異なるID
全域木 (本質的には [K.Sekine, H.Imai 95])
枝刈りの設計 同じ連結成分を 両端とする辺を加えるとき、 サイクルができる
0 に接続 b
c
A
B
a
加えない
b
c
A
B
a 孤立成分が 生じる
0 に接続
1 に接続
最後の辺まで処理後、 0 に接続されないなら
a b c v
mate[v] A A B
b
c
a
A
B
マッチングの列挙
configuration の設計
b
c
a
a b c v
mate[v] 0 1 1
既にマッチングに使われている頂点は 1 使われていない頂点は 0 と すればよい
枝刈りの設計
b
c
a
a b c i
mate[i] 0 1 1
マッチングに 使われている 頂点に 辺を加える時
0 に接続
1 に接続
最後の辺まで処理後、 0 に接続されないなら
辺変数型
パス型 森型 パス
サイクル
ハミルトンパス
ハミルトンサイクル
オイラー路
複数終端対パス
(ナンバーリンク)
森 全域木
シュタイナー木
カット(セット)
s-tカット
k 終端カット
連結成分
Tutte多項式
Jones多項式 (ひもの絡み目)
上記2つ[関根, 今井 1996]
[Yoshinaka et al. 2012]
[Knuth 2008]
信頼性多項式
[Imai et al. 1997]
信頼性多項式
[Hardy et al. 2007]
複数サイクル
頂点変数型
頂点被覆 独立集合 支配集合
0-1 ナップザック 部分和 特殊
数分割 特殊
頂点彩色
括弧列 マトロイド Tutte 多項式
[Imai et al. 1996] [Saitoh et al. 2009]
動的計画法的な見方も可能
クリーク
フラグ型
辺被覆
完全 マッチング
マッチング
集合被覆
集合分割
集合 パッキング
上記3つ [今井, 今井 1998]
ハイパー グラフ
一般化
グラフ
根付き森、木
有向パス [Knuth 08]
[Knuth 2008]
有向グラフ
支配集合の列挙
ではない全ての頂点は
に隣接する 少なくとも1つの
v7
v6
v5
v4
v3
v2
v1
v8
v9 v1 v1 = 0
v2 v2 = 0
v2 v2 = 1 v2 = 0 v2 = 1
v1 = 1
頂点を変数とするZDDを構築 v7
v6
v5
v3
v2 v8
v9
v4 v1
4 5 6 i
mate[i] 0 1 0
頂点が支配されているなら1 支配されていないなら0 と すればよい
頂点の取捨選択の情報を (フロンティア上の)頂点に記憶しているため、 効率が良いとは限らない
0/1 ナップザック問題の列挙
x1 50
x2 100 …
xn 210
…
各アイテムを 取るかとらないかを選択 重さが M 以下になるような取り方
重さ
x1 x1 = 0
x2 x2 = 0
x2 x2 = 1 x2 = 0 x2 = 1
x1 = 1
0
50 0
x1
x2
xn
…
このグラフに対する フロンティア法と 見ることができる
動的計画法のテーブルと見ることもできる
configuration = 重さの総和
辺変数型
パス型 森型 パス
サイクル
ハミルトンパス
ハミルトンサイクル
オイラー路
複数終端対パス
(ナンバーリンク)
森 全域木
シュタイナー木
カット(セット)
s-tカット
k 終端カット
連結成分
Tutte多項式
Jones多項式 (ひもの絡み目)
上記2つ[関根, 今井 1996]
[Yoshinaka et al. 2012]
[Knuth 2008]
信頼性多項式
[Imai et al. 1997]
信頼性多項式
[Hardy et al. 2007]
複数サイクル
頂点変数型
頂点被覆 独立集合 支配集合
0-1 ナップザック 部分和 特殊
数分割 特殊
頂点彩色
括弧列 マトロイド Tutte 多項式
[Imai et al. 1996] [Saitoh et al. 2009]
動的計画法的な見方も可能
クリーク
フラグ型
辺被覆
完全 マッチング
マッチング
集合被覆
集合分割
集合 パッキング
上記3つ [今井, 今井 1998]
ハイパー グラフ
一般化
グラフ
根付き森、木
有向パス [Knuth 08]
[Knuth 2008]
有向グラフ まとめ ・フロンティア法によって様々な対象を表現する ZDDを構築可能 → configuration と枝刈りの設計
課題: 計算量評価等の理論的裏付け
適用事例:配電網のスイッチ構成
配電網
すべての家は ちょうど1つの変電所に つながっている必要がある
サイクルが生じてはいけない
変電所を根とする 根付き全域森
根付き森 ZDD
電気制約 ZDD
∩ 条件を満たす ZDD
引用: http://www.jst.go.jp/pr/announce/20120223/index.html
適用事例:配電網のスイッチ構成
配電網
すべての家は ちょうど1つの変電所に つながっている必要がある
サイクルが生じてはいけない
変電所を根とする 根付き全域森
根付き森 ZDD
電気制約 ZDD
∩ 条件を満たす ZDD
引用: http://www.jst.go.jp/pr/announce/20120223/index.html
468個のスイッチ 制約条件を満たす解の個数は 2136820138348532911682612214804905609 817839244385235398189521540
通り (= 約1063)
約1時間15分 ZDDノード数 約110万個 (779MB)
まとめ
• パスの数え上げアルゴリズム
• ZDD について詳細 – 大規模データの保存、ZDD演算によるフィルタリング
• 様々な対象を表現するZDDを高速に構築する手法
「フロンティア法」 アルゴリズム – ハミルトンパス
– 複数終端対パス
– 全域木
– マッチング
• 適用事例 フロンティア法のソースコード http://www-erato.ist.hokudai.ac.jp/~jkawahara/frontier