← Archive
lm-002067 · 2026-08

02_暴力窮舉不只需要計算力

下載 MD 檔 ⬇

02.暴力窮舉不只需要計算力

系列:《從路徑覆蓋到行星智能:記憶編譯型計算存在論》
部別:第一部——搜尋、記憶與路徑覆蓋
版本:v0.1
日期:2026-08-01


摘要

暴力窮舉通常被描述為一個「算力不足」的問題:候選數量太大,所以只要計算得更快,就能展開更多狀態。然而這種敘述忽略了一個更基本的事實:任何實際搜尋系統都不只是在做算術運算,它還必須保存中間狀態、決定哪些節點尚待展開、維持長序列、避免重複、從歷史中重新取回相關路徑,並把局部結果重新組合成可持續的搜尋過程。

本文因此將暴力搜尋拆解為五種彼此耦合但不可互相取代的能力:計算能力 κ\kappa 、記憶能力 μ\mu 、展開能力 ϵ\epsilon 、序列生成能力 σ\sigma 與回憶能力 ρ\rho 。本文借用圖搜尋的時間—空間差異、系統動力學、帶記憶的非馬可夫系統與泛函表示,建立一個最小耦合模型,說明為何「提高算力」並不等於「提高有效覆蓋率」,以及為何一個真正高效的搜尋智能體必須同時管理分支寬度、路徑深度、記憶密度、索引效率與重複展開。

本文的目的不是提出新的複雜度類別,也不是用認知術語取代演算法理論,而是建立後續「高重疊知識空間」、「有效覆蓋率」與「記憶編譯型智能體」所需的能力分解框架。

關鍵詞: 暴力窮舉、圖搜尋、記憶、展開、序列生成、回憶、時間—空間權衡、非馬可夫系統、計算智能


1.暴力搜尋真的只是「一直算」嗎?

最直覺的暴力窮舉可以寫成:

Ω={x1,x2,,xN}\Omega= \{x_1,x_2,\ldots,x_N\}

然後逐一驗證:

V(xi){0,1}V(x_i)\in\{0,1\}

直到找到可接受解。

如果候選數量隨問題規模快速增加,例如:

N=2nN=2^n

我們自然會認為主要瓶頸是:

計算速度不足\text{計算速度不足}

因此最簡單的想像是:

更強算力每秒驗證更多候選\text{更強算力} \Rightarrow \text{每秒驗證更多候選}

這當然沒有錯。

但只要搜尋不是「每個候選彼此完全獨立」,事情就開始改變。

真實搜尋往往更接近一個狀態圖:

G=(V,E)G=(V,E)

其中從狀態 viv_i 展開後產生一組後繼:

Γ+(vi)={vi1,vi2,,vib}\Gamma^+(v_i)= \{v_{i1},v_{i2},\ldots,v_{ib}\}

此時系統至少還要知道:

  • 哪些節點已經走過;
  • 哪些節點尚待展開;
  • 當前路徑是什麼;
  • 是否形成循環;
  • 哪些中間結果可以重用;
  • 哪些分支已經證明無效;
  • 是否需要返回較早的狀態;
  • 是否有相似問題曾經被處理過。

所以搜尋不是單一算術操作,而是一整套動態過程。


2.經典圖搜尋已經透露了這個問題

以最基本的 BFS 與 DFS 為例。

廣度優先搜尋傾向同時保存大量待展開節點,因此具有較高的記憶需求;深度優先搜尋則沿單一路徑深入,通常只需要保存較小的活動路徑與回溯資訊。

若分支因子為 bb ,最淺解深度為 dd ,最大搜尋深度為 DD ,典型樹搜尋的粗略複雜度可以表示為:

TBFS=O(bd)T_{\mathrm{BFS}} = O(b^d) SBFS=O(bd)S_{\mathrm{BFS}} = O(b^d)

而 DFS 常寫為:

TDFS=O(bD)T_{\mathrm{DFS}} = O(b^D) SDFS=O(D)S_{\mathrm{DFS}} = O(D)

這裡最重要的不是背公式,而是看到一件事:

搜尋能力天然同時包含時間與空間。\boxed{ \text{搜尋能力天然同時包含時間與空間。} }

兩個演算法可以擁有類似的「展開動作」,卻因為記憶管理方式不同,形成完全不同的搜尋行為。

