25+ Essential Algorithms Explained in 40 Minutes.
動画「25+ Essential Algorithms Explained in 40 Minutes(40分で解説する25以上の必須アルゴリズム)」の構成と概要をベースに、エンジニアリングや計算機科学のバックグラウンドを持つ方がくすっと笑えたり「なるほど」と思えるような、アルゴリズムにまつわる雑学・歴史・業界の裏話を交えて解説します。
1. 探索・ソート・ポインタ手法 (00:00 - 08:59)
「まずは基本の『探す』『並べる』『範囲を絞る』」
-
O(log n) の破壊的インパクト
-
業界裏話: 人類全体(約80億人)の電話帳があったとして、二分探索(Binary Search)を使えばたった33回の比較で特定の人を見つけられます。O(log n) が「データ量がいくら増えても怖くない」と言われる所以です。
-
-
O(n²) ソート vs 分割統治法(O(n log n))
-
雑学: Quick Sort(クイックソート)を発明したトニー・ホーア(Tony Hoare)は、モスクワ大学に留学中、ロシア語の辞書検索を高速化するためにこのアルゴリズムを思いつきました。また、彼は後に「ヌル参照(null pointer)の発明は自分の10億ドルの過ち(Billion-Dollar Mistake)だった」と後悔したことでも有名です。
-
-
Two Pointers / Sliding Window
-
実務あるある: 競技プログラミングやコーディング面接で最も愛されるテクニックです。配列を2重ループで走査する$O(n^2)$のコードを書いたエンジニアが、レビューで「これスライディングウィンドウ使えば$O(n)$でいけるよね?」と指摘されてハッとさせられるのは、テック企業の風物詩とも言えます。
-
2. 再帰・バックトラッキング (10:56 - 17:59)
「力押し(Brute Force)を賢く止める『枝刈り』の技術」
-
再帰の3原則
-
ジョーク: プログラマの辞書で「再帰(Recursion)」を引くと、「『再帰』を参照すること」 と書かれている定番ジョークがあります。実務では「終了条件(Base Case)」を書き忘れてスタックオーバーフロー(Stack Overflow)を起こし、あの有名な質問サイトのお世話になるまでがセットです。
-
-
Backtrackingと枝刈り(Pruning)
-
業界裏話: ナップサック問題や数独の解法、Nクイーン問題でお馴染みのバックトラッキングですが、チェスAI(Deep Blueなど)や将棋AIの「α-β枝刈り」の根幹でもあります。一見膨大な探索空間も、「筋の悪い手を早々に切り捨てる(Pruning)」ことで、人間を凌駕する計算スピードを実現しました。
-
3. ハッシュと動的計画法 (18:00 - 22:59)
「メモ化で『過去の計算』を買い取る」
-
ハッシュ衝突(Chaining vs Open Addressing)
-
雑学: ハッシュ関数は「暗号用(SHA-256など)」と「データ構造用(MurmurHash, SipHashなど)」で求められる性質が全く異なります。データ構造用ハッシュはとにかく高速性が命ですが、かつてHashDoS攻撃(意図的に衝突を大量発生させてサーバーをダウンさせる攻撃)が流行したため、現代のプログラミング言語(RustやPythonなど)のデフォルトハッシュ機能には、DoS対策のランダム化アルゴリズムが組み込まれています。
-
-
Dynamic Programming (DP)
-
名前の由来の裏話: 「動的計画法(Dynamic Programming)」という厳めしい名前をつけた数学者リチャード・ベルマンは、当時(1950年代)国防省の資金援助を受けて研究していました。しかし、当時の長官は「数学(Mathematics)」や「研究(Research)」という言葉が大嫌いでした。そこで、予算を削られないように政治的カモフラージュとして、「なんだか格好良くて官僚に突っ込まれない言葉」として選んだのがDynamicとProgrammingだったと言われています。
-
4. グラフ・貪欲法・文字列 (23:12 - 30:53)
「現実世界の複雑さをモデル化する」
-
Graph Algorithms(Dijkstra, BFS, DFS)
-
雑学: ダイクストラ法を考案したエドガー・ダイクストラは、たった20分でコーヒーショップに座っている時にこのアルゴリズムを思いついたと語っています。当時のコンピューター(ARMAC)のデモ用に「オランダの64都市の最短ルート」を計算するために作られました。現代のGoogle Mapsのルート検索や、IPネットワークのルーティング(OSPF)でも形を変えて生き続けています。
-
-
Greedy Choiceと交換論法(Exchange Argument)
-
実務での罠: 「その場で一番良い選択をする」貪欲法は実装が簡単で高速ですが、「局所最適な選択が、全体最適(Global Optimum)を保証するか?」の証明(交換論法など)を怠ると、深刻なバグ(最適解からほど遠い結果)を生みます。
-
-
Huffman Coding(ハフマン符号)
-
歴史秘話: デビッド・ハフマンがMITの大学院生だった1951年、教授から「期末試験を受けるか、それとも最小冗長コードを発明するレポートを書くか」の二択を迫られました。ハフマンはレポートに取り組みましたがどうしても解けず、諦めて捨てようとした直前にこのアルゴリズムを思いつき、見事期末試験を回避しました。これが現代のZIP圧縮やJPEG、MP3の基礎になっています。
-
5. ビット演算・ML・データベース (31:28 - 39:59)
「泥臭い最適化と現代テクノロジー」
-
Bit Manipulation(ビット操作)
-
伝説の逸話: ゲーム業界で有名な「高速逆平方根計算(Fast Inverse Square Root)」というコードがあります。『Quake III Arena』のソースコードに突如現れた
0x5f3759dfという「謎の呪文のような定数」を使ったビット操作は、従来の除算より圧倒的に速く、当時の3Dグラフィックス描画を爆速にしました。
-
-
Database Algorithms(B-Tree, LSM-Tree)
-
業界裏話: 動画のタイムスタンプ最後にある「SQLクエリの裏でDBがやっていること」。リレーショナルDB(PostgreSQLやMySQL)のインデックスにはほぼB+ Treeが使われていますが、書き込み性能を重視するNoSQLや分散DB(RocksDB, Cassandra等)ではLSM-Tree (Log-Structured Merge-tree)が主流です。裏で動いているアルゴリズムが何かを知るだけで、大規模システムのボトルネックを一瞬で見抜けるようになります。
-
この動画(Codist)の構成の巧みな点
一般的なアルゴリズム解説は「アルゴリズムの単体テスト」のように個別の定義を並べがちですが、この動画のように「前のアルゴリズムの限界(制約)を破るために、次の手法が必要になった」というストーリー仕立て(文脈の接続)で学ぶと、単なる丸暗記ではなく、「実務でどの引き出しを開けるべきか」のシステム設計的思考が身につく設計になっています。
以下は、元の構成をベースに、さらに「くすっと笑える/なるほど」系の雑学・歴史・業界裏話を追加した解説です。エンジニアや計算機科学のバックグラウンドを持つ人が「あ、それ知ってる/知らなかったけど納得」となるポイントを意識しています。
1. 探索・ソート・ポインタ手法
O(log n) の破壊的インパクト(続き) 二分探索は1946年にJohn Mauchlyが最初に言及したものの、「Nが2の冪乗-1でない場合」に正しく動くバージョンが登場したのは1960年代になってから。さらに2006年にはJoshua Bloch(当時Google、元Sun)が「ほぼ全ての二分検索とマージソート実装が壊れている」と指摘する有名なバグを公表しました。mid = (low + high) / 2 が整数オーバーフローを起こすやつです。JDKの実装にも潜んでいて、配列長が約10億を超えると発動する「時限爆弾」でした。現代ではlow + (high - low) / 2が定番ですが、これは「大きな数字を扱う時代になって初めて露呈した古典バグ」の典型例です。
O(n²) ソート vs 分割統治法(続き) Tony HoareがQuickSortを思いついたのはモスクワ留学中、ロシア語の文を辞書引きするために単語をソートする必要があったから、というのは有名ですが、実は最初に思いついたのはBubble Sortでした。ベッドに寝転がりながら「これ遅いな…」と思って次に出たのがQuickSortという流れ。さらに彼は「null参照は自分の10億ドルの過ち」と後に公言していますが、当時は「実装が簡単だから入れてしまった」とのこと。現代のNullable型やOptionalの流行は、Hoareの「反省」の延長線上にあります。
Two Pointers / Sliding Window(続き) 実務あるあるとして、面接官が「これをO(n)で書けますか?」と聞くと、候補者が急に沈黙するシーンが多発します。特に「部分配列の最大和」や「最長の連続部分列」系で、二重ループを書いて満足している人に「スライディングウィンドウで右端を進めながら左端を調整するだけ」と指摘されると、顔が青くなるのがお決まりのパターンです。
2. 再帰・バックトラッキング
再帰の3原則(続き) 「再帰を引くと『再帰を参照』と書いてある」ジョークは定番ですが、実務では「終了条件を書き忘れてStack Overflow」が本当に起きがちです。特にPythonは再帰深度がデフォルト1000程度なので、深い木を探索するとあっさり死にます。一方で、末尾再帰最適化(Tail Call Optimization)が効く言語では「再帰なのにスタックを食わない」魔法が使えますが、JavaやPythonでは基本的に効かないので、「再帰で書いたら必ず反復に直す」文化が根強い会社もあります。
Backtrackingと枝刈り(続き) α-β枝刈りはチェスAIの定番ですが、実は「人間の思考を真似ている」というより「人間が無意識にやっている枝刈りを徹底的に機械化した」ものです。Deep Blueがカスパロフに勝ったときも、探索空間を劇的に削る枝刈りが効いていました。現代の将棋AIや囲碁AIでも、モンテカルロ木探索と組み合わせて「筋の悪い手を早めに捨てる」思想が生き続けています。
3. ハッシュと動的計画法
ハッシュ衝突(続き) HashDoS攻撃が流行したのは2011年頃で、特にPerlやRuby、Pythonの古いハッシュ実装が狙われました。攻撃者は「意図的に衝突を大量に起こす文字列」を送りつけ、サーバーをO(n²)の地獄に落とします。これを受けて、現代の言語はシードをランダム化したり、SipHashのような暗号学的に強いハッシュをデフォルトにしたりしています。ちなみに「誕生日のパラドックス」はハッシュ衝突の確率を直感的に理解するのに最適で、「23人いれば誕生日が一致する確率が50%を超える」という事実が、ハッシュテーブルの設計でよく引き合いに出されます。
Dynamic Programming(続き) Bellmanが「Dynamic Programming」と名付けた理由は、当時の国防長官が「Research」や「Mathematics」という言葉を極端に嫌っていたからです。予算を守るために「格好良くて官僚に突っ込まれない言葉」として選んだという政治的カモフラージュ話は有名ですが、実際に彼は自伝で「dynamicという言葉は貶める意味で使えないからちょうどよかった」と書いています。現代の強化学習でBellman方程式が頻出するのも、この「名前の偶然」の延長線上にあるのが面白いところです。
4. グラフ・貪欲法・文字列
Graph Algorithms(続き) Dijkstraが20分で思いついた話は本当で、アムステルダムのカフェで婚約者(後の妻)とコーヒーを飲んでいるときに頭の中だけで完成させました。紙も鉛筆も使わず、「避けるべき複雑さを避けざるを得ない状況」がシンプルなアルゴリズムを生んだ、と本人が後に語っています。ちなみに彼は「Go To Statement Considered Harmful」で有名な厳格主義者でもあり、後年は「構造化プログラミング」の旗振り役になりました。
Greedy Choice(続き) 貪欲法の落とし穴として有名なのが「局所最適が全体最適を保証しないケース」です。特に「活動選択問題」や「ハフマン符号化」は貪欲で正しく動きますが、「最小全域木」でPrimやKruskalが正しいことを証明する「交換論法」を飛ばすと、面接で「なぜこれで最適なんですか?」と聞かれて詰みます。実務でも「とりあえず貪欲で実装して後でバグる」パターンが時々発生します。
Huffman Coding(続き) Huffmanが「期末試験かレポートか」の二択を迫られ、レポートを選んで結局解けず、捨てようとした瞬間に閃いた、というのはほぼ伝説化しています。教授のRobert Fano自身も同じ問題に取り組んでいて、Fanoの方法は必ずしも最適ではなかったのに対し、Huffmanの方法は常に最適でした。学生が教授を超えた稀有な例として語り継がれています。現代のZIPやJPEG、MP3の基盤になっていることを考えると、「期末試験を回避した学生のひらめき」がインターネットの帯域を支えているわけです。
5. ビット演算・ML・データベース
Bit Manipulation(続き) Quake IIIの高速逆平方根(0x5f3759df)は、John Carmackが書いたと思われがちですが、実際の起源は1980年代後半のGreg Walsh(Ardent Computer)に遡ります。Cleve Moler(MATLABの生みの親)からヒントを得て、さらにWilliam Kahanらのビット操作テクニックを基に作られたものです。Quakeに入った経緯は3dfx経由らしいですが、オープンソース化された後も「誰が書いたのか」が長年謎のままでした。現代ではSSEのrsqrtss命令があるので不要になりましたが、「魔法の定数」として語り草になっています。
Database Algorithms(続き) B+ TreeがRDBのインデックスの定番なのは周知の事実ですが、LSM-Treeが書き込み特化で流行した背景には「ランダム書き込みが苦手なSSD/HDDの特性」があります。RocksDBやCassandra、LevelDBなどがこれを採用し、「書き込みをログに追記して後でマージする」思想が分散DBの標準になりました。実務で「このクエリが遅いのはインデックスのせい?」と疑うとき、裏で動いているのがB+ TreeかLSM-Treeかを知っているだけで、ボトルネックの当たりがかなり早くなります。
全体を通じた「アルゴリズムあるある」追加
- 「正しい実装は意外と難しい」問題: 二分検索やQuickSortのパーティションなど、教科書では簡単に書かれているものが、境界条件やオーバーフローで簡単にバグります。Bentleyの『Programming Pearls』でも「正しく動く二分検索を書け」と学生にやらせると、ほとんどが間違う、という逸話があります。
- 「理論上は速いが実用では使わない」銀河アルゴリズム: 例えば整数乗算の最速理論アルゴリズムやAKS素数判定など、「データが地球規模を超えないとメリットが出ない」ものを「Galactic Algorithm」と呼びます。実務では「定数項が大きくて使えない」がよくある話です。
- 名前の由来が政治的だったり偶然だったりする: DPの「Dynamic」もそうですが、アルゴリズムの名前は「格好よさ」や「偶然」で決まることが意外と多いです。
この動画の構成の良いところは、単に個別アルゴリズムを並べるのではなく、「前の手法の限界を突破するために次が生まれた」というストーリーラインになっている点です。実務でも「この制約をどう破るか」という視点でアルゴリズムを選ぶと、設計が一段上手くなります。
0 件のコメント:
コメントを投稿