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
A_アルゴリズム高速化を目指して
Search
Takashi Makino
April 25, 2021
Programming
1.5k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
A_アルゴリズム高速化を目指して
Takashi Makino
April 25, 2021
More Decks by Takashi Makino
See All by Takashi Makino
あなたの知らないスクラムの世界
makky0620
0
110
Flutterでもテスト駆動したい
makky0620
0
380
Discord botにScrumの Discord botにScrumの手伝いをしてもらう手伝いをしてもらう
makky0620
0
430
Other Decks in Programming
See All in Programming
5分で問診!Composer セキュリティ健康診断
codmoninc
0
560
The Bowling Game- From Imperative to Functional Programming - Part 1
philipschwarz
PRO
0
340
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
140
AIが無かった頃の素敵な出会いの話
codmoninc
1
200
全PRの83%がAIレビューだけでマージできるようになった開発組織はその後どうなったか
athug
0
290
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
160
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
110
変わらないものが、変わるものを決める — 意図駆動開発 × イベントソーシング × イミュータブル | What Doesn't Change Decides What Can — IDD × Event Sourcing × Immutability
tomohisa
0
150
광주소프트웨어마이스터고등학교 DevFest 특강 - 바이브 코딩 시대에서 주니어 개발자로 살아남는 방법
utilforever
1
150
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
840
jsmini JavaScript Engine を作ってみた話
yosuke_furukawa
PRO
0
180
改善しないと、タスクが回らない。 “てんこ盛りポジション” を引き継いだ情シスの、入社3ヶ月の業務改善録
krm963
0
100
Featured
See All Featured
What's in a price? How to price your products and services
michaelherold
247
13k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
470
Reality Check: Gamification 10 Years Later
codingconduct
0
2.2k
Being A Developer After 40
akosma
91
590k
Fireside Chat
paigeccino
42
4k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.2k
Side Projects
sachag
455
43k
Raft: Consensus for Rubyists
vanstee
141
7.6k
The browser strikes back
jonoalderson
0
1.4k
How Software Deployment tools have changed in the past 20 years
geshan
0
34k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
What does AI have to do with Human Rights?
axbom
PRO
1
2.3k
Transcript
A*アルゴリズム 高速化を目指して 牧野トミー孝史 2021/04/21@TechBash
高速化の前に理解しよう • 一般的な経路探索アルゴリズムに A*アルゴリズムがある • Wikipediaにこうしたら速くなるよと書いてある ◦ データ構造の工夫 ◦ ヒューリスティック関数の工夫
• そもそものアルゴリズムを自分で実装したことがない →しっかり理解したことをみんなに伝えてみよう!
どんな問題を解くのか StartからGoalまでの経路を求める! • ノード(青い点):81個 • エッジ(線):144本 Start Goal
どんな問題を解くのか StartからGoalまでの経路を求める! • ノード(青い点):81個 • エッジ(線):144本 Start Goal 赤い線っぽくなってく れたらいいな
A*の考え方 S G (0, 0) (100, 100) (50, 100) (0,
100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) f(n) = g(n) + h(n) のf(n)が最小となる経路をたどっていく
A*の考え方 最小経路の時のコストをf(n)*と置くと ※nはノードを指している f(n)* = g(n)* + h(n)* g(n)*はスタートからノードnまでのコスト h(n)*はノードnからゴールまでのコスト
g(n)*とh(n)*はわからないため、推定値として計 算する必要がある。推定値 f(n)と置くと f(n) = g(n) + h(n) g(n)は通った時に算出すれば良いが、 h(n)はゴールに辿り着くまで不明である。 S G (0, 0) (100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50)
A*の考え方 最小経路の時のコストをf(n)*と置くと ※nはノードを指している f(n)* = g(n)* + h(n)* g(n)*はスタートからノードnまでのコスト h(n)*はノードnからゴールまでのコスト
g(n)*とh(n)*はわからないため、推定値として計 算する必要がある。推定値 f(n)と置くと f(n) = g(n) + h(n) g(n)は通った時に算出すれば良いが、 h(n)はゴールに辿り着くまで不明である。 S G (0, 0) (100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) f(n)* = 50 + 50*3 = 200
(50, 50) A*の考え方 最小経路の時のコストをf(n)*と置くと ※nはノードを指している f(n)* = g(n)* + h(n)*
g(n)*はスタートからノードnまでのコスト h(n)*はノードnからゴールまでのコスト g(n)*とh(n)*はわからないため、推定値として計 算する必要がある。推定値 f(n)と置くと f(n) = g(n) + h(n) g(n)は通った時に算出すれば良いが、 h(n)はゴールに辿り着くまで不明である。 S G (0, 0) (100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (100, 50) f(n) = 50 + ? = ??
(50, 50) A*の考え方 最小経路の時のコストをf(n)*と置くと ※nはノードを指している f(n)* = g(n)* + h(n)*
g(n)*はスタートからノードnまでのコスト h(n)*はノードnからゴールまでのコスト g(n)*とh(n)*はわからないため、推定値として計 算する必要がある。推定値 f(n)と置くと f(n) = g(n) + h(n) g(n)は通った時に算出すれば良いが、 h(n)はゴールに辿り着くまで不明である。 S G (0, 0) (100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (100, 50) h(n)にはヒューリスティックな関数を定 義する e.g. ユークリッド距離 マンハッタン距離 e.g. マンハッタン距離の時 h(n) = (100-50) + (100-0) h(n) = 150 f(n) = 50 + 150 = 200
コストを使ってどうやって経路探索するのか Wikipediaの実装をそのまま再現 事前準備・備考 • 優先度付きキューOPENとCLOSEを用意 • 優先度はf(n)の低い順 • h(n)はマンハッタン距離 S
G (0, 0) (100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50)
OPEN:[11] CLOSE:[] TARGET: 説明 スタートのノードをOPENへ入れる (0, 0) (100, 100) (50,
100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 22 21 31 32 23 33
OPEN:[] CLOSE:[11] TARGET:11 説明 OPENから一つ取り出しCLOSEに加える (0, 0) (100, 100) (50,
100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 22 21 31 32 23 33
12 21 OPEN:[] CLOSE:[11] TARGET:11 説明 TARGETと隣接しているノードがOPENまたはCLOSE に含まれるか確認する (含まれなかった) (0,
0) (100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 13 22 31 32 23 33
12 21 OPEN:[12(200), 21(200)] CLOSE:[11] TARGET:11 説明 TARGETと隣接しているノードのfn(n)を求めてOPEN に追加する f(12)
= 50 + 150 = 200 f(21) = 50 + 150 = 200 この時各ノードに親情報( 11から繋がっている)を付 与する ここまで1セット (0, 0) (100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 13 22 31 32 23 33
OPEN:[21(200)] CLOSE:[11, 12(200)] TARGET:12(200) 説明 OPENから一つ取り出しCLOSEに加える (0, 0) (100, 100)
(50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 22 21 31 32 23 33
13 22 OPEN:[21(200)] CLOSE:[11, 12(200)] TARGET:12(200) 説明 TARGETと隣接しているノードがOPENまたはCLOSE に含まれるか確認する (含まれなかった)
(0, 0) (100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 12 21 31 32 23 33
13 22 OPEN:[21(200), 13(200), 22(200)] CLOSE:[11, 12(200)] TARGET:12(200) 説明 TARGETと隣接しているノードのfn(n)を求めてOPEN
に追加する f(13) = 100 + 100 = 200 f(22) = 100 + 100 = 200 この時各ノードに親情報を付与する (0, 0) (100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 12 21 31 32 23 33
13 22 OPEN:[21(200), 13(200), 22(200)] CLOSE:[11, 12(200)] TARGET:12(200) 説明 TARGETと隣接しているノードのfn(n)を求めてOPEN
に追加する f(13) = 100 + 100 = 200 f(22) = 100 + 100 = 200 この時各ノードに親情報を付与する (0, 0) (100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 12 21 31 32 23 33
OPEN:[13(200), 22(200)] CLOSE:[11, 12(200), 21(200)] TARGET:21(200) 説明 OPENから一つ取り出しCLOSEに加える (0, 0)
(100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 22 21 31 32 23 33
22 31 OPEN:[13(200), 22(200)] CLOSE:[11, 12(200), 21(200)] TARGET:21(200) 説明 TARGETと隣接しているノードがOPENまたはCLOSE
に含まれるか確認する (22がOPENに含まれている) (0, 0) (100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 21 32 23 33
22 31 OPEN:[13(200), 22(200), 31(200)] CLOSE:[11, 12(200), 21(200)] TARGET:21(200) 説明
TARGETと隣接しているノードのfn(n)を求めてOPEN に追加する f(31) = 90 + 110 = 200 f(22) = 100 + 100 = 200 もしf(22)が元のコストより低ければコストと親情報を 更新する この時各ノードに親情報を付与する (0, 0) (100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 21 32 23 33
(0, 0) (100, 100) (50, 100) (0, 100) (50, 0)
(90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 22 21 31 32 23 33 OPEN:[13(200), 22(200)] CLOSE:[11, 12(200), 21(200), 31(200)] TARGET:31(200) 説明 OPENから一つ取り出しCLOSEに加える (ちょっと恣意的に31を取り出しました)
32 22 31 OPEN:[13(200), 22(200)] CLOSE:[11, 12(200), 21(200), 31(200)] TARGET:31(200)
説明 TARGETと隣接しているノードがOPENまたはCLOSE に含まれるか確認する (含まれなかった) (0, 0) (100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 21 23 33
32 22 31 OPEN:[13(200), 22(200), 32(200] CLOSE:[11, 12(200), 21(200), 31(200)]
TARGET:31(200) 説明 TARGETと隣接しているノードのfn(n)を求めてOPEN に追加する f(32) = 150 + 50 = 200 この時各ノードに親情報を付与する (0, 0) (100, 100) (50, 100) (0, 100) (50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 21 23 33
(0, 0) (100, 100) (50, 100) (0, 100) (50, 0)
(90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 22 21 31 32 23 33 OPEN:[13(200), 22(200)] CLOSE: [11, 12(200), 21(200), 31(200), 32(200)] TARGET:32(200) 説明 OPENから一つ取り出しCLOSEに加える (ちょっと恣意的に32を取り出しました)
22 33 (0, 0) (100, 100) (50, 100) (0, 100)
(50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 21 31 32 23 OPEN:[13(200), 22(200)] CLOSE: [11, 12(200), 21(200), 31(200), 32(200)] TARGET:32(200) 説明 TARGETと隣接しているノードがOPENまたはCLOSE に含まれるか確認する (22がOPENに含まれる)
22 33 (0, 0) (100, 100) (50, 100) (0, 100)
(50, 0) (90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 21 31 32 23 OPEN:[13(200), 22(200), 33(200)] CLOSE: [11, 12(200), 21(200), 31(200), 32(200)] TARGET:32(200) 説明 TARGETと隣接しているノードのfn(n)を求めてOPEN に追加する f(22) = 250 + 100 = 350 f(33) = 0+200 = 200 この時各ノードに親情報を付与する
(0, 0) (100, 100) (50, 100) (0, 100) (50, 0)
(90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 22 21 31 32 23 33 OPEN:[13(200), 22(200), 33(200)] CLOSE: [11, 12(200), 21(200), 31(200), 32(200), 33(200] TARGET:33(200) 説明 OPENから一つ取り出しCLOSEに加える (ちょっと恣意的に33を取り出しました)
(0, 0) (100, 100) (50, 100) (0, 100) (50, 0)
(90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 22 21 31 32 23 33 OPEN:[13(200), 22(200), 33(200)] CLOSE: [11, 12(200), 21(200), 31(200), 32(200), 33(200] TARGET:33(200) 説明 TARGETがGoalと等しいので終了
(0, 0) (100, 100) (50, 100) (0, 100) (50, 0)
(90, 0) (0, 50) (50, 50) (100, 50) 11 12 13 22 21 31 32 23 33 OPEN:[13(200), 22(200), 33(200)] CLOSE: [11, 12(200), 21(200), 31(200), 32(200), 33(200] TARGET:33(200) 説明 TARGETの親情報をたどっていけば 33->32->31->21->11 という経路となることがわかる
実際に解いてみると Start Goal • ノード(青い点):81個 • エッジ(線):144個 • 計算時間:0.00536s
こんな複雑な問題も解ける Start Goal • ノード(青い点):2401個 • エッジ(線):3984個 • 計算時間:3.24s(これじゃ遅い)
余談:ダイクストラ法って何? A*アルゴリズムの特殊版 ヒューリスティックな値が0として、スタートからノードnまでのコストのみで計算 f(n) = g(n) + h(n) h(n) =
0