因此,暴力窮舉即使在最經典的演算法形式中,也從來不只是「計算幾次」這麼簡單。


3.第一項能力:計算能力 κ\kappa

本文把計算能力記為:

κ\kappa

它表示單位時間內可完成的狀態轉換、比較、評分、驗證或運算量。

粗略地,可以想成:

κoperationstime\kappa \sim \frac{\text{operations}}{\text{time}}

如果其他條件都不變,提高 κ\kappa 可以讓系統:

  • 更快驗證候選;
  • 更快計算後繼;
  • 更快比較策略;
  • 更快完成局部推理。

若單一節點平均需要計算成本 cvc_v ,理想狀態下單位時間可處理節點數約為:

RcomputeκcvR_{\mathrm{compute}} \approx \frac{\kappa}{c_v}

但這只是理論吞吐量。

如果系統沒有足夠記憶保存產生的節點,或沒有能力決定下一個該處理誰,那麼:

Reffective<RcomputeR_{\mathrm{effective}} < R_{\mathrm{compute}}

甚至可能遠小於它。

所以:

κ 決定你能算多快,但不決定你算的是不是新的東西。\boxed{ \kappa\text{ 決定你能算多快,但不決定你算的是不是新的東西。} }

4.第二項能力:記憶能力 μ\mu

記憶能力記為:

μ\mu

但這裡不能只把它理解成硬碟容量。

至少要區分:

μ=(μcapacity,μretention,μorganization)\mu= (\mu_{\mathrm{capacity}}, \mu_{\mathrm{retention}}, \mu_{\mathrm{organization}})

也就是:

  • 能存多少;
  • 能保存多久;
  • 能否以可利用形式保存。

對搜尋而言,記憶至少承擔四種功能:

4.1 保存當前活動前沿

例如 BFS 的 queue:

Ft={v1,v2,,vm}F_t= \{v_1,v_2,\ldots,v_m\}

這些都是尚待展開的候選狀態。


4.2 保存已訪問集合

Ht={v:visited before t}H_t= \{v:\text{visited before }t\}

用來避免循環與重複。

若沒有 HtH_t ,圖搜尋可能將同一個狀態反覆當成新狀態。


4.3 保存局部結果

例如:

f(xi)=yif(x_i)=y_i

若未來再次需要 f(xi)f(x_i) ,可以直接重用。


4.4 保存完整或部分路徑

p=(v0,v1,,vn)p= (v_0,v_1,\ldots,v_n)

使系統可以回溯、解釋或從中間狀態重新開始。

因此,記憶不是搜尋結束後才附加上去的「紀錄功能」。

它本身就是搜尋演算法的一部分。


5.第三項能力:展開能力 ϵ\epsilon

本文將展開能力記為:

ϵ\epsilon

它表示系統從當前狀態產生候選後繼的能力。

對某狀態 vv

