前一陣子我在想一個問題:有沒有哪些演算法,AI 系統天天在用,但刷題刷不到?
查完之後可以確定:這不是錯覺,而且不是少數幾個漏網之魚,是一整族。
題庫收錄的是「好出題的」,不是「重要的」
先講落差怎麼來的,因為這比清單本身有用。
人類的演算法教材、LeetCode、競賽題庫,高度集中在同一族題目:精確、離散、單機、最壞情況分析。輸入固定、答案唯一、複雜度可以證明。
這些特性有一個共通點——好評分。有唯一標準答案,機器判得出對錯;複雜度可以分析,能出「請優化到 O(n log n)」這種要求。
而 AI 生產系統大量依賴的是另一族:機率的、近似的、串流的、相似度導向的。它們的共同特徵是「用可控的誤差換規模」——我不保證找到最近的那一筆,我保證九成九的時候找到夠近的,而代價從幾小時降到幾毫秒。
這種東西沒辦法出成考題。「請估算這個資料流有幾個不重複的值,誤差 2% 以內」——標準答案是什麼?允許哪些解法?改題老師怎麼判?
所以結論是這句:題庫的 label 集中,是「可考試性」的產物,不是「重要性」的排序。
一個東西沒有出現在你的學習路線圖上,可能是因為它不重要,也可能是因為它不好考。這兩件事長得很像,但完全不一樣。
它們其實都是經典演算法的親戚
這是我覺得最值得講的部分——這族東西看起來陌生,是因為名字陌生,不是因為概念陌生。
最好的例子是 HNSW,向量資料庫(存 embedding 的那種資料庫,RAG 檢索靠它)的核心索引結構。名字看起來很嚇人,但它就是 skip list 和圖的合體——skip list 那個「上層跳得遠、下層走得細」的多層結構,套在圖上就是 HNSW 的分層導航。
你如果讀過 skip list,你已經懂了 HNSW 的一半。
底下這張表就是照「血緣」整理的。左邊是名字,中間是它實際在幹嘛,右邊是它的親戚——而那些親戚在這個系列裡多半已經有文章了。
| 名字 | 它在做什麼 | 血緣 |
|---|---|---|
| HNSW | 在幾億筆向量裡快速找出「最像的前幾筆」,不保證最準但夠近 | skip list + 圖 |
| Product Quantization / IVF-PQ | HNSW 的另一半:把每筆向量壓縮成幾個位元組,好讓十億筆塞得進記憶體 | 分塊 + k-means 量化 |
| MinHash + LSH | 判斷兩份文件像不像,不用兩兩比對——訓練資料去重靠它 | hash table + bloom filter |
| SimHash | 同上的另一個做法,Google 拿來去掉重複網頁 | 同 sketch 家族 |
| Count-Min Sketch / HyperLogLog | 用一點點記憶體估「這個東西出現幾次」「總共有幾種」,允許誤差 | sketches / HyperLogLog |
| Reservoir Sampling / Alias Method | 資料像水流一樣流過、無法全部存下時,怎麼公平抽樣;LLM 決定「下一個字選哪個」的底層也是它 | randomized |
| 加權 Reservoir Sampling | 上面的加權版,每筆被抽中的機率不同(推薦、訓練資料配比用) | Reservoir 變體 |
| Beam Search | 生成句子時同時保留 k 條最有希望的候選路徑,而不是每步只選最好的那個 | BFS + greedy + DP 混血 |
| Speculative Decoding | 讓小模型先猜幾個字、大模型一次驗證,猜對就賺到、猜錯就回滾——現在 LLM 加速的主力 | 分支預測 + 驗證回滾 |
| BPE Tokenization | 把文字切成模型看得懂的單位,所有 LLM 的第一步 | greedy + Huffman |
| Myers Diff | 算出兩份檔案的最小差異——coding agent 每改一次檔就用一次 | LCS / edit distance 變體 |
| BM25 + RRF | 關鍵字檢索的評分法,以及把它跟向量檢索的結果融合排序;RAG 的混合檢索骨幹 | 資訊檢索出身,幾乎不進演算法課 |
| Viterbi | 一串觀測值反推最可能的隱藏狀態序列(詞性標注、語音對齊) | DP 直系 |
| MCTS + UCB | 在太大而不能全搜的空間裡,靠反覆試探決定往哪走;AlphaGo 和 agent 規劃都用 | 賽局 + randomized |
| 反向模式自動微分 | backprop 的本質——沿著計算圖倒著算梯度 | 拓撲排序 + DAG 上的 DP |
| Consistent Hashing | 加減機器時只搬動一小部分資料,不用全部重算 | hash table 的分散式延伸 |
| 語意快取 / KV cache | 把算過的東西留著,下次相似的請求直接用 | LRU cache 延伸 |
有些東西我刻意沒收
FlashAttention、RoPE、t-SNE 和 UMAP 這幾個,AI 圈很重視,但我沒放進來。
理由是它們屬於架構設計或數值方法,不是傳統意義的演算法——FlashAttention 是 GPU 記憶體存取的優化,RoPE 是位置編碼的設計,t-SNE/UMAP 是降維統計。
我用的收錄標準是「有狀態變化可以一步一步呈現出來」。這個標準剛好把上面那幾個過濾掉,也剛好保證清單裡的每一個都能畫成動畫看懂。
如果要把這族做成視覺化,有一件事一定要畫進去
我在做演算法視覺化的時候想通一件事:這族東西的視覺化,不能只畫「它怎麼運作」,要同時畫出「估計值 vs 真實值」。
經典演算法的視覺化畫的是過程——資料怎麼被搬動、指標怎麼移動,結果一定是對的。但 sketch 家族和近似最近鄰搜尋的重點根本不在過程,在於它錯了多少、錯得值不值得。
HyperLogLog 估出來說有 10,342 個不重複值,真實答案是 10,289——這個 0.5% 的誤差換來的是「用幾 KB 記憶體處理幾億筆資料」。不把那個誤差畫出來,觀眾看到的就只是一個奇怪的雜湊技巧,看不到這族演算法真正的交易條件。
用精確度換規模,這件事本身才是要被看見的東西。而這也正是它們跟經典演算法最大的觀念差異——經典演算法問「怎麼算得更快」,這一族問「要不要算得那麼準」。
這些視覺化,現在都能點開玩
上面那個原則我後來真的做出來了——底下這一整套互動頁,每一個都同幀對照「近似結果」和「暴力真值」,你可以自己調參數,看誤差怎麼隨規模變化。想印證「用精確度換規模」是什麼感覺,直接點開比讀十段文字都快。
向量檢索(RAG 的骨架)
HNSW 近似最近鄰、 IVF 向量壓縮、 SimHash 相似度雜湊、 RRF 混合檢索、MMR 去冗餘重排
串流估計(最能看出估計 vs 真值的落差)
HyperLogLog、Heavy Hitters、 Alias 取樣
LLM 生成
Top-p 取樣、 Viterbi 序列解碼、Speculative Decoding 推測解碼、 DFA、Scaled Dot-Product Attention
其他這族成員
UCB 樹搜尋、反向模式自動微分、k-means 分群、 KV Cache、 Myers Diff 文本演算法、差分隱私 Randomized Response
相關
- 這一族的近親多半在系列裡都有:skip list、bloom filter、sketches、HyperLogLog、randomized
- 刷題路線 → LeetCode Roadmap