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

Path Copying による永続データ構造

Da19e6f67889fbbd41efd3a5d3448f3c?s=47 toyama
July 18, 2020

Path Copying による永続データ構造

Da19e6f67889fbbd41efd3a5d3448f3c?s=128

toyama

July 18, 2020
Tweet

Transcript

  1. Path Copying と永続データ構造 会津大学 学部1年 児島大和

  2. 自己紹介
 • HN: 遠山 (twitter:@toyama_pts) • 絵を描いています • AtCoder: 青(highest)

  3. 永続データ構造ってなに?
 • 変更を加えても以前のデータが保存されている ◦ 破壊的変更を絶対に許さない • どのバージョンに対しても変更を行える • 今回は木構造の永続化について扱います

  4. 今回扱う木構造
 • 親から子へリンクを持つ有向木

  5. 今回扱う木構造
 • 親から子へリンクを持つ有向木 ◦ 二分探索木 7 5 8 2 6

    1 3 9
  6. 今回扱う木構造
 • 親から子へリンクを持つ有向木 ◦ セグメント木 (区間和を高速に取れる配列) a1+a2+a3+a4+a5+a6+a7+a8 a1+a2+a3+a4 a5+a6+a7+a8 a1+a2

    a3+a4 a5+a6 a7+a8 a1 a2 a3 a4 a5 a6 a7 a8
  7. 永続化

  8. ナイーブ解法
 • 変更前の構造をまるっとコピー 7 5 8 2 6 9

  9. ナイーブ解法
 • 変更前の構造をまるっとコピー 7 5 8 2 6 9 7

    5 8 2 6 9 全コピー
  10. ナイーブ解法
 • 変更前の構造をまるっとコピー 7 5 8 2 6 9 7

    5 8 1 6 9 全コピー
  11. ナイーブ解法
 • 変更前の構造をまるっとコピー • 空間計算量さん!? 7 5 8 2 6

    9 7 5 8 1 6 9 全コピー
  12. ナイーブ解法
 • 変更前の構造をまるっとコピー • 空間計算量さん!? • 時間計算量さん!!? 7 5 8

    2 6 9 7 5 8 1 6 9 全コピー
  13. ナイーブ解法
 • 変更前の構造をまるっとコピー • 空間計算量さん!? • 時間計算量さん!!? ◦ 二分探索木は O(log

    N) でデータ追加できた ◦ しかし O(N) に悪化してしまった!(ヤバい) 7 5 8 2 6 9 7 5 8 1 6 9 全コピー
  14. スマート解法 (Path Copying)
 • 同じデータをたくさんコピーしていて無駄っぽい

  15. スマート解法 (Path Copying)
 • コピーする必要のあるノードを考える 5 3 6 2 4

    7 5 3 6 2 4 9
  16. スマート解法 (Path Copying)
 5 3 6 2 4 7 5

    3 6 2 4 7 9 • コピーする必要のあるノードを考える
  17. スマート解法 (Path Copying)
 5 3 6 2 4 7 5

    3 6 2 4 7 9 • コピーする必要のあるノードを考える • 旧6から新9へ辺をつなげば良さそう....?
  18. スマート解法 (Path Copying)
 5 3 6 2 4 7 5

    3 6 2 4 7 9 • コピーする必要のあるノードを考える • 旧6から新9へ辺をつなげば良さそう....? 子を辿るときどちらへ行けば分からない
  19. スマート解法 (Path Copying)
 5 3 6 2 4 7 5

    3 6 2 4 7 9 6 • コピーする必要のあるノードを考える
  20. スマート解法 (Path Copying)
 5 3 6 2 4 7 5

    3 6 2 4 7 9 6 5 • コピーする必要のあるノードを考える
  21. スマート解法 (Path Copying)
 5 3 6 2 4 7 5

    3 6 2 4 7 9 6 5 • コピーする必要のあるノードを考える
  22. スマート解法 (Path Copying)
 5 3 6 2 4 7 5

    3 6 2 4 7 9 6 5 • コピーする必要のあるノードを考える • 変更ノードから根までをコピー • 根から一意に探索可能
  23. スマート解法 (Path Copying)
 5 3 6 2 4 7 5

    3 6 2 4 7 9 6 5 • コピーする必要のあるノードを考える • 変更ノードから根までをコピー • 根から一意に探索可能 うれしい!!!!
  24. 子から親へ辺があると...
 5 3 6 2 4 7 5 3 6

    2 4 7 9 6 5
  25. 子から親へ辺があると...
 5 3 6 2 4 7 5 3 6

    2 4 7 9 6 5
  26. 子から親へ辺があると...
 5 3 6 2 4 7 5 3 6

    2 4 7 9 6 5 親を辿るときどちらへ行けば....?
  27. 子から親へ辺があると...
 5 3 6 2 4 7 5 3 6

    2 4 7 9 6 5 うれしくない.... • Path Copying で効率的な永続化は難しい
  28. 使用例
 • 永続配列 0 1 2 3 4 5 6

    7
  29. 使用例
 • 永続配列 0 1 2 3 4 5 6

    7
  30. 使用例
 • 永続配列 0 1 2 3 4 5 6

    7
  31. 使用例
 • 永続配列 0 1 2 3 4 5 6

    7
  32. 使用例
 • 永続配列 0 1 2 3 4 5 6

    7
  33. 使用例
 • 永続配列 0 1 2 3 4 5 6

    7
  34. 使用例
 • 永続配列 0 1 2 3 4 5 6

    7
  35. 使用例
 • 永続配列 0 1 2 3 4 5 6

    7
  36. 使用例
 • 永続配列 0 1 2 3 4 5 6

    7
  37. 永続データ構造使用例
 • 矩形和を処理 ◦ 時間軸を縦軸と見立てる 0 0 0 0 0

    0 0 0 ver.1
  38. 永続データ構造使用例
 • 矩形和を処理 ◦ 時間軸を縦軸と見立てる 0 0 0 0 0

    0 0 0 ver.1 0 0 0 0 0 0 0 0 ver.2
  39. 永続データ構造使用例
 • 矩形和を処理 ◦ 時間軸を縦軸と見立てる 0 0 0 0 0

    0 0 0 ver.1 0 0 2 0 0 4 0 0 ver.2 [2] += 2, [5] += 4
  40. 永続データ構造使用例
 • 矩形和を処理 ◦ 時間軸を縦軸と見立てる 0 0 0 0 0

    0 0 0 ver.1 0 0 2 0 0 4 0 0 ver.2 0 0 2 0 0 4 0 0 ver.3
  41. 永続データ構造使用例
 • 矩形和を処理 ◦ 時間軸を縦軸と見立てる 0 0 0 0 0

    0 0 0 ver.1 0 0 2 0 0 4 0 0 ver.2 1 0 3 0 0 4 0 0 ver.3 [0] += 1, [2] += 1
  42. 永続データ構造使用例
 • 矩形和を処理 ◦ 時間軸を縦軸と見立てる 0 0 0 0 0

    0 0 0 ver.1 0 0 2 0 0 4 0 0 ver.2 1 0 3 0 0 4 0 0 ver.3 1 0 3 0 0 4 0 0 ver.4
  43. 永続データ構造使用例
 • 矩形和を処理 ◦ 時間軸を縦軸と見立てる 0 0 0 0 0

    0 0 0 ver.1 0 0 2 0 0 4 0 0 ver.2 1 0 3 0 0 4 0 0 ver.3 1 3 3 0 0 6 0 0 ver.4 [1] += 3, [5] += 2
  44. 永続データ構造使用例
 • 矩形和を処理 ◦ 時間軸を縦軸と見立てる 0 0 0 0 0

    0 0 0 ver.1 0 0 2 0 0 4 0 0 ver.2 1 0 3 0 0 4 0 0 ver.3 1 3 3 0 0 6 0 0 ver.4 y=[1, 4] x=[1, 3]の和
  45. 永続データ構造使用例
 • 矩形和を処理 ◦ 時間軸を縦軸と見立てる 0 0 0 0 0

    0 0 0 ver.1 0 0 2 0 0 4 0 0 ver.2 1 0 3 0 0 4 0 0 ver.3 1 3 3 0 0 6 0 0 ver.4 y=[1, 2], x=[1, 3]の和
  46. 永続データ構造使用例
 • 矩形和を処理 ◦ 時間軸を縦軸と見立てる • 累積和で区間和を計算するのと同じ要領で矩形和を処理可能 0 0 0

    0 0 0 0 0 ver.1 0 0 2 0 0 4 0 0 ver.2 1 0 3 0 0 4 0 0 ver.3 1 3 3 0 0 6 0 0 ver.4
  47. まとめ -メリット
 • コピーが効率的(大抵 O(1)) ◦ 参照じゃないよ! ◦ 差分の小さい構造をたくさん作るとき有利 •

    適用範囲が広い • 実現方法が美しい カッコいい 憧れる
  48. まとめ -デメリット
 • やっぱりメモリは食う • デストラクタの実装が難 ◦ std::shared_ptr を使うと遅い... •

    ならし計算量が壊れるかも • 競プロでさえ使うことは少ない
  49. 実装例
 • 僕の github にあります (C++) ◦ https://toyama1710.github.io/cpp_library

  50. ご清聴あり がとうござ いました!