Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
【2019-06-19】アルゴリズム勉強会 - 最小全域木
Search
Hidehisa Arai
June 19, 2021
Technology
300
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
【2019-06-19】アルゴリズム勉強会 - 最小全域木
Hidehisa Arai
June 19, 2021
More Decks by Hidehisa Arai
See All by Hidehisa Arai
世界モデルにおける分布外データ対応の方法論
koukyo1994
7
2.3k
生成AIの二大潮流と自動運転
koukyo1994
22
25k
ICML2021論文読み会資料
koukyo1994
2
1.7k
Kaggle昔?話
koukyo1994
2
2.6k
コンペ中のコード、どうしてる?
koukyo1994
3
2.3k
変数間の関係を捉えたいあなたへ
koukyo1994
3
1.8k
脱! Deepでポン🎶ハイパラチューニング芸人を卒業するために
koukyo1994
7
4.9k
鳥蛙コンペ反省会資料
koukyo1994
3
1.5k
6th place solution to Cornell Birdcall Identification Challenge
koukyo1994
0
200
Other Decks in Technology
See All in Technology
しくみを学んで使いこなそう GitHub Copilot app
torumakabe
2
290
Type-safe IaC for Dart
coborinai
0
170
AI時代のPlaywright活用(システムテストを自動化する ー 実行エンジンにPla ywrightを選んだ理由)
ynisqa1988
1
810
LLMやAIエージェントをソフトウェアに組み込むプラクティス
shibuiwilliam
2
440
Webアプリ認証の全体像 / The Big Picture of Web App Authentication
kitano_yuichi
1
350
ruby.wasmとPicoRuby.wasmに対応した仮想DOMライブラリを作ってる話 #kaigieffect_kaigi
sue445
PRO
0
160
マルチアカウント環境でSecurity Hubの運用、その後どうなった? / SRE NEXT 2026 miniLT会
genda
0
110
Vポイント分析基盤におけるデータモデリング20年史
taromatsui_cccmkhd
3
250
AI x 開発生産性を取り巻く予算戦略と投資対効果
i35_267
3
1.7k
Oracle Exadata Database Service on Cloud@Customer X11M (ExaDB-C@C) サービス概要
oracle4engineer
PRO
2
8.4k
AmplifyHostingConstructからSSRフレームワークのためのホスティング設計を考察する/amplify-hosting-construct
fossamagna
1
260
ガバナンスの「ちょうどいい落とし所」を探れ!開発スピードを妨げない運用判断の勘所 / SRE NEXT 2026
genda
1
270
Featured
See All Featured
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Producing Creativity
orderedlist
PRO
348
40k
We Are The Robots
honzajavorek
0
280
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
540
Designing Powerful Visuals for Engaging Learning
tmiket
1
450
Between Models and Reality
mayunak
4
380
Embracing the Ebb and Flow
colly
88
5.1k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.2k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.3k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.6k
The Cost Of JavaScript in 2023
addyosmani
55
10k
Transcript
2021/06/19 アルゴリズム勉強会 Hidehisa Arai 1
はじめに 水源 a b d f c e h i
k l j g 10 15 18 33 11 21 20 6 85 9 56 2 22 77 5 39 30 81 14 12 38 41 67 水源から村の各戸に水道を引きたい。コスト最小になる引き方は? => 最小全域木 2
ナイーブな考え方① 水源 a b d f c e h i
k l j g 10 15 18 33 11 21 20 6 85 9 56 2 22 77 5 39 30 81 14 12 38 41 67 水源から村の各戸に水道を引きたい。コスト最小になる引き方は? =>コストが小さい辺からとりあえず採用してみよう 途中経過 3
ナイーブな考え方② 水源 a b d f c e h i
k l j g 10 15 18 33 11 21 20 6 85 9 56 2 22 77 5 39 30 81 14 12 38 41 67 水源から村の各戸に水道を引きたい。コスト最小になる引き方は? =>コストが小さい辺からとりあえず採用してみよう 途中経過 次にコストの低い辺は これだが、採用すると 巡回が発生する・・・ =>巡回が発生しそうならスキップ! 4
ナイーブな考え方③ 水源 a b d f c e h i
k l j g 10 15 18 33 11 21 20 6 85 9 56 2 22 77 5 39 30 81 14 12 38 41 67 水源から村の各戸に水道を引きたい。コスト最小になる引き方は? =>コストが小さい辺からとりあえず採用してみよう いつ終わるの? => 全ノードを繋いだら終わり! 5
ナイーブな考え方 - アルゴリズムを書き下してみる • 入力の辺のコストが小さい順に採用していく ◦ コスト順にソートしておくと良さそう! • 巡回が発生しそうだったらスキップする
◦ 巡回が発生しそうってなに? • 全ノードを繋いだら終わり! ◦ 簡単に判別する方法はある? ◦ => 最終的には「木」になるのでノード数 - 1個の辺を採用 したら終わり! 水源 a b c e h 10 15 18 33 11 21 20 6 繋いでは ダメな辺 繋いでもOK な辺 6
ナイーブな考え方 - 巡回が発生しそうってなに? 水源 a b c e h 10
15 18 33 11 21 20 6 同じ部分グラフ= 連結成分 別の部分グラフ=連 結成分でない 両ノードが連結成分なエッジを選ば ないようにしたい =>連結成分の判定って? =>Union Find! 7
ナイーブな考え方 - アルゴリズムを書き下してみる • 入力の辺のコストが小さい順に採用していく ◦ コスト順にソートしておくと良さそう! • 巡回が発生しそうだったらスキップする
◦ 両ノードが連結成分なエッジをスキップする ◦ => Union Findで連結かどうか判定 • 全ノードを繋いだら終わり! ◦ 簡単に判別する方法はある? ◦ => 最終的には「木」になるのでノード数 - 1個の辺を採 用したら終わり! あり本間違えてる・・・? クラスカル(Kruskal)法といいます 8
クラスカル法 - 計算量 O(ElogE) O(V) O(Vα(n)) ※α(n)はアッカーマン関数の逆関数 O(ElogE) O(ElogV)
OR† † E < V2 なためlogE < logV2 = 2logV 9
別の考え方① 水源 a b d f c e h i
k l j g 10 15 18 33 11 21 20 6 85 9 56 2 22 77 5 39 30 81 14 12 38 41 67 水源から村の各戸に水道を引きたい。コスト最小になる引き方は? => 連結を保ちながらちょっとずつ木を大きくすることもできるのでは? 最初は重み最小の辺で良さそう、次は? 10
別の考え方② 水源 a b d f c e h i
k l j g 10 15 18 33 11 21 20 6 85 9 56 2 22 77 5 39 30 81 14 12 38 41 67 水源から村の各戸に水道を引きたい。コスト最小になる引き方は? => 連結を保ちながらちょっとずつ木を大きくすることもできるのでは? 最初は重み最小の辺で良さそう、次は? => すでに連結されている成分で最小コストの辺を繋ぐ 次にコストの低い辺は これだが、採用すると 巡回が発生する・・・ =>巡回が発生しそうならスキップ! 11
別の考え方③ 水源 a b d f c e h i
k l j g 10 15 18 33 11 21 20 6 85 9 56 2 22 77 5 39 30 81 14 12 38 41 67 水源から村の各戸に水道を引きたい。コスト最小になる引き方は? => 連結を保ちながらちょっとずつ木を大きくすることもできるのでは? いつ終わるの? => 全てのノードが繋がれば終わり! 12
別の考え方 - アルゴリズムを書き下してみる • 初めはコスト最小の辺を選ぶ(必須ではない) • すでに連結な成分に繋がっている辺の中で最小 コストの辺を選ぶ、ただし巡回が発生しそうな時は スキップ ◦
連結成分から伸びる辺で最小コストの辺ってどうやって 見つける? ◦ 巡回が発生しそうってなに? • 全ノードを繋いだら終わり! ◦ 簡単に判別する方法はある? ◦ => 最終的には「木」になるのでノード数 - 1個の辺を採用 したら終わり! d f h i k j g 9 2 22 5 81 41 最小がこれな ことをどう判定 する? 13
別の考え方 - 最小コストの辺をどう見つける? d f h i k j g
9 2 22 5 81 12 41 minCost[h] = 22 minCost[k] = 5 minCost[j] = 81 minCost[g] = 41 minCost[d] = 9 連結成分からそれ 以外のノードへの 最小移動コストを計 算しておき、その中 で最小の値をとる。 d f e h i k j g 9 2 22 5 81 41 67 minCost[e] = INF 連結成分から いけないノー ドはINF e 67 minCost[h] = 22 minCost[k] = 5 used[k] = true minCost[j] = 81 minCost[d] = 9 minCost[e] = INF minCost[g] = min(41, 12) 14
• すでに連結な成分に繋がっている辺の中で最小コストの辺を選ぶ、ただし巡回が 発生しそうな時はスキップ ◦ 連結成分から伸びる辺で最小コストの辺ってどうやって見つける? ▪ 連結成分からのそれ以外のノードへの最小コストを保持しておく ▪
連結成分から直接いけないノードへの最小コストはINF ▪ 辺を選択した後、最小コストを更新する必要がある • 全てのノードについて新しく追加されたノードからのコストと現在のminCostを比較する ◦ 巡回が発生しそうってなに? ▪ クラスカル法と違い、同じ連結成分かどうか調べる必要はない(連結成分は必ず一つの木) ▪ すでに連結成分になったかどうかを記録しておくだけでヨシ! ▪ 次の最小の辺は「まだ連結されていない辺」から選ぶ 別の考え方 - 最小コストの辺をどう見つける? 15
別の考え方 - 必要な要素を考える 連結成分からのそれ以外のノードへの最小コストを保持しておく連結 成分から直接いけないノードへの最小コストはINF => minCostの配列が必要。|minCost| = VでINFで初期化する。
すでに連結成分になったかどうかを記録しておくだけでヨシ! => 連結成分かどうかの配列が必要。|used| = Vでfalseで初期化する。 次の最小の辺は「まだ連結されていない辺」から選ぶ => 全てのノードvについてused[v] = falseかつminCost[v]が最小かを確認 全てのノードについて新しく追加されたノードからのコストと現在のminCostを比較する => ノードからノードへのコストを保持する行列Costが必要。辺が実際には存在し ないところはINFで初期化する。 => 全てのノードvについて現在のminCost[v]とCost[v][u]の比較をし、Cost[v][u] の方が小さければminCost[v] = Cost[v][u]となる。 16
別の考え方 - アルゴリズム全体 ノードからノードへのコストを保持する行列が必 要。辺が実際には存在しないところはINFで初期 化する。 minCostの配列が必要。|minCost| = VでINFで初 期化する。
連結成分かどうかの配列が必要。|used| = Vで falseで初期化する。 全てのノードvについてused[v] = falseかつ minCost[v]が最小かを確認 全てのノードvについて現在のminCost[v]と Cost[v][u]の比較をし、Cost[v][u]の方が小さけ ればminCost[v] = Cost[v][u]となる。 17 プリム(Prim)法といいます
別の考え方 - 計算量 O(V) V回実行される 単体でO(V) 単体でO(V) O(V2) O(V2) V×
V× O(V2) 18
別の考え方 - 計算量改善 プライオリティキューを使う => O(logV) 隣接リストを使う O((V+E)logV) 19