文字列の集合を表すseqbddに...
TRANSCRIPT
-
文字列の集合を表すSeqBDDに関する種々の技法について
4月20日(金)
立命館大学 修士課程2回生
青木洋士
1
-
目次
• SeqBDD
• 逆順の文字列集合を表す SeqBDD の構築
• 写像枝を用いた SeqBDD の節点削減手法
2
-
b
a
#
トライと SeqBDD
• 接頭辞を共有して文字列集合を表現
• SeqBDD は接尾辞も共有
• 接頭辞を指定して検索
–検索文字列長に比例
{ ab, ac, bc }
b
a
c
b
1
SeqBDD
c c
b
トライ
# #
3
-
SeqBDD
• 文字列集合間で共通な節点を共有
–各節点が文字列集合に対応
• 枝のたどり方
– 1-枝は節点の文字を含む
– 0-枝は節点の文字を含まない
• 文字列集合を一意に表現
– 0-枝側は、辞書順に文字が出現
4
b
a
c
b
1 0
{abb, ac, bc}
b
{bc}
{c}
{bb, c}
{b}
{ε}
SeqBDD
abb ac
φ
-
SeqBDD同士の集合演算 Apply
• 先頭が文字cであるかどうかで文字列を分類
–再帰的に展開
–演算結果をキャッシュし、再利用
5
P ∩ Q
Pc ∩ Qc
c
Pc ∩ Qc
効率の良い演算
-
逆順の文字列集合を表す SeqBDD の構築
• P.reverse = { s | sR ∈ P }
– s は系列、 sR はsの逆順の文字列
6
P
a
b
s
c
t
1
P.reverse {abs, abt, act, ct}
s
b
a
b
c
1
{sba, tba, tca, tc} t
a
-
接頭辞・接尾辞による検索
• 接頭辞による検索
– 1パス
• 接尾辞による検索
–複数パス
• 逆順の文字列集合のSeqBDD
–接尾辞による検索が接頭辞による検索に対応
7
P = {abt, abct, bt, b}
a
b b
P.psearch(ab) = {abt, abct}
t t
1
c
-
単純な手法 • 再帰的に処理
–文字列を1つずつ取り出しながら構築
• 共有されている接尾辞を何度も処理
8
P.reverse
P
a
b
s
c
t
1
{abs, abt, act, ct}
s
b
a
1
t
b
a
1
t
c
a
1
t
c
1
∪ ∪ ∪
t
t t t
-
提案手法
a
b
s
c
t
1
1
2 3
4 5
P = {abs, abt, act, ct}
9
6
• トポロジカル順序で節点を処理
–節点をトポロジカルソート
–根から終端節点まで処理
• 各節点を一度だけ処理
-
根に {ε}、他の節点に {} を対応付け
10
1
{ε} {}
0
a
b
s
c
t
1
{ε}
{}
{}
{} {}
P
{}
-
文字aに対応する節点を展開
11
1
{ε} {}
0
a
{a}
a
b
s
c
t
1
{ε}
{}
{}
{} {}
P
{a}
{}
{ε}
-
文字bに対応する節点を展開
12
1
{ε} {}
0
a
b {ba}
{a}
a
b
s
c
t
1
{ε}
{a}
{ε}
{} {}
P
{ba}
{}
{a}
{a},
-
文字cに対応する節点を展開
13
1
{ε} {}
0
a
b {ba}
{a}
a
{ε, a} c
{c, ca}
a
b
s
c
t
1
{ε}
{a}
{ε, a}
{ba} {}
P
{c, ca}
{}
-
文字sに対応する節点を展開
14
a
b
s
c
t
1
{ε}
{a}
{ε, a}
{ba} {c, ca}
P
1
{ε} {}
0
a
b {ba}
{a}
a
{ε, a} c
{c, ca}
{sba}
s
{ba}
{} {sba}
-
文字tに対応する節点を展開
15
{sba}
a
b
s
c
t
1
{ε}
{a}
{ε, a}
{ba} {ba, c, ca}
P
{tba, tc, tca}
1
{ε} {}
0
a
b {ba}
{a}
a
{ε, a} c
{c, ca}
{sba}
s
b
{ba, c, ca} t
{tba, tc, tca}
-
16
{tba, tc, tca}
1
{ε} {}
0
a
b {ba}
{a}
a
{ε, a} c
{c, ca}
{sba}
s
b
{ba, c, ca} t s
{sba, tba, tc, tca}
{sba, tba, tc, tca}
a
b
s
c
t
1
{ε}
{a}
{ε, a}
{ba} {ba, c, ca}
P 1-終端節点に逆順の文字列集合が対応
-
ランダムデータでの実験
17
0.00
0.05
0.10
0.15
0.20
0.25
0.30
0.35
0.40
10
20
30
40
50
60
70
80
90
10
0
実行時間
[秒
]
平均系列長 [文字]
配列から構築
単純手法
提案手法
0.00
0.20
0.40
0.60
0.80
1.00
1.20
1.40
1.60 1
00
00
20
00
0
30
00
0
40
00
0
50
00
0
60
00
0
70
00
0
80
00
0
90
00
0
10
00
00
実行時間
[秒
]
系列数 [個]
配列から構築
単純手法
提案手法
系列数を変化 系列長を変化
-
応用: SeqBDDによる連想配列
• SeqBDDMap
• キーと値のペア(k, v)を連結
• 値を逆順にする
(k, v) ⇒ k#vR
{ (ab, yz), (ac, yx), (bc, xx), (bc, yx) }
SeqBDDMap
文字列vの逆順
bc#xy
18
b
a
c
b
c
# #
z
y y
x x
x
1
#
-
SeqBDDMapのキーと値の入替え
• (bc, xy)のキーと値の入れ替えを考える
19
(bc, xy)
(xy, bc)
bc#yx
xy#cb
入れ替え
文字列化
文字列化
逆順 入れ替え=逆順文字列の構築
-
写像枝を用いた SeqBDD
• BDDは、属性枝の手法を用いて節点削減
–否定枝
– Variable Shifters
• SeqBDDの節点も削減したい
–写像枝(提案手法)
20
-
否定枝の技法
• BDDの枝に論理の否定を表す記号を付与
21
~a~b~c + ~ab + a~bc
a
b
c
0 1
c
b
a
0
c
b
-
x2 x3
Variable Shiftersの技法
• BDDの変数番号を下から詰めて読み替え
–変数番号の共通の差を利用して節点共有
22
1 0 1 0 1 0
1
2 1
4 3
x1
x3
x2
x4
f g g f
-
提案手法: 写像付きSeqBDD
• できるだけ多くの部分グラフを共有
• 構築途中でも属性枝を用いて圧縮
• 属性枝を用いた演算
– getSeqBDD: 子節点と変数番号から新節点を取得
–節点の生成は、常に getSeqBDD で行う
23
一意にグラフを構築
-
準備: 写像
• 定義域、値域は文字集合 Σ
• 恒等写像 I からの変化のみ記す
– f = { 1 → a, 3 → c } なら、f(1) = a, f(2) = 2, f(3) = c
24
1 2 3 … a b c …
1 2 3 … a b c …
f Σ Σ
-
枝に写像を付与
• 各節点の文字 (∈ β) を他の文字 (∈ α) で置き替え – α ∩ β = φ
• 元の文字との対応を表すために写像を枝に付与
P
a
c
1
Q
b 1→c
25
P
2
1
1
Q
2 1→c
2→a 2→b
-
写像の繰り上げ
• できるだけ親の節点に写像を繰り上げる
• 部分構造を共有しやすくする
1→c
26
P
2
1
1
Q
2 1→c
2→a 2→b 1→c 2→a
P
2
1
1
Q 1→c 2→b
-
0-枝側の写像を優先して繰り上げ
a b
a
b c
1
3
2
1
1
1→b 2→a
1→c 2→b 3→a
3
2
1
1
1→b 2→a
3→a
1→c 2→b
27
• 0-枝には、常に I が対応
I
-
既存の変数番号を繰り返し利用
a b
c
d a
1
1
2
1
1
1→d 2→c
1→a 2→b
?
2
1
1
1→d 2→c
1→a 2→b
?
28
• 写像のサイズをアルファベットサイズに抑える
-
同じ変数を繰り返し利用できない場合
b y
c
d x
1
a
c
3
2
1
1
4
5
1→x 2→y 3→b 4→a 5→c
1→d 2→c
29
• 同じ値へ写る要素は一つ
-
写像の演算
• 加算: h = f g –一致しない要素だけ足す
– f = { 1 → a, 2 → b }, g = { 1 → b, 3 → c } なら、
– h = { 1 → a, 2 → b, 3 → c }
• 減算: h = f g –一致する要素だけ取り除く
– f = { 1 → a, 2 → b, 3 → c }, g = { 1 → b, 3 → c } なら、
– h = { 1 → a, 2 → b }
30
+
-
-
一意に集合を表現するための制約
• 節点は、 getSeqBDD のみで取得
• getSeqBDD ( c, P1, P0 )
– c は先頭の文字 (∈β)、c’ は c を置き換えた文字 (∈α)
– P1 は1-枝につながる 写像付き SeqBDD
– P0 は0-枝につながる 写像付き SeqBDD
31
P = P1.push(c) ∪ P0
N1
P1 f1
N0
P0 f0
N1 N0
f1' f0
' = I
f
c'
-
getSeqBDD • (1) ∃x( f0(x) = c )
– c’ = x
• (2) ∃x( f1(x) = c ) ⋀ ¬∃y( f0(y) = c ) – c’ = x
• (3) (1), (2) 以外のとき – c’ = min { x | f0(x) = x }
32
• c’ = x
• f = { c’ → c } f0 f1 • f1’ = f1 f
• f0 ’ = I N1
P1 f1
N0
P0 f0
N1 N0
f1' f0
' = I
f
c'
+
-
+
1-枝側の写像
P = P1.push(c) ∪ P0
0-枝側の写像
-
例: P = { abb, ad, bd, cb, d }
33
SeqBDD 写像付きSeqBDD
c b b
b d
1
a
P
1
2
3
5 4
I
I
I
I {2→b}
{3→b}
{2→d, 3→c, 4→b, 5→a}
P
I
-
既存のSeqBDDとの節点数の比較
• 既存の SeqBDD よりも節点が増加しない
• 写像付き SeqBDD の性質
–同じ接頭辞を共有
–同じ文字列集合の部分グラフを共有
–同じ文字列集合以外の部分グラフも共有
34
SeqBDDの性質
-
まとめ
• SeqBDD –文字列の集合を表現
• 逆順の文字列集合を表す SeqBDD の構築 – Applyを用いた手法ではなく、グラフのトポロジカル順序で処理
–単純な手法と比べて効率がよい
• 写像枝を用いた SeqBDD –一意に構築
–節点数を削減
35