O slideshow foi denunciado.
Seu SlideShare está sendo baixado. ×

JOI春季ステップアップセミナー 2021 講義スライド

Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Próximos SlideShares
Optimization night 4_dp
Optimization night 4_dp
Carregando em…3
×

Confira estes a seguir

1 de 115 Anúncio

JOI春季ステップアップセミナー 2021 講義スライド

Baixar para ler offline

アルゴリズムを学ぶ中学生・高校生のための勉強会セミナー (JOI 春季ステップアップセミナー 2021) で講義した資料です!

『アルゴリズムを学ぶとどんな世界が広がるか 〜 グラフを中心として 〜』

セミナーページ:https://www.ioi-jp.org/seminar/2020/spring-semi.html

アルゴリズムを学ぶ中学生・高校生のための勉強会セミナー (JOI 春季ステップアップセミナー 2021) で講義した資料です!

『アルゴリズムを学ぶとどんな世界が広がるか 〜 グラフを中心として 〜』

セミナーページ:https://www.ioi-jp.org/seminar/2020/spring-semi.html

Anúncio
Anúncio

Mais Conteúdo rRelacionado

Diapositivos para si (20)

Semelhante a JOI春季ステップアップセミナー 2021 講義スライド (14)

Anúncio

Mais recentes (20)

