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
Scratchからアルゴリズムへ 〜二分探索〜
Search
R.K.
August 17, 2020
Programming
0
910
Scratchからアルゴリズムへ 〜二分探索〜
R.K.
August 17, 2020
Tweet
Share
More Decks by R.K.
See All by R.K.
公平ゲームとNim、Grundy数
asmape0104
0
220
Other Decks in Programming
See All in Programming
Gemini CLIの"強み"を知る! Gemini CLIとClaude Codeを比較してみた!
kotahisafuru
2
670
ZeroETLで始めるDynamoDBとS3の連携
afooooil
0
130
階層化自動テストで開発に機動力を
ickx
1
450
バイブコーディング超えてバイブデプロイ〜CloudflareMCPで実現する、未来のアプリケーションデリバリー〜
azukiazusa1
2
740
JetBrainsのAI機能の紹介 #jjug
yusuke
0
160
Quality Gates in the Age of Agentic Coding
helmedeiros
PRO
1
110
What's new in Adaptive Android development
fornewid
0
130
中級グラフィックス入門~効率的なメッシュレット描画~
projectasura
3
2k
新しいモバイルアプリ勉強会(仮)について
uetyo
1
230
バイブコーディングの正体——AIエージェントはソフトウェア開発を変えるか?
stakaya
3
230
Advanced Micro Frontends: Multi Version/ Framework Scenarios
manfredsteyer
PRO
0
120
MCPで実現できる、Webサービス利用体験について
syumai
7
2.2k
Featured
See All Featured
GitHub's CSS Performance
jonrohan
1031
460k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
8
400
Automating Front-end Workflow
addyosmani
1370
200k
Building a Modern Day E-commerce SEO Strategy
aleyda
42
7.4k
4 Signs Your Business is Dying
shpigford
184
22k
A better future with KSS
kneath
238
17k
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.9k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
10
1k
Done Done
chrislema
185
16k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
Building an army of robots
kneath
306
45k
Transcript
Scratchから アルゴリズムへ 〜 ⼆分探索 〜 あすまるびぃ (@asmape_RK)
このスライドについて • このスライドは、東京⼤学⼯学部電⼦情報⼯学科・電気電⼦⼯ 学科の授業である、アルゴリズム(https://iis- lab.org/algorithms2020)の期末レポート課題として制作され たものを⼀般に公開したものになります。 本スライドの内容に関して、お気づきの点やさらに良くするた めのコメントがございましたら、ぜひ本スライドの制作者にご 共有ください。
皆さんはプログラミングと⾔うと 何を思い浮かべますか?
プログラミング • ゲームやウェブページなどの開発? • ゲームのようなものを作るのは、Scratchでやったことがあるかもしれ ません。 • 問題を解いたり、データの処理をする? • 今⽇はこちらについて触れていきましょう。
問題を解く、データを処理する • データの中から指定のデータを探し出す • GoogleやYahoo!の検索など • 問題を解く • 地図上の最短経路を計算する、パズルを解くのに必要な⼿を調べる、 オセロや将棋などのAIを作る、数学の問題を解くなど。
⼤事な概念 アルゴリズム
次のような問題を考えてみましょう。 • 0でない数字と数字が与えられたとき、についての1次⽅程 式 − = 0を解きなさい。 • 例: =
3, = 6のとき = 2。 = 2, = 0のとき = 0 • これをコンピュータに解かせるには?
解き⽅ • − = 0の形のまま計算すると = ! " なので、この割り算を計 算させれば良い。
※ ⼀応確認 − = 0 ↓移項 = ↓ で割る =
解き⽅ • このとき、 = ! " とすれば − = 0の解が得られるというのは
⼈間が考えたもの! • コンピュータは指⽰に従って計算してくれるだけである。 • このように、解き⽅の⼿順は⼈間が与えなければならない、こ の⼿順のことをアルゴリズムという。
アルゴリズムの実装 • どんなアルゴリズムも、みなさんがScratchで使ってきた「変 数」「条件分岐」「ループ」などの組み合わせでできている。 • 是⾮今までの知識をフル活⽤しながら、今⽇説明するアルゴリ ズムの話を聞いてみてください。
今⽇のテーマ • 「探索」 • 複数のデータ、数字の列などの中から、お⽬当てのものを探す⼿法。 • ⽣徒のリストから◦組の⼈を⾒つけ出す。商品のリストから価格が1000円以下 のものを探し出す。など。 • 今回は簡単に、⼀致するものを探し出す⽅法を考える。
• つまり、次の問題を解く。「数字のリストがあります。この中に指⽰された数字 があるかどうか調べてください。」
今⽇のテーマ • 以下の名前のアルゴリズムを扱う。 • 線形探索 • ⼆分探索 • ハッシュ法
住んでいる階を当てる問題 • Aさんは、50階建てのビルに住んでいます。 • あなたは、Aさんが住んでいる階を当てます。 • あなたは、Aさんに「はい」「いいえ」で答えられる質問をす ることが出来ます。 • さて、⼀番多い場合でも何回質問すればAさんの住んでいる階
を当てられるでしょうか。
素朴な⽅法 • 「あなたは◦階に住んでいますか?」という質問を繰り返す。 • この場合、1階から聞き始めて、Aさんが50階に住んでいた場合、 50回質問をすることになる。 • つまり、ビルの階数と同じ回数だけ質問しなければならない!
質問を変えてみる • 「あなたは◦階以下に住んでますか?」 • ⼀回の質問で、かなり候補を絞ることが出来そう。
質問を変えてみる • 「あなたは25階以下に住んでいますか?」 • 候補:50→25 • 候補を半分にできる! • 「はい」の場合を考える。
質問を変えてみる • 「あなたは25階以下に住んでいますか?」 • 候補:50→25 • 「はい」の場合を考える。 • 「あなたは13階以下に住んでいますか?」 •
候補:25→13または12 • いちばん質問が多い回数を考えるので「はい」の場合を考える。
質問を変えてみる • 「あなたは7階以下に住んでいますか?」 • 候補:13→7または6 • 「はい」の場合を考える。
質問を変えてみる • 「あなたは7階以下に住んでいますか?」 • 候補:13→7または6 • 「はい」の場合を考える。 • 「あなたは4階以下に住んでいますか?」 •
候補:7→4または3 • 「はい」の場合を考える。
質問を変えてみる • 「あなたは2階以下に住んでいますか?」 • 候補:4→2 • 「はい」の場合を考える。 • 「あなたは1階に住んでいますか?」 •
候補:2→1 • 多くてもここで分かる!
質問した回数 • 「あなたは◦階以下に住んでいますか?」 • 25 • 13 • 7 •
4 • 2 • 1 • 質問回数は多くても6回!
⼆分探索 • このように、候補を半分にすることを繰り返す当て⽅を「⼆分 探索」という。 • ⼀⽅、はじめに出てきたように「◦階ですか?」という質問を 地道にする当て⽅を「線形探索」という。
質問回数の⽐較 • 線形探索の場合、階の数と等しい。 • ⼆分探索の場合、「階の数を何回半分にできるか」という数と ⼤体等しい。
質問回数の⽐較 • 階の数が⼤きければ⼤きいほどその差は歴然。10000ぐらいに なっても⼗数回の質問で済む。 階の数 50 100 500 1000 5000
10000 線形探索 50 100 500 1000 5000 10000 ⼆分探索 6 7 9 10 13 14
半分にできる回数 • ある数を半分にできる回数は、⼤体(数字の桁数-1)に⽐例する ことが知られている • 例:100階で7回の質問、10000階で14回の質問。それぞれの(桁数-1) は2、4であり2倍。質問の回数も2倍である。 • 桁数の上昇はその数に⽐べてとても⼩さい。 •
1万→1億は1万倍だが、(桁数-1)は2倍しか増えていない。 • ちなみになぜそうなるかという話は、⾼校までのお楽しみ。 • 対数という概念です。数学に興味がある⼈は調べてみてください。
いろいろ⼆分探索してみよう • もっと⾊んな所で⼆分探索を使いたい。 • ⼆分探索が使えるのは、複数のものから1つを選んだとき、答 えがその前と後のどちらにあるかが分かるとき!
数を探し出す問題 • 何らかの数が書かれた紙が⼊っている箱が何個かあります(図は 10個の例)。 • 箱にはふたがついていて、何が⼊っているかは開けるまでわか りません。 • このうちのどこかに、20が⼊っています。開ける箱をできるだ け少なくして、20の⼊っている箱を当ててください。
1 2 3 4 5 6 7 8 9 10 ? ? ? ? ? ? ? ? ? ?
数を探し出す問題 • 今の条件では⼆分探索を使えない! • なぜなら、箱を開けてもどちらに答えがあるかがわからないか ら。 • この場合は線形探索を使うしかない。 1 2
3 4 5 6 7 8 9 10 ? ? ? ? ? ? ? ? ? ?
数を探し出す問題 • 次の条件を追加してみよう。 • 箱の中に⼊っている数は左から⼩さい順に並んでいる。 • これなら、⼤⼩関係から探す数が左右どちら側にあるかが分か る! 1 2
3 4 5 6 7 8 9 10 ? ? ? ? ? ? ? ? ? ?
数を探し出す問題 • まずは5番⽬を開けてみよう。 • 45だった!答えはこれより左側にある! 1 2 3 4 5
6 7 8 9 10 ? ? ? ? 45 ? ? ? ? ?
数を探し出す問題 • 2番⽬を開けてみよう。 • 10だった!答えはこれより右側にある! 1 2 3 4 5
6 7 8 9 10 ? 10 ? ? 45 ? ? ? ? ?
数を探し出す問題 • 3番⽬を開けてみよう。 • ⾒つけた! 1 2 3 4 5
6 7 8 9 10 ? 10 20 ? 45 ? ? ? ? ?
プログラミングで書く準備 • これをコンピュータにやってもらうプログラムを書きましょう。 • どんな変数が必要だろうか。 • どうやったら、繰り返し「真ん中」を計算できる? • 繰り返しが終わる条件は?(=繰り返しを続ける条件は?)
⽅針 • 2つの⽬印を⽤意する。 • •と同じところか、•と▪の間の範囲に答えが存在するという 印。 (0) 1 2 3
4 5 6 7 8 9 10 (11) • ? ? ? ? ? ? ? ? ? ? ▪
⽅針 • 真ん中の位置を決める。 • (•の位置+ ▪の位置)÷2、⼩数点以下は切り捨てることにする。 • 今回は5、取り敢えず▲の印をつける。 (0) 1
2 3 4 5 6 7 8 9 10 (11) • ? ? ? ? ?▲ ? ? ? ? ? ▪
⽅針 • ▲の印のところを開ける。 • 数は45、これより右に答えは存在しない。 (0) 1 2 3 4
5 6 7 8 9 10 (11) • ? ? ? ? 45▲ ? ? ? ? ? ▪
⽅針 • ▪の印を5番⽬に移動する! • これで答えはここより右にないことが表せた。 (0) 1 2 3 4
5 6 7 8 9 10 (11) • ? ? ? ? 45▪ ? ? ? ? ?
⽅針 • 同じことを繰り返していく。 • ▲をつける。場所は(0+5)÷2の切り捨てなので2番⽬。 • ここの数は10。 (0) 1 2
3 4 5 6 7 8 9 10 (11) • ? 10▲ ? ? 45▪ ? ? ? ? ?
⽅針 • 今度はここより右に答えがあるので•を移動する! • 次は…? (0) 1 2 3 4
5 6 7 8 9 10 (11) ? 10• ? ? 45▪ ? ? ? ? ?
⽅針 • 今度はここより右に答えがあるので•を移動する! • 次は…? (0) 1 2 3 4
5 6 7 8 9 10 (11) ? 10• ? ? 45▪ ? ? ? ? ?
⽅針 • 今度はここより右に答えがあるので•を移動する! • 次は…? (0) 1 2 3 4
5 6 7 8 9 10 (11) ? 10• ? ? 45▪ ? ? ? ? ?
⽅針 • 次は3番⽬。 • 答えの位置はわかったけど試しに続けてみる。 (0) 1 2 3 4
5 6 7 8 9 10 (11) ? 10• 20▲ ? 45▪ ? ? ? ? ?
⽅針 • 最初の取り決めより•は答えそのものであっても良いので•を 移動させる。 ※最初の取り決め「•と同じところか、•と▪の間の範囲に答え が存在するという印」 (0) 1 2 3
4 5 6 7 8 9 10 (11) ? 10 20• ? 45▪ ? ? ? ? ?
⽅針 • 最後、4番⽬を開ける。 (0) 1 2 3 4 5 6
7 8 9 10 (11) ? 10 20• 30▲ 45▪ ? ? ? ? ?
⽅針 • 30は答えよりも⼤きいので▪を動かす。 (0) 1 2 3 4 5 6
7 8 9 10 (11) ? 10 20• 30▪ 45 ? ? ? ? ?
⽅針 • •と▪の間がなくなったので答えは•のところ! • つまり、「•と▪の距離が1」が繰り返しを終わる条件。 (0) 1 2 3 4
5 6 7 8 9 10 (11) ? 10 20• 30▪ 45 ? ? ? ? ?
ところで • 探したい数字がなかった場合はどうなる?
存在しない場合 • 3番⽬の中⾝が20じゃなくて19だった場合このようになる。 • つまり•から左は20より⼩さく、 ▪から右は20より⼤きい範 囲になる。 • 最終的に•が探したいものと等しくなかった場合、その数はな かったということになる!
(0) 1 2 3 4 5 6 7 8 9 10 (11) ? 10 19• 30▪ 45 ? ? ? ? ?
存在しない場合 • また、すべての数字が探したいものより⼤きかった場合、 •は 0の位置から動かない。 • 0番⽬の箱は存在しないので、少し気をつける。 (0) 1 2
3 4 5 6 7 8 9 10 (11) • 24▪ 25 27 30 45 ? ? ? ? ?
Scratchで実装してみましょう
実装例 • 今回は適当に箱を作る • 変数「カウンタ」を使っ て、次のような動作をす る。カウンタの数字を とする。 • を0〜19まで変化させ
て、10〜10 + 9の数の どれかを箱に⼊れる。
実装例 • 確かに⼩さい順になる。 箱に⼊りうる数 (10〜10 + 9) 0 0〜9 1
10〜19 2 20〜29 3 30〜39 ⋮ ⋮ 18 180〜189 19 190〜200
実装例 • ⼆分探索の部分 • 変数「左の印」、「右の印」、 「真ん中の印」は、それぞれ が何番⽬にあるかの情報を持 つ。
実装例 • 結果を出⼒する部分。 • 0番⽬を弾く。
動作例 • 左に作られた箱の中⾝が表⽰ されるので、どれを探しても らいたいか決めましょう。 • 存在しない数字を⼊れたとき にきちんと存在しないと⾔っ てくれるか確認しましょう。
動作例
ここまでのまとめ • 線形探索 • 遅いけど、どんなデータに対しても調べられる。 • ⼆分探索 • 早いけど、順番に並べられたデータにしか使えない。
ハッシュ法 • データを何番⽬に⼊れるかを⼯夫することにより、探したいも のを⼀発で⾒つけ出す⽅法。 • データから何番⽬に⼊れるかを導き出す。これをハッシュとい う。 • 例えば、1の位を使うなど。次に説明します。
1の位を⽤いる⽅法 • 数の1の位は0〜9なので、 (1の位)番⽬の位置の箱に⼊れる(0は 10番⽬)。 • 例:データが13, 25, 37, 52,
59のとき、10個の箱を⽤意して以 下のように⼊れる。 1 2 3 4 5 6 7 8 9 10 52 13 25 47 59
1の位を⽤いる⽅法 • 52を探したい場合 • 52の1の位は2なので2番⽬に⼊っているはずである。 • 2番⽬の箱を開けると⾒つかる。 • 35を探したい場合 •
35の1の位は5なので5番⽬に⼊っているはずである。 • 5番⽬の箱を開けると25なので⾒つからない。 1 2 3 4 5 6 7 8 9 10 52 13 25 47 59
ハッシュ法の利点・⽋点 • 利点 • とにかく早い • ⼀発で⾒つけられる。 • データを箱に⼊れるのも時間がかからない。 •
⽋点 • 衝突 • 同じ1の位を持つ数が複数あるとうまく⾏かない。 • 空の箱が出る • 速さのために無駄なスペースがある。 • 専⾨的な⾔葉で⾔うと「空間計算量が⼤きい」
⽋点の克服 • ここにさらに32を追加することを考える。 • 2番⽬はすでに埋まっている。どうする? 1 2 3 4 5
6 7 8 9 10 52 13 25 47 59
チェーン法 • 1つの箱に複数の数字を⼊れられるようにする。 • 箱の中に複数の数字が⼊るので、箱の中で線形探索などが必要。 ただし、数は少なくなるはずなので何もせず線形探索するより は早い。 1 2 3
4 5 6 7 8 9 10 52,32 13 25 47 59
オープンアドレス法 • 開いてる別の場所に⼊れる。 • 本来⼊れる場所からスタートし、右に⾒ていって開いてるとこ ろに⼊れる。 • ⾒つけるときは、32だと思って2番⽬を開けると52なので、そ こから右の⽅を順番に探すという⼿順を取る。 1
2 3 4 5 6 7 8 9 10 52 13 32 25 47 59
⼤きさの問題 • 1の位を⽤いる⽅法かつオープンアドレス法の場合は、データ が10個しか⼊れられない。 • チェーン法の場合でも、データが100個、1000個となると同じ 箱に⼊る数字が10個、100個とどんどん増えていってしまう。 • 普通は、もっと⼤きな数の箱を⽤意する。
まとめ • 線形探索 • 遅いけど、どんなデータに対しても調べられる。 • ⼆分探索 • 早いけど、順番に並べられたデータにしか使えない。 •
ハッシュ法 • 早いけど、箱がたくさん必要。
まとめ • 今回紹介したアルゴリズムは、ほんの⼀部分にしか過ぎません。 • ぜひ興味が湧いた⽅は、⾃分で勉強してみたりしてみてくださ い。