Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
@ 2021 Loglass Inc. 1 木構造のデータって意外と多くない? Kotlinと探索アルゴリズムでスマートに 木構造データをさばく 2021/9/22 株式会社ログラス 佐藤有斗
Slide 2
Slide 2 text
@ 2021 Loglass Inc. 2 ● 佐藤 有斗(ゆいと) ● 株式会社ログラス ● TypeScriptとKotlinとScalaの民 ● 好きなゲーム: スマブラ、原神 # 自己紹介
Slide 3
Slide 3 text
@ 2021 Loglass Inc. 3 # 株式会社ログラスについて ● 創業2年目のシードスタートアップ ● プランニング・クラウド ● Kotlin × Spring Boot 次世代型プランニング・クラウド「Loglass」を開発するログラス、 ICCサミット 「カタパルト・グランプリ」で優勝 https://prtimes.jp/main/html/rd/p/000000036.000052025.html
Slide 4
Slide 4 text
@ 2021 Loglass Inc. 4 木構造のデータってよく使いますか?
Slide 5
Slide 5 text
@ 2021 Loglass Inc. 5 # 木構造のデータってこんなの(以下ツリーと呼びます) 1 11 13 12 111 112 1121
Slide 6
Slide 6 text
@ 2021 Loglass Inc. 6 # 世の中にツリーはとても多い ディレクトリ 部署 家系図 法人 タスク
Slide 7
Slide 7 text
@ 2021 Loglass Inc. 7 # Loglassにもたくさん出てくるツリー
Slide 8
Slide 8 text
@ 2021 Loglass Inc. 8 # よくあるケース: ツリーを他のツリーに変換したい 1 11 13 12 111 112 1121 10 110 130 120 1110 1120 11210 10倍!
Slide 9
Slide 9 text
@ 2021 Loglass Inc. 9 再帰関数を書くか、、、
Slide 10
Slide 10 text
@ 2021 Loglass Inc. 10 再帰関数を書くか、、、
Slide 11
Slide 11 text
@ 2021 Loglass Inc. 11 再帰関数を書くか、、、
Slide 12
Slide 12 text
@ 2021 Loglass Inc. 12 読みづらい😇
Slide 13
Slide 13 text
@ 2021 Loglass Inc. 13 # 普段使いにはつらい再帰関数 ● そもそも処理が追いづらい ○ 土日の趣味プログラミング以外で出会いたくない
Slide 14
Slide 14 text
@ 2021 Loglass Inc. 14 mapみたいな関数があればな〜〜〜〜〜〜〜
Slide 15
Slide 15 text
@ 2021 Loglass Inc. 15 例えば: listOf(1,2,3).map { it * 10 }
Slide 16
Slide 16 text
@ 2021 Loglass Inc. 16 tree.map { it * 10 } な感じで書きたいな〜
Slide 17
Slide 17 text
@ 2021 Loglass Inc. 17 よし、作ろう
Slide 18
Slide 18 text
@ 2021 Loglass Inc. 18 1. 木構造を抽象化する 2. mapのインターフェースを考える 3. mapの実装をする # Tree.mapを作るまでのステップ
Slide 19
Slide 19 text
@ 2021 Loglass Inc. 19 1. 木構造を抽象化する 2. mapのインターフェースを考える 3. mapの実装をする # Tree.mapを作るまでのステップ
Slide 20
Slide 20 text
@ 2021 Loglass Inc. 20 # 1. 木構造を抽象化する ● ジェネリクスを使って木構造の中のデータは何でもとれるようにする
Slide 21
Slide 21 text
@ 2021 Loglass Inc. 21 # 1. 木構造を抽象化する ● これでどんなデータでも木構造にできる! あ い え う Tree True False False Tree Hoge1 Hoge2 Hoge3 Tree
Slide 22
Slide 22 text
@ 2021 Loglass Inc. 22 1. 木構造を抽象化する 2. mapのインターフェースを考える 3. mapの実装をする # Tree.mapを作るまでのステップ
Slide 23
Slide 23 text
@ 2021 Loglass Inc. 23 # 2. mapのインターフェースを考える tree.map { it * 10 } な感じで書きたいな〜
Slide 24
Slide 24 text
@ 2021 Loglass Inc. 24 # 2. mapのインターフェースを考える tree.map { data -> data * 10 } ちょっと整形
Slide 25
Slide 25 text
@ 2021 Loglass Inc. 25 # 2. mapのインターフェースを考える tree.map { data -> data * 10 } ここは (Int) -> Int
Slide 26
Slide 26 text
@ 2021 Loglass Inc. 26 # 2. mapのインターフェースを考える tree.map { data -> data * 10 } つまり (Treeの中身) -> 変換したい型の関数
Slide 27
Slide 27 text
@ 2021 Loglass Inc. 27 # 2. mapのインターフェースを考える tree.map { data -> data * 10 } つまり (T) -> S の関数
Slide 28
Slide 28 text
@ 2021 Loglass Inc. 28 # 2. mapのインターフェースを考える 1 2 4 3 Tree あ い え う Tree f: (T) => S ● つまりこう
Slide 29
Slide 29 text
@ 2021 Loglass Inc. 29 1. 木構造を抽象化する 2. mapのインターフェースを考える 3. mapの実装をする # Tree.mapを作るまでのステップ
Slide 30
Slide 30 text
@ 2021 Loglass Inc. 30 # 3. mapの実装をする
Slide 31
Slide 31 text
@ 2021 Loglass Inc. 31 # 3. mapの実装をする 自分自身に関数を適用 さっきの 「1 -> “あ”」の関数
Slide 32
Slide 32 text
@ 2021 Loglass Inc. 32 # 3. mapの実装をする 子供全員に再帰関数を 適用する
Slide 33
Slide 33 text
@ 2021 Loglass Inc. 33 できた!
Slide 34
Slide 34 text
@ 2021 Loglass Inc. 34 全体像
Slide 35
Slide 35 text
@ 2021 Loglass Inc. 35 FIN
Slide 36
Slide 36 text
@ 2021 Loglass Inc. 36 ではない
Slide 37
Slide 37 text
@ 2021 Loglass Inc. 37
Slide 38
Slide 38 text
@ 2021 Loglass Inc. 38 10000階層のツリー
Slide 39
Slide 39 text
@ 2021 Loglass Inc. 39
Slide 40
Slide 40 text
@ 2021 Loglass Inc. 40 スタックオーバーフロー!!!
Slide 41
Slide 41 text
@ 2021 Loglass Inc. 41 # ⚠ここからは尺の関係上ざっくり説明します ● 全てを理解しようとしないでください ● あ〜こんなやり方あるんだな〜で大丈夫です 👍 ● コードはこちらです ○ https://github.com/YuitoSato/kotlin-sandbox/blob/master/src/main/kotlin/tree/Tre e.kt
Slide 42
Slide 42 text
@ 2021 Loglass Inc. 42 # 再帰関数におけるスタックオーバーフローとは ● 子の計算を全て終えないと親の関数が終わらない ○ 計算時の関数内ローカル変数をスタックに保持するが、そこがパンクする
Slide 43
Slide 43 text
@ 2021 Loglass Inc. 43 # では世の中の全ての再帰関数はスタックオーバーフローを起こすの? ● 言語によってはNo ● 一部の言語には末尾再帰最適化というものが実装されている
Slide 44
Slide 44 text
@ 2021 Loglass Inc. 44 # 末尾再帰最適化 (tail call optimization) とは~ ざっくり説明 ● 一部のプログラムではビルド時に 末尾呼び出しの再帰関数を単なる While文に最適化してい る
Slide 45
Slide 45 text
@ 2021 Loglass Inc. 45 # これは末尾再帰
Slide 46
Slide 46 text
@ 2021 Loglass Inc. 46 # これは末尾再帰ではない 最後に評価される関数は Treeのコンストラクタ
Slide 47
Slide 47 text
@ 2021 Loglass Inc. 47 別のやり方でやろう
Slide 48
Slide 48 text
@ 2021 Loglass Inc. 48 最適化が使えないので自力Whileをする
Slide 49
Slide 49 text
@ 2021 Loglass Inc. 49 # map処理のおさらい 1 2 4 3 5 6
Slide 50
Slide 50 text
@ 2021 Loglass Inc. 50 # map処理のおさらい あ 2 4 3 5 6
Slide 51
Slide 51 text
@ 2021 Loglass Inc. 51 # map処理のおさらい あ い 4 3 5 6
Slide 52
Slide 52 text
@ 2021 Loglass Inc. 52 # map処理のおさらい あ い 4 う 5 6
Slide 53
Slide 53 text
@ 2021 Loglass Inc. 53 # map処理のおさらい あ い え う 5 6
Slide 54
Slide 54 text
@ 2021 Loglass Inc. 54 # map処理のおさらい あ い え う お 6
Slide 55
Slide 55 text
@ 2021 Loglass Inc. 55 幅優先探索だ!💡
Slide 56
Slide 56 text
@ 2021 Loglass Inc. 56 # 幅優先探索にはキュー(先に入れたものが先に出る)を使う 1 2 4 3 5 6 処理待ちノードを入れるキュー 優先処理 1
Slide 57
Slide 57 text
@ 2021 Loglass Inc. 57 # 幅優先探索にはキュー(先に入れたものが先に出る)を使う あ 2 4 3 5 6 処理待ちノードを入れるキュー 優先処理 2 3 4 1
Slide 58
Slide 58 text
@ 2021 Loglass Inc. 58 # 幅優先探索にはキュー(先に入れたものが先に出る)を使う あ い 4 3 5 6 処理待ちノードを入れるキュー 優先処理 3 4 5 6 2
Slide 59
Slide 59 text
@ 2021 Loglass Inc. 59 # こう実装してみます
Slide 60
Slide 60 text
@ 2021 Loglass Inc. 60 # こう実装してみます キューと最終的に返す ツリーの初期化。
Slide 61
Slide 61 text
@ 2021 Loglass Inc. 61 # こう実装してみます キューから取り出して 関数を適用
Slide 62
Slide 62 text
@ 2021 Loglass Inc. 62 # こう実装してみます 処理したノードを 最終的なツリーに足す
Slide 63
Slide 63 text
@ 2021 Loglass Inc. 63 # こう実装してみます 次に処理されるノード(子 供)をキューにいれる
Slide 64
Slide 64 text
@ 2021 Loglass Inc. 64 # こう実装してみます 最後にリターン
Slide 65
Slide 65 text
@ 2021 Loglass Inc. 65 # イメージ: ① キューと空のツリーを用意する 1 2 4 3 5 6
Slide 66
Slide 66 text
@ 2021 Loglass Inc. 66 # イメージ: ② キューに積む 1 2 4 3 5 6 1
Slide 67
Slide 67 text
@ 2021 Loglass Inc. 67 # イメージ: ③ キューの先頭に関数を適用する 1 2 4 3 5 6 あ
Slide 68
Slide 68 text
@ 2021 Loglass Inc. 68 # イメージ: ④ キューの先頭を最終的なツリーに追加する 1 2 4 3 5 6 あ
Slide 69
Slide 69 text
@ 2021 Loglass Inc. 69 # イメージ: ④ 子供を全てキューに積む 1 2 4 3 5 6 あ 2 3 4
Slide 70
Slide 70 text
@ 2021 Loglass Inc. 70 # イメージ: ①~④を繰り返す 1 2 4 3 5 6 あ い え う お か
Slide 71
Slide 71 text
@ 2021 Loglass Inc. 71 できた!(強引)
Slide 72
Slide 72 text
@ 2021 Loglass Inc. 72 今回のコードはこちらに全てあります。 https://github.com/YuitoSato/kotlin-sandbox/blo b/master/src/main/kotlin/tree/Tree.kt
Slide 73
Slide 73 text
@ 2021 Loglass Inc. 73 # まとめ → 世の中にツリーは多い → ツリーのデータ変換は再帰関数が多くてつらい → map関数を作って再帰処理を隠蔽する → と思ったらスタックオーバーフローしてしまった → スタックオーバーフローを回避するために幅優先探索で実装する → ハッピー!
Slide 74
Slide 74 text
@ 2021 Loglass Inc. 74 ハッピー!(強引)
Slide 75
Slide 75 text
@ 2021 Loglass Inc. 75 # 余談: Q. スタックオーバーフローってどれくらいで起きるの? 🤔 A. 手元のマシンで試したら10000階層くらいで発生した(※JVM内で格納しているスタックの量 に寄ります)
Slide 76
Slide 76 text
@ 2021 Loglass Inc. 76 # 余談: Q. Loglassってそんな階層の深いツリーを扱うの? 🤔 A. 扱いません
Slide 77
Slide 77 text
@ 2021 Loglass Inc. 77 # 余談: Q. え、じゃあ幅優先探索の実装とか、必要、、? A. 要りません
Slide 78
Slide 78 text
@ 2021 Loglass Inc. 78 結論: ほぼほぼ再帰処理実装でOK(オチです)
Slide 79
Slide 79 text
@ 2021 Loglass Inc. 79 ありがとうございました! Kotlinで複雑なデータ構造に 立ち向かいたい人Welcomeです!