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

Numbered Automatonによる文字列の完全ハッシュ

MatsuTaku
November 12, 2019

Numbered Automatonによる文字列の完全ハッシュ

MatsuTaku

November 12, 2019
Tweet

Other Decks in Research

Transcript

  1. StringBeginners Vol. 9 19/11/12 @ Riken AIP 自己紹介 ❏ 名前:

    松本 拓真  Twitter :@MatsuTaku14 ❏ 所属: 徳島大学大学院先端技術科学教育部 M2 同大学博士後期進学予定 ❏ 研究: 文字列辞書、ダブル配列 ❏ ダブル配列オートマトンの圧縮手法、 DEIM Forum、2018 ❏ ダブル配列オートマトンによる圧縮文字列辞書の実装、 IFAT研究報告、2018 ❏ 趣味 ❏ 競技プログラミングAtCoder ❏ User: MatsuTaku, highest rating: 1392, highest perf 1933 ❏ 将棋: 将棋ウォーズ(ゲーム) 2級。相掛かり、角換わりの勉強中 ❏ アニメ鑑賞: Ufotable(fate, 鬼滅の刃), ufotable chinema徳島でアニメ映画鑑賞
  2. StringBeginners Vol. 9 19/11/12 @ Riken AIP 問題設定 ❏ 文字列集合を表現し,

    各文字列に異なる整数値IDを割り当てる string ID a 1 a b 2 b a 3 c a a 4 c b 5 ❏ 文字列集合{S1, … , Sn}は辞書順 に並んでいるとし, i番目の文字列SiのIDはiとする. ❏ string-to-ID (文字列→IDを応答) ID-to-string (ID→文字列を応答) の2つの機能を提供する
  3. StringBeginners Vol. 9 19/11/12 @ Riken AIP Trie ❏ 文字列集合を接頭辞を併合したグラフで表現

    ❏ 各文字列により一意の受理状態へ到達する string ID a 1 a b 2 b a 3 c a a 4 c b 5 1 2 5 3 4 a b b a c a a b Trieは,文字列の完全ハッシュを容易に実現する
  4. StringBeginners Vol. 9 19/11/12 @ Riken AIP Deterministic Finite Automaton

    ❏ DAWGが有名 (Trieより状態数を少なくできる) ❏ 全ての状態の入次数が1でない場合,受理状態と各文字列は対応しない string ID a 1 a b 2 b a 3 c a a 4 c b 5 a b b a c a b 完全ハッシュのための工夫が必要
  5. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automaton [1]

    ❏ DFAのパスに整数値の重みを 割り当てることで,string-to-IDとID-to-stringを実現 string ID a 1 a b 2 b a 3 c a a 4 c b 5 a | 2 b | 1 b | 1 c | 2 a | 1 b | 1 | 5 重み:遷移先以降の経路パターンの数 a | 1
  6. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automaton [1]

    string ID a 1 a b 2 b a 3 c a a 4 c b 5 a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 重み:遷移先以降の経路パターンの数 ❏ DFAのパスに整数値の重みを 割り当てることで,string-to-IDとID-to-stringを実現
  7. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automaton [1]

    string ID a 1 a b 2 b a 3 c a a 4 c b 5 a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 重み:遷移先以降の経路パターンの数 ❏ DFAのパスに整数値の重みを 割り当てることで,string-to-IDとID-to-stringを実現
  8. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automaton [1]

    string ID a 1 a b 2 b a 3 c a a 4 c b 5 a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 重み:遷移先以降の経路パターンの数 ❏ DFAのパスに整数値の重みを 割り当てることで,string-to-IDとID-to-stringを実現
  9. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonによる string-to-ID

    入力文字列: Sin 出力ID: IDout w(p): パスpの重み カウンター変数: C = 0 a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 Sinによる経路上の各状態で以下を実行 ❏ if 受理状態 C = C + 1 ❏ for p ∈ 現在の状態のパスから辞書順: if pが経路ではない C = C + w(p) else 遷移を実行し,次の状態へ Sinによる遷移が終了したとき,C = IDout {
  10. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonによる string-to-ID

    入力文字列: Sin = ‘caa’ 出力ID: IDout = 4 w(p): パスpの重み カウンター変数: C = 0 a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 Sinによる経路上の各状態で以下を実行 ❏ if 受理状態 C = C + 1 ❏ for p ∈ 現在の状態のパスから辞書順: if pが経路ではない C = C + w(p) else 遷移を実行し,次の状態へ Sinによる遷移が終了したとき,C = IDout { C = 0
  11. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonによる string-to-ID

    入力文字列: Sin = ‘caa’ 出力ID: IDout = 4 w(p): パスpの重み カウンター変数: C = 0 a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 Sinによる経路上の各状態で以下を実行 ❏ if 受理状態 C = C + 1 ❏ for p ∈ 現在の状態のパスから辞書順: if pが経路ではない C = C + w(p) else 遷移を実行し,次の状態へ Sinによる遷移が終了したとき,C = IDout { C = 0 + 2 = 2
  12. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonによる string-to-ID

    入力文字列: Sin = ‘caa’ 出力ID: IDout = 4 w(p): パスpの重み カウンター変数: C = 0 a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 Sinによる経路上の各状態で以下を実行 ❏ if 受理状態 C = C + 1 ❏ for p ∈ 現在の状態のパスから辞書順: if pが経路ではない C = C + w(p) else 遷移を実行し,次の状態へ Sinによる遷移が終了したとき,C = IDout { C = 2 + 1 = 3
  13. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonによる string-to-ID

    入力文字列: Sin = ‘caa’ 出力ID: IDout = 4 w(p): パスpの重み カウンター変数: C = 0 a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 Sinによる経路上の各状態で以下を実行 ❏ if 受理状態 C = C + 1 ❏ for p ∈ 現在の状態のパスから辞書順: if pが経路ではない C = C + w(p) else 遷移を実行し,次の状態へ Sinによる遷移が終了したとき,C = IDout { C = 3
  14. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonによる string-to-ID

    入力文字列: Sin = ‘caa’ 出力ID: IDout = 4 w(p): パスpの重み カウンター変数: C = 0 a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 Sinによる経路上の各状態で以下を実行 ❏ if 受理状態 C = C + 1 ❏ for p ∈ 現在の状態のパスから辞書順: if pが経路ではない C = C + w(p) else 遷移を実行し,次の状態へ Sinによる遷移が終了したとき,C = IDout { C = 3 + 1 = 4 IDout = C = 4
  15. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonによる ID-to-string

    入力ID: IDin 出力文字列: Sout w(p): パスpの重み カウンター変数: C = IDin a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 ❏ for p ∈ 現在の状態のパスから辞書順: if w(p) < C C = C - w(p) if w(p) > C pによる遷移を実行 if w(p) = C pによる遷移を実行 if 受理状態 C = C - 1 if C = 0 return 経路上の文字列 {
  16. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonによる ID-to-string

    入力ID: IDin = 4 出力文字列: Sout = ‘caa’ w(p): パスpの重み カウンター変数: C = IDin a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 ❏ for p ∈ 現在の状態のパスから辞書順: if w(p) < C C = C - w(p) if w(p) > C pによる遷移を実行 if w(p) = C pによる遷移を実行 if 受理状態 C = C - 1 if C = 0 return 経路上の文字列 { C = 4
  17. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonによる ID-to-string

    入力ID: IDin = 4 出力文字列: Sout = ‘caa’ w(p): パスpの重み カウンター変数: C = IDin a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 ❏ for p ∈ 現在の状態のパスから辞書順: if w(p) < C C = C - w(p) if w(p) > C pによる遷移を実行 if w(p) = C pによる遷移を実行 if 受理状態 C = C - 1 if C = 0 return 経路上の文字列 { C = 4 - 2 = 2
  18. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonによる ID-to-string

    入力ID: IDin = 4 出力文字列: Sout = ‘caa’ w(p): パスpの重み カウンター変数: C = IDin a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 ❏ for p ∈ 現在の状態のパスから辞書順: if w(p) < C C = C - w(p) if w(p) > C pによる遷移を実行 if w(p) = C pによる遷移を実行 if 受理状態 C = C - 1 if C = 0 return 経路上の文字列 { C = 2 - 1 = 1
  19. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonによる ID-to-string

    入力ID: IDin = 4 出力文字列: Sout = ‘caa’ w(p): パスpの重み カウンター変数: C = IDin a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 ❏ for p ∈ 現在の状態のパスから辞書順: if w(p) < C C = C - w(p) if w(p) > C pによる遷移を実行 if w(p) = C pによる遷移を実行 if 受理状態 C = C - 1 if C = 0 return 経路上の文字列 { C = 1
  20. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonによる ID-to-string

    入力ID: IDin = 4 出力文字列: Sout = ‘caa’ w(p): パスpの重み カウンター変数: C = IDin a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 ❏ for p ∈ 現在の状態のパスから辞書順: if w(p) < C C = C - w(p) if w(p) > C pによる遷移を実行 if w(p) = C pによる遷移を実行 if 受理状態 C = C - 1 if C = 0 return 経路上の文字列 { C = 1
  21. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonによる ID-to-string

    入力ID: IDin = 4 出力文字列: Sout = ‘caa’ w(p): パスpの重み カウンター変数: C = IDin a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5 ❏ for p ∈ 現在の状態のパスから辞書順: if w(p) < C C = C - w(p) if w(p) > C pによる遷移を実行 if w(p) = C pによる遷移を実行 if 受理状態 C = C - 1 if C = 0 return 経路上の文字列 { C = 1 - 1 = 0 Sout = ‘caa’
  22. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonによる string-to-ID,

    ID-to-string ❏ string-to-ID,ID-to-stringの何れも, オートマトンを順方向に探索することで実現できる ❏ 比較回数は,経路上の状態が持つパス数に依存 a | 2 b | 1 b | 1 a | 1 c | 2 a | 1 b | 1 | 5
  23. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automaton ~

    順位数version ~ ❏ 順位数:親の状態から辞書順でパスを見たときの,若いパスの重みの合計 a | 2 → 0 b | 1 → 0 b | 1 → 2 a | 1 → 0 c | 2 → 3 a | 1 → 0 b | 1 → 0 | 5 → 0 重み → 順位数 a | w1 → 0 b | w2 → w1 c | w3 → w1+w2
  24. StringBeginners Vol. 9 19/11/12 @ Riken AIP 順位数を用いた string-to-ID 入力文字列:

    Sin 出力ID: IDout r(p): パスpの順位数 カウンター変数: C = 0 a | 0 b | 0 b | 2 a | 0 c | 3 a | 0 b | 0 | 0 Sinによる経路上の各状態で以下を実行 ❏ if 受理状態 C = C + 1 ❏ C = C + r(p) Sinによる遷移が終了したとき,C = IDout {
  25. StringBeginners Vol. 9 19/11/12 @ Riken AIP 順位数を用いた string-to-ID 入力文字列:

    Sin = ‘caa’ 出力ID: IDout = 4 r(p): パスpの順位数 カウンター変数: C = 0 a | 0 b | 0 b | 2 a | 0 c | 3 a | 0 b | 0 | 0 Sinによる経路上の各状態で以下を実行 ❏ if 受理状態 C = C + 1 ❏ C = C + r(p) Sinによる遷移が終了したとき,C = IDout { IDout = 0 + 3 + 0 + 0 + 1 = 4
  26. StringBeginners Vol. 9 19/11/12 @ Riken AIP 順位数を用いた ID-to-string 入力ID:

    IDin 出力文字列: Sout r(p): パスpの順位数 カウンター変数: C = 0 重み変数: W = 5 a | 0 b | 0 b | 2 a | 0 c | 3 a | 0 b | 0 5 | 0 ❏ for p ∈ 現在の状態のパスから辞書順: if pが最後のパスではない: w = r(pの次のパス) - r(p) else: w = W - r(p) if w < C C = C - w if w > C pによる遷移を実行,W = w if w = C pによる遷移を実行,W = w if 受理状態 C = C - 1 if C = 0 return 経路上の文字列 { ルートの重みだけ必要
  27. StringBeginners Vol. 9 19/11/12 @ Riken AIP 順位数を用いた ID-to-string 入力ID:

    IDin 出力文字列: Sout r(p): パスpの順位数 カウンター変数: C = 0 重み変数: W = 5 a | 0 b | 0 b | 2 a | 0 c | 3 a | 0 b | 0 5 | 0 ❏ for p ∈ 現在の状態のパスから辞書順: if pが最後のパスではない: w = r(pの次のパス) - r(p) else: w = W - r(p) if w < C C = C - w if w > C pによる遷移を実行,W = w if w = C pによる遷移を実行,W = w if 受理状態 C = C - 1 if C = 0 return 経路上の文字列 { ルートの重みだけ必要 ① 5 ② 元々の重み =順位数の差分 ② 次のパスの順位数との 差分から重みを取り出す 後の操作は同じ
  28. StringBeginners Vol. 9 19/11/12 @ Riken AIP 順位数を用いた ID-to-string 入力ID:

    IDin 出力文字列: Sout r(p): パスpの順位数 カウンター変数: C = 0 重み変数: W = 5 a | 0 b | 0 b | 2 a | 0 c | 3 a | 0 b | 0 5 | 0 ❏ for p ∈ 現在の状態のパスから辞書順: if pが最後のパスではない: w = r(pの次のパス) - r(p) else: w = W - r(p) if w < C C = C - w if w > C pによる遷移を実行,W = w if w = C pによる遷移を実行,W = w if 受理状態 C = C - 1 if C = 0 return 経路上の文字列 { ルートの重みだけ必要 5 競技単調増加列の中から C以下の最大のパスを探す 問題と考えられる.
  29. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonの特徴 ❏

    グラフ表現の自由度が高い ❏ 状態数削減のモチベーションが高い用途で有効かも ❏ 効率的かどうかは,どう実装するかに依存する. ❏ オートマトンはTrieの様に簡潔表現(LOUDS)がなく, 単純に空間効率が良くなるとは言えない ❏ 順位数ver ❏ string-to-IDの改善も, 遷移先が簡単に定まるデータ構造で実装した場合に限る ❏ ID-to-string は,次の遷移先が簡単に求まる実装でなければ非効率
  30. StringBeginners Vol. 9 19/11/12 @ Riken AIP 重みのデータ量としての特徴 ❏ 親の重み

    = 子のパスの重みの合計 つまり,階層が深くなれば重みは小さい値になる したがって,全体として重みはほとんどが非常に小さい値で表現される →符号化圧縮表現が可能 (DACs, Elias-Fano) 重み,順位数 英語Wikipediaタイトル集合のDAWG 表現での重みと順位数
  31. StringBeginners Vol. 9 19/11/12 @ Riken AIP Numbered Automatonの応用 ❏

    実用例がまだ少ない ❏ 順位数 ❏ 順位数を用いたDAWG辞書の実装(string-to-ID only)[2,3](blog) ❏ 重みと順位数ハイブリッドによる圧縮文字列辞書[4] ❏ 静的な用途に向いている ❏ 動的なオートマトンの構築は計算コストが高い ❏ 重みや順位数を圧縮できる
  32. StringBeginners Vol. 9 19/11/12 @ Riken AIP 参考文献 [1] Martn-Vide,

    C.: Scientific Applications of Language Methods (2011). [2]伊藤, 辞書検索に用いる有限オートマトンの構成と実装、言語処理学会Vol.4. pp47-50. 1998. [3]sileのブログ。http://sile.hatenablog.jp/entry/20100710/1278784402 [4] 松本,神田,森田,泓田、ダブル配列オートマトンによる圧縮文字列辞書の実装、 IPSJ/IFAT研究報告、2018.