JOI春季ステップアップセミナー 2021 講義スライド

  1. 1. アルゴリズムを学ぶと どんな世界が広がるか ~ グラフを中心として ~ NTT データ数理システム 大槻 兼資 (ペンネーム:けんちょん) 2021/3/27 @JOI春季ステップアップセミナー 1
  2. 2. • 積極的に声やチャットで喋ってもらえたら嬉しいです 最初に 2 • 「ちゃんと理解しなきゃ」と堅くならずに、気楽に • アルゴリズム、競プロを楽しもう!
  3. 3. • 2014年:東京大学大学院情報理工学系研究科 数理情報学専攻修士課程修了 自己紹介 (本業編) • 2015年~:NTT データ数理システム • 専門は数理工学全般 • アルゴリズム • 探索, ネットワーク, etc… • 数理最適化 • シフトスケジューリングなど • 機械学習 • チャットボットなど http://www.dis.uniroma1.it/challenge9/download.shtml 3
  4. 4. 4 自己紹介 (趣味編) (3月27日) (7 の形) (1234567890 で「コ」) • 虫食算作り • コミケなどにも出店 • 競技プログラミング
  5. 5. 自己紹介 (趣味編) (全部虫食い) (たのしい) (将棋: 美濃囲い) • 虫食算作り • コミケなどにも出店 • 競技プログラミング
  6. 6. 6 アルゴリズムとは • ある問題を解くための方法、手順のこと • それを実装したものがプログラム 「うまくやるための手順書」 というイメージ https://ja.wikipedia.org/wiki/%E6%95%B0%E7%8B%AC
  7. 7. 7 アルゴリズムの身近な例 • 料理のレシピ • ゲームの攻略法 • 英単語の辞書での調べ方 • 3 の倍数の判定方法 / 99
  8. 8. 8 アルゴリズム本に込めた想い • アルゴリズムは、実際の問題解決に活かしてナンボ • 「~法」の知識の紹介だけでは終わらない • 「具体的な問題の解き方」を詳しく解説
  9. 9. 9 アルゴリズム本に込めた想い 設計技法 ・本の最初に設計技法を特集 ・本の全体で設計技法を使用 第 1 章 アルゴリズムとは 第 2 章 計算量とオーダー記法 第 3 章 全探索 第 4 章 再帰と分割統治法 第 5 章 動的計画法 第 6 章 二分探索法 第 7 章 貪欲法 第 8 章 配列、連結リスト ハッシュテーブル 第 9 章 スタックとキュー 第 10 章 グラフと木 第 11 章 Union-Find 第 12 章 ソート 第 13 章 グラフ探索 第 14 章 最短路問題 第 15 章 最小全域木問題 第 16 章 ネットワークフロー 第 17 章 P と NP 第 18 章 難問対策 データ構造 グラフ
  10. 10. 10 アルゴリズム本に込めた想い 設計技法 赤字の章が今回の話に関係 第 1 章 アルゴリズムとは 第 2 章 計算量とオーダー記法 第 3 章 全探索 第 4 章 再帰と分割統治法 第 5 章 動的計画法 第 6 章 二分探索法 第 7 章 貪欲法 第 8 章 配列、連結リスト ハッシュテーブル 第 9 章 スタックとキュー 第 10 章 グラフと木 第 11 章 Union-Find 第 12 章 ソート 第 13 章 グラフ探索 第 14 章 最短路問題 第 15 章 最小全域木問題 第 16 章 ネットワークフロー 第 17 章 P と NP 第 18 章 難問対策 データ構造 グラフ
  11. 11. 11 本格的な例:幅優先探索 • 迷路の最短路を求めよう! • スタート (S) からゴール (G) への最短経路は?
  12. 12. 12 幅優先探索 • まず S から 1 手で行けるマスに「1」と書く
  13. 13. 13 幅優先探索 • 次に「1」から 1 手で行けるマスに「2」と書く
  14. 14. 14 幅優先探索 • 「2」から 1 手で行けるマスに「3」と書く
  15. 15. 15 幅優先探索 • 「3」から 1 手で行けるマスに「4」と書く
  16. 16. 16 幅優先探索 • 「4」から 1 手で行けるマスに「5」と書く
  17. 17. 17 幅優先探索 • 「5」から 1 手で行けるマスに「6」と書く
  18. 18. 18 幅優先探索 • 「6」から 1 手で行けるマスに「7」と書く
  19. 19. 19 幅優先探索 • 「7」から 1 手で行けるマスに「8」と書く
  20. 20. 20 幅優先探索 • 「8」から 1 手で行けるマスに「9」と書く
  21. 21. 21 幅優先探索 • 「9」から 1 手で行けるマスに「10」と書く
  22. 22. 22 幅優先探索 • 「10」から 1 手で行けるマスに「11」と書く
  23. 23. 23 幅優先探索 • 「11」から 1 手で行けるマスに「12」と書く
  24. 24. 24 幅優先探索 • 「12」から 1 手で行けるマスに「13」と書く
  25. 25. 25 幅優先探索 • 「13」から 1 手で行けるマスに「14」と書く
  26. 26. 26 幅優先探索 • 「14」から 1 手で行けるマスに「15」と書く
  27. 27. 27 幅優先探索 • 「15」から 1 手で行けるマスに「16」と書く • これでゴール!!!
  28. 28. 28 幅優先探索 • ゴールから、「数値が 1 ずつ下がっていくように」 遡っていくと、最短経路が得られる
  29. 29. 29 幅優先探索の実応用 • カーナビ • 電車の乗り換え案内 • パズル (15-パズルなど) の最小手数
  30. 30. 30 今日の話 • アルゴリズムとは (ここまで終わった) • アルゴリズムを学んで広がる世界 (グラフも) • グラフ探索:深さ優先探索と幅優先探索 • 数学のすすめ
  31. 31. 31 今日の話 • アルゴリズムを学んで広がる世界 (グラフも)
  32. 32. 32 アルゴリズムを学ぶ動機は様々 • 競技プログラミングで勝ちたい! • コンピュータサイエンスの重要な一分野として 学んでおきたい • ソフトウェアエンジニアとしてステップアップしたい • 就職で有利にしたい! どんな人にもオススメ!!
  33. 33. 33 アルゴリズムで身に付く力 • 問題を理解する力 (理解力) • ロジカルに考える力 (思考力) • コーディング力 (技術力) • アルゴリズムを説明する力 (説明力) • 何かを楽しんで主体的に学んだ経験そのもの 一生モノのスキル
  34. 34. 34 アルゴリズムと IT 技術 • AI や量子コンピュータなどの、分野の流行に依らない 一生モノのスキル • むしろ AI を学ぶための強力な下地となる • さまざまな分野で、問題解決に寄与する • サービス, インフラ, 物流, 製造, 公共, ヘルスケア, etc… • 世の中に溢れるライブラリなどの速度性能向上の勘所を つかんだり、より上手に応用したりできるようになる
  35. 35. 35 アルゴリズムによる問題解決 数理モデル化 AtCoder みたいな問題 解 解釈・意思決定 アルゴリズム
  36. 36. 36 数理モデル化の例:グラフ • 物事の関係性を「丸」と「線」を用いて表したもの • コンピュータサイエンスのあらゆる領域で使われる 頂点 辺
  37. 37. 37 • 辺に「向き」があることもある (有向グラフ) 数理モデル化の例:グラフ
  38. 38. • あれもこれも実はグラフ! • さまざまな分野の問題をグラフに関する問題として 見通よく汎用的に扱える! 38 数理モデル化の精神 数理モデル化の例:グラフ
  39. 39. 例(1):友人関係 • 頂点:人間 39 • 辺:友人関係 タスク例 A さんの友達の友達が 何人いるか求める (グラフのデータ構造, 10 章)
  40. 40. 例(2):鉄道路線図 • 頂点:駅 40 • 辺:線路 タスク例 A 駅から B 駅への 最短経路を求める (Dijkstra 法, 14 章)
  41. 41. 例(3):数独ソルバー • 頂点:局面 41 • 辺:局面遷移 タスク例 数独の解を求める (深さ優先探索, 13 章) 2 3 2 2 1 1 1 2 3 2 2 1 1 2 3 2 2 1 1 3 2 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1 2 3 2 2 1 1 3 2 3 2 2 1 1 3 2 3 2 2 1 1 3 1 2 3
  42. 42. 例(4):8パズルの最小手数 • 頂点:局面 42 • 辺:局面遷移 タスク例 8パズルの 最小手数を求める (幅優先探索, 13 章) 2 7 3 4 1 5 8 6 2 7 3 4 1 5 8 6 2 7 3 4 1 5 8 6 2 7 3 4 1 5 8 6 2 7 3 4 1 5 8 6 2 7 3 4 1 5 8 6 2 7 3 4 1 5 8 6 2 7 3 4 1 5 8 6 2 7 3 4 1 5 8 6 2 7 3 4 1 5 8 6 2 7 3 4 1 5 8 6 2 7 3 4 1 5 8 6 2 7 3 4 1 5 8 6 1 8 3 2 4 5 7 6 1 8 3 7 4 5 2 6 3 8 5 4 1 2 7 6 3 7 5 4 1 6 2 8 目標配置 初期配置
  43. 43. 例(5):タスクの依存関係 • 頂点:タスク 43 • 辺:依存関係 タスク例 タスクの適切な順序 を決定する (トポロジカルソート, 13 章) 皿洗い 食事 帰宅 歯磨き 風呂 就寝
  44. 44. 例(6):電気回路 • 頂点:素子 44 • 辺:導線 タスク例 有向グラフ (電流の向き考慮) の有向閉路を検出 (深さ優先探索, 13 章)
  45. 45. 例(7):家系図 • 頂点:家族 45 • 辺:血縁関係 タスク例 A さんと B さんの 最近の共通祖先を求める (LCA)
  46. 46. 例(8):化学式 • 頂点:原子 46 • 辺:原子の結合 タスク例 CnH2n+2 の 異性体の個数を数え上げる (形式的冪級数) O OH
  47. 47. 例(9):しりとり • 頂点:文字 47 • 辺:単語 タスク例 すべての単語を用いた しりとりを見つける (Euler 路) d DNA の部分系列の集まり から全体を復元する問題 などに応用あり g dog m gram good dim a and arm t tea team
  48. 48. 例(10):マッチング • 頂点:「男」と「女」 48 • 辺:恋愛対象 タスク例 最大で何組のペアを 作れるかを求める (二部マッチング, 16 章) 極めて多彩な応用あり
  49. 49. • あれもこれも実はグラフ! • さまざまな分野の問題をグラフに関する問題として 見通よく汎用的に扱える! 49 数理モデル化の精神 グラフのすごさ (再掲)
  50. 50. 50 今日の話 • グラフ探索:深さ優先探索と幅優先探索
  51. 51. 51 グラフ探索の考え方 0 1 4 2 3 5 7 6 • グラフの各頂点を順に 探索して行きたい 2 3 2 2 1 1 1 2 3 2 2 1 1 2 3 2 2 1 1 3 2 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1 2 3 2 2 1 1 3 2 3 2 2 1 1 3 2 3 2 2 1 1 3 1 2 3 探索しないと頂点集合が 判明しない 8
  52. 52. 52 グラフ探索の考え方 0 1 4 2 3 5 7 6 • まずは頂点 0 を訪問 8
  53. 53. 53 グラフ探索の考え方 0 1 4 2 3 5 7 6 • todo リスト更新 todo リスト 頂点 1 頂点 4 頂点 2 頂点 0 から直接行ける頂点を 「あとで読む」という意味を 込めて todo リストに 赤:訪問済み 橙:todo 8
  54. 54. 54 グラフ探索の考え方 0 1 4 2 3 5 7 6 • todo リストから頂点 1 を取り出す 赤:訪問済み 橙:todo 8 todo リスト 頂点 4 頂点 2
  55. 55. 55 グラフ探索の考え方 0 1 4 2 3 8 5 7 6 • todo リスト更新 todo リスト 頂点 4 頂点 2 赤:訪問済み 橙:todo 頂点 3 頂点 8 頂点 1 から直接行ける頂点 3, 8 を todo リストに追加
  56. 56. 56 グラフ探索の考え方 0 1 4 2 3 8 5 7 6 • 次の探索は?? 赤:訪問済み 橙:todo どちらを優先して取り出す? ・最初に追加された頂点 4, 2 ・最後に追加された頂点 3, 8 todo リスト 頂点 4 頂点 2 頂点 3 頂点 8
  57. 57. 57 グラフ探索の考え方 0 1 4 2 3 8 5 7 6 赤:訪問済み 橙:todo どちらを優先して取り出す? ・最初に追加された頂点 4, 2 ・最後に追加された頂点 3, 8 todo リスト 頂点 4 頂点 2 頂点 3 頂点 8 深さ優先探索 幅優先探索
  58. 58. 58 グラフ探索の考え方 0 1 4 2 3 8 5 7 6 赤:訪問済み 橙:todo todo リスト 頂点 4 頂点 2 頂点 3 頂点 8 深さ優先探索 幅優先探索 :猪突猛進に突き進む :近いところから全体を舐めながら
  59. 59. 59 幅優先探索 赤:訪問済み 橙:todo • todo リストはキュー 0 1 4 2 3 5 7 6 8 • todo リストに頂点 0 をセットしておく todo 0 0
  60. 60. 60 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 • 頂点 0 を取り出す • 頂点 1, 4, 2 を新たに キューに追加する todo 1 4 2 0 1 1 1
  61. 61. 61 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 • 頂点 1 を取り出す • 頂点 3, 8 を新たに キューに追加する todo 4 2 3 8 0 1 1 1 2 2
  62. 62. 62 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 • 頂点 4 を取り出す • 新たな追加頂点はなし todo 2 3 8 0 1 1 1 2 2
  63. 63. 63 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 • 頂点 2 を取り出す todo 3 8 0 1 1 1 2 2 • 頂点 5 を新たに キューに追加する 2 5
  64. 64. 64 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 • 頂点 3 を取り出す todo 8 0 1 1 1 2 2 • 頂点 7 を新たに キューに追加する 2 5 7 3
  65. 65. 65 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 • 頂点 8 を取り出す todo 0 1 1 1 2 2 2 5 7 • 新たな追加頂点はなし 3
  66. 66. 66 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 • 頂点 5 を取り出す todo 0 1 1 1 2 2 2 7 • 頂点 6 を新たに キューに追加する 6 3 3
  67. 67. 67 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 • 頂点 7 を取り出す todo 0 1 1 1 2 2 2 6 3 3 • 新たな追加頂点はなし
  68. 68. 68 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 • 頂点 6 を取り出す todo 0 1 1 1 2 2 2 3 3 • 新たな追加頂点はなし todo がキューになったので終了
  69. 69. 69 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 • 始点に近いところから 舐めるように探索 0 1 1 1 2 2 2 3 3 距離 1 • 距離 1 を探索 • 距離 2 を探索 距離 2 距離 3 • 距離 3 を探索
  70. 70. 70 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 todo 0 1 1 1 2 2 2 3 3 vector<int> dist(N, -1); queue<int> todo; // 初期条件 dist[0] = 0; todo.push(0); // BFS while (!todo.empty()) { int v = todo.front(); todo.pop(); for (int x : G[v]) { if (dist[x] != -1) continue; dist[x] = dist[v] + 1; todo.push(x); } }
  71. 71. 71 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 todo 0 1 1 1 2 2 2 3 3 vector<int> dist(N, -1); queue<int> todo; // 初期条件 dist[0] = 0; todo.push(0); // BFS while (!todo.empty()) { int v = todo.front(); todo.pop(); for (int x : G[v]) { if (dist[x] != -1) continue; dist[x] = dist[v] + 1; todo.push(x); } } dist 値
  72. 72. 72 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 todo 0 1 1 1 2 2 2 3 3 vector<int> dist(N, -1); queue<int> todo; // 初期条件 dist[0] = 0; todo.push(0); // BFS while (!todo.empty()) { int v = todo.front(); todo.pop(); for (int x : G[v]) { if (dist[x] != -1) continue; dist[x] = dist[v] + 1; todo.push(x); } } todo リストから頂点 v を 取り出す処理 dist 値
  73. 73. 73 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 todo 0 1 1 1 2 2 2 3 3 vector<int> dist(N, -1); queue<int> todo; // 初期条件 dist[0] = 0; todo.push(0); // BFS while (!todo.empty()) { int v = todo.front(); todo.pop(); for (int x : G[v]) { if (dist[x] != -1) continue; dist[x] = dist[v] + 1; todo.push(x); } } 頂点 v と隣接している頂点 を todo リストに入れる処理 dist 値
  74. 74. 74 幅優先探索 赤:訪問済み 橙:todo 0 1 4 2 3 5 7 6 8 todo 0 1 1 1 2 2 2 3 3 vector<int> dist(N, -1); queue<int> todo; // 初期条件 dist[0] = 0; todo.push(0); // BFS while (!todo.empty()) { int v = todo.front(); todo.pop(); for (int x : G[v]) { if (dist[x] != -1) continue; dist[x] = dist[v] + 1; todo.push(x); } } 頂点 v と隣接している頂点 を todo リストに入れる処理 dist 値 探索済みの頂点は スキップする
  75. 75. 75 幅優先探索の実応用 (再掲) • カーナビ • 電車の乗り換え案内 • パズル (15-パズルなど) の最小手数
  76. 76. 76 深さ優先探索 • 数独ソルバーを作ることを考える https://ja.wikipedia.org/wiki/%E6%95%B0%E7%8B%AC
  77. 77. 77 深さ優先探索 • 数独を解く過程もグラフで表せる! 2 3 2 2 1 1 1 2 3 2 2 1 1 2 3 2 2 1 1 3 2 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1 2 3 2 2 1 1 3 2 3 2 2 1 1 3 2 3 2 2 1 1 3 1 2 3 https://ja.wikipedia.org/wiki/%E6%95%B0%E7%8B%AC
  78. 78. 78 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1
  79. 79. 79 深さ優先探索の動き 2 3 2 2 1 1 1 2 3 2 2 1 1 • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る
  80. 80. 80 深さ優先探索の動き 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 2 1 1 • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る
  81. 81. 81 深さ優先探索の動き 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 2 1 1 • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る
  82. 82. 82 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 2 3 2 2 1 1
  83. 83. 83 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 2 3 2 2 1 1
  84. 84. 84 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1
  85. 85. 85 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 1 2 3 2 2 1 1
  86. 86. 86 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 1 2 3 2 2 1 1
  87. 87. 87 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 1 2 2 3 2 2 1 1
  88. 88. 88 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 1 2 2 3 2 2 1 1
  89. 89. 89 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1
  90. 90. 90 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1
  91. 91. 91 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 2 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1
  92. 92. 92 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 2 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1
  93. 93. 93 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 2 3 2 2 1 1 3 2 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1
  94. 94. 94 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 2 3 2 2 1 1 3 2 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1 2 3 2 2 1 1 3 1
  95. 95. 95 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 2 3 2 2 1 1 3 2 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1 2 3 2 2 1 1 3 1
  96. 96. 96 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 2 3 2 2 1 1 3 2 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1 2 3 2 2 1 1 3 2 3 2 2 1 1 3 1 2
  97. 97. 97 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 2 3 2 2 1 1 3 2 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1 2 3 2 2 1 1 3 2 3 2 2 1 1 3 1 2
  98. 98. 98 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 2 3 2 2 1 1 3 2 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1 2 3 2 2 1 1 3 2 3 2 2 1 1 3 2 3 2 2 1 1 3 1 2 3
  99. 99. 99 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 2 3 2 2 1 1 3 2 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1 2 3 2 2 1 1 3 2 3 2 2 1 1 3 2 3 2 2 1 1 3 1 2 3
  100. 100. 100 深さ優先探索の動き • 矛盾するまで猛突猛進に突き進む / 矛盾したら戻る 2 3 2 2 1 1 1 2 3 2 2 1 1 2 3 2 2 1 1 3 2 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 1 2 3 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 3 2 2 1 1 1 2 2 3 1 2 3 2 3 2 2 1 1 2 3 2 2 1 1 3 2 3 2 2 1 1 3 2 3 2 2 1 1 3 1 2 3 終了!
  101. 101. 101 深さ優先探索と再帰関数 • 深さ優先探索の実装は、再帰関数が便利 2 3 2 2 1 1 3 2 3 2 2 1 1 2 3 2 2 1 1 3 2 3 2 2 1 1 3 2 3 2 2 1 1 3 1 2 3 終了! void dfs(State &cur) { if (cur が終了状態) { // 解を格納するなど return; } // 次の状態を順に試す for (cur に対する操作全体) { cur を変形する dfs(cur); // 再帰呼び出し cur を戻す } }
  102. 102. 102 深さ優先探索の実応用 • 数独ソルバー • https://github.com/drken1215/sudoku • 虫食算ソルバーも同様に作れる • コンピュータ将棋 AI の探索ルーチン • makefile などのビルドシステム • 動的計画法にもつながる • ネットワークの輸送経路の確保 http://www.dis.uniroma1.it/challenge9/download.shtml
  103. 103. 深さ優先探索のポイント • 「目の付け所」がとても大事! • 探索順序を工夫したり…探索不要なところを見出したり • 数独なら、選択肢が少なそう なマスから順に考えるなど 加藤徹作、大駒誠一, 武純也, 丸尾学著 『虫食算パズル700選』 問 698
  104. 104. 深さ優先探索と幅優先探索の比較 深さ優先探索のメリット • 枝刈りなどによって探索効率を上げられる余地が大きい • 帰りがけ順 (再帰関数を抜ける直前) にさまざまな処理 をしたい場合など (DP が代表的) 幅優先探索のメリット • 最小手数を求めたい場合など • 探索範囲自体は広いものの、求めたい解が始点のすぐ 近くにあることがわかっている場合など
  105. 105. 105 今日の話 • 数学のすすめ
  106. 106. 106 アルゴリズムによる問題解決 数理モデル化 AtCoder みたいな問題 解 解釈・意思決定 アルゴリズム
  107. 107. 107 数学を学ぼう! • さまざまな分野のさまざまな問題が、数理モデル化 によって汎用的に解ける!!! • 何をするにも強力な下地になる • 例:あれもこれも実はグラフ!
  108. 108. 108 ちょっとした例:区間分割 DP 0 1 2 3 4 5 6 7 8 9 • 系列データをいくつかの区間に分ける • 区間分割の仕方を最適化したい
  109. 109. 109 i 個 j 個 dp[i] ← 最初の i 個をいくつかの区間に区切る方法の 「良さ」の最大値 (i 個目のところで一旦区切るとする) dp[i] = min(dp[i], dp[j] + f(j, i)) 区間分割を扱う DP (5.6 章)
  110. 110. 110 http://chasen.naist.jp/chaki/t/2009-09-30/doc/mecab-cabocha-nlp-seminar-2009.pdf 僕は君を愛している 僕 は 君 を 愛し て いる 単語ごとに区切る 例(1):分かち書き
  111. 111. 111 例(2):発電計画問題 • 発電の on と off のタイミングを最適化する on off on off • 需要供給バランスの考慮などもあって、各区間のコス ト関数 f(i, j) はとても複雑なものになる • 「~時間以上連続稼働」といった制約も考慮
  112. 112. 112 例(3):パネルのグループ分け さまざまな長さのパネルがたくさん並んでいる それをいい感じにグループ分けしたい
  113. 113. 113 例(4):タイムスケジューリング • お客さまを順に回る配送 (配送順序は固定) • 「何時から何時の間に届けてほしい」 • 「~分間に 1 回は休憩が必要」という制約もある → どこで休憩をとるかを最適化 休憩場所ごとに区切る
  114. 114. 114 数学は分野横断的! • さまざまな分野の問題が、数理モデル化によって 本質的に同じ問題になったりなる! • 競プロの数学パズルは、まさにそういう問題たち グラフ DP 機械学習 ○○手法 電気 機械 化学 生物 経済 ○○
  115. 115. 115 全体のまとめ • アルゴリズムは何をするにも重要な基礎、 どんな人にもオススメ! • アルゴリズムは問題解決に生かしてナンボ • さまざまな問題が、数理モデル化 によって見通しよく扱える! • あれもこれも実はグラフ • アルゴリズムは楽しい!!

×