E(v)={v1,v2,,vb}E(v)= \{v_1',v_2',\ldots,v_b'\}

其中 bb 是有效分支數。

如果 ϵ\epsilon 很低,系統可能一次只能提出很少候選。

如果 ϵ\epsilon 很高,則可以快速生成:

b1b\gg1

的大量分支。

表面上看:

ϵ搜尋能力\epsilon\uparrow \Rightarrow \text{搜尋能力}\uparrow

但這只在其他能力同步提高時成立。

因為展開本身會產生新的負擔:

ϵFt\epsilon\uparrow \Rightarrow |F_t|\uparrow

也就是待處理前沿快速增大。

當:

dFtdt>dNprocesseddt\frac{d|F_t|}{dt} > \frac{dN_{\mathrm{processed}}}{dt}

系統會出現「候選生成速度大於候選消化速度」的情況。

此時更強的展開能力反而製造擁塞。

因此:

能想到更多可能性能有效處理更多可能性\boxed{ \text{能想到更多可能性} \neq \text{能有效處理更多可能性} }

6.第四項能力:序列生成能力 σ\sigma

展開能力回答的是:

我一次能產生多少後繼?

序列生成能力則回答:

我能否維持一條長而連續的有效路徑?

將它記為:

σ\sigma

假設一條路徑為:

pn=(v0,v1,,vn)p_n= (v_0,v_1,\ldots,v_n)

序列生成能力涉及:

  • 維持前面狀態的約束;
  • 保持長距離一致性;
  • 知道當前位於哪一層;
  • 在需要時回溯;
  • 避免局部正確、全局失效。

一個系統完全可能具有:

ϵ1\epsilon\gg1

卻只有:

σϵ\sigma\ll\epsilon

也就是很會產生候選,但不擅長把候選組成長程路徑。

這種系統的外部表現可能是:

  • 靈感很多;
  • 分支很多;
  • 局部建議很多;
  • 但長任務容易失去一致性。

反之,一個 σ\sigma 很高但 ϵ\epsilon 很低的系統,則可能:

  • 能沿著一條路走很遠;
  • 但不容易想到替代路徑。

所以:

分支寬度路徑深度維持能力\boxed{ \text{分支寬度} \neq \text{路徑深度維持能力} }

7.第五項能力:回憶能力 ρ\rho

回憶能力記為:

ρ\rho

它不是「記憶中有沒有」,而是:

當前狀態能否快速索引到真正有用的歷史資訊?

若記憶空間為:

M={m1,m2,,mN}\mathcal M= \{m_1,m_2,\ldots,m_N\}

面對查詢狀態 qq ,回憶函數可以寫成:

R(q,M)MqR(q,\mathcal M) \rightarrow \mathcal M_q

其中:

MqM\mathcal M_q\subseteq\mathcal M

是與當前任務相關的記憶。

如果記憶容量巨大:

M1|\mathcal M|\gg1

但每次都需要線性掃描:

Tretrieve=O(M)T_{\mathrm{retrieve}} = O(|\mathcal M|)

那麼「記得很多」可能反而讓系統越來越慢。

真正可用的強記憶,需要:

高容量+高精度索引+低檢索延遲\text{高容量} + \text{高精度索引} + \text{低檢索延遲}

因此:

μ 決定保存了多少,ρ 決定需要時能拿回多少。\boxed{ \mu\text{ 決定保存了多少,}\rho\text{ 決定需要時能拿回多少。} }

8.五項能力不是加法,而是耦合

最簡單的錯誤模型是:

I=κ+μ+ϵ+σ+ρI= \kappa+\mu+\epsilon+\sigma+\rho

這暗示任何一項增加,都能等量增加整體搜尋能力。

但實際上,更合理的是:

Ieff=F(κ,μ,ϵ,σ,ρ)I_{\mathrm{eff}} = F(\kappa,\mu,\epsilon,\sigma,\rho)

其中 FF 具有強烈耦合。

例如:

ϵ\epsilon\uparrow

只有在:

κ,μ,ρ\kappa,\mu,\rho

足以處理新增候選時,才真正增加有效探索。

同樣地:

μ\mu\uparrow

只有在:

ρ\rho\uparrow

或至少不顯著下降時,才增加可用記憶。

可以用一個純概念性的乘法模型表示:

Ieff=καμβϵγσδρηI_{\mathrm{eff}} = \kappa^\alpha \mu^\beta \epsilon^\gamma \sigma^\delta \rho^\eta

其中:

α,β,γ,δ,η>0\alpha,\beta,\gamma,\delta,\eta>0

這不是經驗定律,而是在表達:

某一項接近零時,其他能力再高也可能無法完全補償。


9.瓶頸形式:最弱能力可能決定整體吞吐量

另一種建模方式是:

Ieffmin{fκ(κ),fμ(μ),fϵ(ϵ),fσ(σ),fρ(ρ)}I_{\mathrm{eff}} \leq \min \{ f_\kappa(\kappa), f_\mu(\mu), f_\epsilon(\epsilon), f_\sigma(\sigma), f_\rho(\rho) \}

例如:

  • 每秒可以生成一萬個候選;
  • 但每秒只能驗證一千個;
  • 那麼剩下九千個會堆積。

或者:

  • 可以保存十億條記憶;
  • 但每次只能有效找到其中十條;
  • 那麼大量容量不能直接轉化為反應能力。

這和流體系統或管線系統很相似:

QsystemminiQiQ_{\mathrm{system}} \approx \min_i Q_i

最窄的瓶頸限制整體流量。

因此,一個高性能搜尋智能體的設計目標不是單點極大化,而是:

讓五種能力的比例彼此匹配。\boxed{ \text{讓五種能力的比例彼此匹配。} }

10.用系統動力學描述候選前沿

設:

F(t)F(t)

為尚未處理的候選前沿數量。

候選被產生的速率可寫成:

G(t)=g(ϵt,σt)G(t) = g(\epsilon_t,\sigma_t)

候選被處理的速率為:

P(t)=p(κt,ρt,μt)P(t) = p(\kappa_t,\rho_t,\mu_t)

那麼:

dFdt=G(t)P(t)D(t)\frac{dF}{dt} = G(t)-P(t)-D(t)

其中 D(t)D(t) 是因去重、剪枝或失效而直接移除的候選量。

如果:

G(t)>P(t)+D(t)G(t)>P(t)+D(t)

則:

F(t)持續膨脹F(t)\rightarrow\text{持續膨脹}

這就是搜尋爆炸的一種動力學表述。

因此,「更能展開」甚至可能使系統更快進入資源飽和。

真正重要的是:

G(t)D(t)P(t)\frac{G(t)-D(t)}{P(t)}

是否可以維持在系統可承受區域。


11.記憶如何改變搜尋動力學?

若完全沒有歷史記憶,系統看到一個狀態時,只能當作新的候選處理。

設原始生成速率為:

G0(t)G_0(t)

若記憶與回憶可以辨識其中比例:

rt[0,1]r_t\in[0,1]

為已知或高度重複狀態,那麼真正需要重新計算的有效生成速率為:

Geff(t)=G0(t)(1rt)G_{\mathrm{eff}}(t) = G_0(t)(1-r_t)

當:

rtr_t\uparrow

即使原始展開量沒有下降:

G0(t)=constantG_0(t)=\text{constant}

真正需要支付的重新計算成本仍然下降。

這是本系列後面極重要的一個方向:

智能提升不一定來自算得更多,也可能來自需要重算的東西變少。\boxed{ \text{智能提升不一定來自算得更多,也可能來自需要重算的東西變少。} }

12.從馬可夫搜尋到帶歷史的非馬可夫搜尋

如果下一步只依賴當前狀態:

P(xt+1xt)P(x_{t+1}\mid x_t)

我們得到的是近似馬可夫式描述。

但具有長期記憶的智能體,其決策可能依賴:

x0,x1,,xtx_0,x_1,\ldots,x_t

更一般地:

P(xt+1)=P(xt+1xt,Mt)P(x_{t+1}) = P \left( x_{t+1} \mid x_t,\mathcal M_t \right)

而:

Mt=U(x0,,xt)\mathcal M_t = U(x_0,\ldots,x_t)

所以當前搜尋方向受到歷史影響。

用記憶核 KK 表示,可以概念性地寫成:

x˙t=F(xt,0tK(ts)xsds)\dot x_t = F \left( x_t, \int_0^tK(t-s)x_s\,ds \right)

這表示:

過去走過的路徑會改變現在的搜尋向量場。

當某些區域已被大量探索,系統可以降低它們的再次進入權重;當某些路徑曾經失敗,也可以直接抑制相似展開。

因此記憶不是被動檔案,而是:

改寫未來搜尋機率的動態場。\boxed{ \text{改寫未來搜尋機率的動態場。} }

13.泛函表示:搜尋能力是一個作用在狀態空間上的算子族

設知識或候選狀態位於某個函數空間:

H\mathcal H

可以暫時引入五個算子:

K\mathcal K

代表計算與轉換;

M\mathcal M

代表記憶保存;

E\mathcal E

代表候選展開;

S\mathcal S

代表序列延伸;

R\mathcal R

代表記憶回取。

那麼一次完整的智能搜尋不再是單一函數:

f:xyf:x\rightarrow y

而更像算子組合:

T=VKRSEM\mathcal T = \mathcal V \circ \mathcal K \circ \mathcal R \circ \mathcal S \circ \mathcal E \circ \mathcal M

實際順序可以依系統而不同,也可能形成迴圈:

EKMRE\mathcal E \rightarrow \mathcal K \rightarrow \mathcal M \rightarrow \mathcal R \rightarrow \mathcal E

因此,真正需要研究的是:

算子之間的作用與回饋\text{算子之間的作用與回饋}

而不是只看某一個算子的速度。


14.展開能力過強也可能降低有效覆蓋率

假設單位時間生成候選數:

NgenN_{\mathrm{gen}}

其中真正新的候選為:

NnewN_{\mathrm{new}}

則可以定義一個簡單的有效展開率:

ηexpand=NnewNgen\eta_{\mathrm{expand}} = \frac{N_{\mathrm{new}}}{N_{\mathrm{gen}}}

若系統瘋狂生成大量相似狀態:

NgenN_{\mathrm{gen}}\uparrow

但:

NnewconstantN_{\mathrm{new}} \approx\text{constant}

則:

ηexpand\eta_{\mathrm{expand}}\downarrow

因此:

更多生成⇏更多有效覆蓋\text{更多生成} \not\Rightarrow \text{更多有效覆蓋}

這正是下一篇要進一步處理的高重疊知識空間問題。


15.記憶容量過強也可能形成新瓶頸

同樣地,假設:

Mt|\mathcal M_t|\rightarrow\infty

但索引品質不變。

若每次檢索都必須在越來越大的記憶中做近似全域搜尋,則:

Tretrieve=f(M)T_{\mathrm{retrieve}} = f(|\mathcal M|)

可能持續上升。

於是出現一種反直覺情況:

μ\mu\uparrow

卻:

ρeffective\rho_{\mathrm{effective}}\downarrow

也就是:

記得越多,越難找到真正需要的東西。

所以後續若要討論「極強記憶智能體」,不能只假設無限容量,還必須要求:

可用記憶的增長速度高於檢索負擔的增長速度。\boxed{ \text{可用記憶的增長速度高於檢索負擔的增長速度。} }

這會直接導向後面「極致分類與快速索引」的主題。


16.序列能力與記憶之間也存在交換

一條長路徑:

pn=(v0,,vn)p_n= (v_0,\ldots,v_n)

可以用至少兩種方式維持。

第一種是完整保存:

M(pn)=(v0,,vn)M(p_n)= (v_0,\ldots,v_n)

第二種是只保存:

M(pn)=(A,G,V)M(p_n)= (A,G,V)

其中:

  • AA :少數錨點;
  • GG :路徑生成規則;
  • VV :驗證條件。

然後需要時重新生成中間段。

這表示:

μ\mu

與:

σ+κ\sigma+\kappa

之間可能存在某種資源交換。

保存更多,可以減少重新生成;

保存更少,則需要更強生成與計算。

因此:

記憶與計算不是單向替代,而是一種動態時間—空間—生成權衡。\boxed{ \text{記憶與計算不是單向替代,而是一種動態時間—空間—生成權衡。} }

17.一個最小耦合狀態向量

現在可以把五種能力寫成:

zt=(κt,μt,ϵt,σt,ρt)z_t= \left( \kappa_t, \mu_t, \epsilon_t, \sigma_t, \rho_t \right)

並定義整體有效搜尋能力:

Qt=F(zt,Ωt,Ht)Q_t= F(z_t,\Omega_t,H_t)

其中:

  • Ωt\Omega_t :仍可能需要探索的空間;
  • HtH_t :已探索歷史。

若要再加入重複率:

Dt[0,1]D_t\in[0,1]

則可以寫一個概念性的有效覆蓋速率:

dCdt=ακtϵtσtρtΨ(μt)(1Dt)\frac{dC}{dt} = \alpha \kappa_t \epsilon_t \sigma_t \rho_t \Psi(\mu_t) (1-D_t)

其中 Ψ(μt)\Psi(\mu_t) 表示記憶被有效組織後對搜尋產生的增益。

這不是物理定律,也不是已驗證經驗式,而是一個理論骨架。

它要表達的只有一件事:

有效覆蓋率是多項能力的耦合結果。\boxed{ \text{有效覆蓋率是多項能力的耦合結果。} }

18.真正的暴力搜尋其實有六個循環

一個完整的搜尋智能體可以被拆成:

生成候選\text{生成候選} \downarrow 保存候選\text{保存候選} \downarrow 選擇下一狀態\text{選擇下一狀態} \downarrow 計算/驗證\text{計算/驗證} \downarrow 更新歷史記憶\text{更新歷史記憶} \downarrow 回憶與去重\text{回憶與去重}

然後重新進入:

生成候選\text{生成候選}

因此暴力窮舉更完整的形式不是:

for xΩ:  V(x)\text{for }x\in\Omega:\;V(x)

而是:

生成—記憶—調度—計算—回寫—回憶\boxed{ \text{生成—記憶—調度—計算—回寫—回憶} }

的反覆閉環。


19.從「暴力窮舉」走向「記憶化覆蓋」

當系統沒有記憶時,最接近:

blind expansion\text{blind expansion}

每次只知道目前位置。

當加入 visited set、dynamic programming、memoization、transposition table 或其他重用機制後,系統開始把:

已支付的計算\text{已支付的計算}

保存成:

未來可以跳過的計算\text{未來可以跳過的計算}

如果再加入跨問題的長期記憶與結構索引,則進一步變成:

過去任務未來任務的搜尋先驗\text{過去任務} \rightarrow \text{未來任務的搜尋先驗}

這就是本系列真正想推進的方向:

搜尋不再只是當下展開,而是被整個歷史塑形的覆蓋過程。\boxed{ \text{搜尋不再只是當下展開,而是被整個歷史塑形的覆蓋過程。} }

20.本文的三個核心結論

20.1 暴力窮舉不只需要計算力

因為搜尋還需要:

μ,ϵ,σ,ρ\mu,\epsilon,\sigma,\rho

共同工作。


20.2 展開量不等於有效覆蓋量

如果大量路徑重複:

raw expansioneffective expansion\text{raw expansion}\gg\text{effective expansion}

那麼更高吞吐量只會更快製造冗餘。


20.3 記憶的真正價值是降低未來重算率

高效智能不只追求:

κ\kappa\uparrow

還追求:

P(需要重新從零計算)P(\text{需要重新從零計算})\downarrow

因此,智能的累積效應可以來自:

更多計算+更少重算\boxed{ \text{更多計算} + \text{更少重算} }

21.結論:下一步不是算得更多,而是問「哪些根本不必再算」

一個完全沒有歷史的計算系統,面對巨大狀態空間時,只能不斷重新展開。

一個具有持久記憶、有效回憶與序列能力的系統,則可以逐漸把已經探索過的空間從:

待求解\text{待求解}

轉化為:

可索引\text{可索引}

真正的分水嶺因此不是:

每秒能算多少?

而是:

每秒新增了多少不可由既有歷史替代的覆蓋?

於是,本篇最後留下的問題是:

如果知識空間本身存在極大量重複、交叉、循環與等價路徑,那麼應該如何定義真正的「新覆蓋」?\boxed{ \text{如果知識空間本身存在極大量重複、交叉、循環與等價路徑,那麼應該如何定義真正的「新覆蓋」?} }

這正是下一篇:

《知識不是樹:高重疊知識空間中的路徑問題》

所要處理的核心。


參考資料

  1. MIT OpenCourseWare, Lecture 12: Searching I: Graph Search and Representations, Introduction to Algorithms.
    https://ocw.mit.edu/courses/6-006-introduction-to-algorithms-spring-2008/resources/lec12/

  2. Stanford CS221, States-based Models Cheatsheet.
    https://stanford.edu/~shervine/teaching/cs-221/cheatsheet-states-models/

  3. NIST Dictionary of Algorithms and Data Structures, Asymptotic Space Complexity.
    https://xlinux.nist.gov/dads/HTML/asymptoticSpaceComplexity.html

  4. Hu, Y. et al., Memory in the Age of AI Agents, arXiv, 2025.
    https://arxiv.org/abs/2512.13564

  5. Lipton, Z. C., Berkowitz, J., & Elkan, C., A Critical Review of Recurrent Neural Networks for Sequence Learning, arXiv, 2015.
    https://arxiv.org/abs/1506.00019


系列內部依賴

前置: 01《知道答案之後,真的就容易了嗎?》
後續: 03《知識不是樹:高重疊知識空間中的路徑問題》、04《從路徑數量到有效覆蓋率》、06《記憶編譯型狀態智能體》。

一句話摘要

搜尋效率不是單純的計算吞吐量,而是計算、記憶、展開、序列生成與回憶共同決定的有效新增覆蓋率。\boxed{ \text{搜尋效率不是單純的計算吞吐量,而是計算、記憶、展開、序列生成與回憶共同決定的有效新增覆蓋率。} }