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

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

More Related Content

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