附錄 A:演算法形式化、程式範例與可行性論證
EveMissLab 工作論文 · 附錄(v0.1 草稿)
本附錄承擔本文刻意推遲的工作:把網頁中實際運行的三個演算法——AFSA、退火 Langevin/Fokker–Planck 測度流、自適應 AMF——逐一抽出,各自配上形式化後的數學定義與更新方程式、基本的程式語言範例(以 Python/NumPy 為例),並論證「為何可以這樣辦到」。本版為初稿,符號與書目將於後續版本統一收斂;程式範例以可讀與忠於網頁邏輯為先,未針對效能優化。
A.0 共同設定與記號
設搜索域 (網頁中 ),食物濃度/適應度場為 。本文一律處理最大化問題:尋找 。種群為 個點 。 表示對域的逐分量投影(clamp)。「公告牌」記錄歷史全局最佳 。
衡量成本的單位是函數評估次數(evaluations),記 ;演算法的優劣以「達到給定解品質所耗的 」衡量,而非迭代次數。本文所有對打皆以 對 的曲線比較,並以同一初始種群 餵給所有競爭者以消除初始偶然性。
容差命中定義為 ,其中 (以細網格掃描近似), 為地形幅度的百分之一。
A.1 AFSA(人工魚群演算法)
A.1.1 形式化
魚 的狀態為位置 、適應度 。參數:視野 、步長 、擁擠度因子 、覓食重試次數 、種群 。
定義「朝目標前進一步」算子(步長帶隨機縮放):
視野鄰域 ,鄰數 。
覓食 Prey. 對 :抽 , ;若 則回傳 並終止。若 次皆失敗,回傳隨機步 。
聚群 Swarm. 中心 。若 且 (中心更優且不擁擠),回傳 ;否則退回 Prey。
追尾 Follow. 取 ,並計其鄰擁擠度 。若 且 ,回傳 ;否則退回 Prey。
行為選擇與公告牌. 對每條魚,模擬 Swarm 與 Follow 兩候選、取結果適應度較高者;若二者皆不優於 ,執行 Prey。所有魚更新後,以最優個體刷新公告牌。終止條件為達容差或迭代上限。
A.1.2 程式範例(Python/NumPy)
import numpy as np
def afsa_step(X, f, lo, hi, visual=1.2, step=0.4, delta=0.62, try_num=5):
"""單次 AFSA 迭代。X: (N,d) 種群;f: 適應度(最大化);lo,hi: 域邊界。"""
N, d = X.shape
Y = np.array([f(x) for x in X])
def move(x, target):
v = target - x
nv = np.linalg.norm(v)
if nv < 1e-9:
return x.copy()
return x + step * np.random.rand() * v / nv
def neighbors(i):
dist = np.linalg.norm(X - X[i], axis=1)
idx = np.where(dist <= visual)[0]
return idx[idx != i]
def prey(i):
for _ in range(try_num):
xj = X[i] + visual * np.random.uniform(-1, 1, d)
if f(xj) > Y[i]:
return move(X[i], xj)
return X[i] + step * np.random.uniform(-1, 1, d) # 隨機遊走
def swarm(i):
nb = neighbors(i); nf = len(nb)
if nf == 0:
return None
xc = X[nb].mean(axis=0)
if f(xc) > Y[i] and nf < delta * N:
return move(X[i], xc)
return None
def follow(i):
nb = neighbors(i)
if len(nb) == 0:
return None
j = nb[int(np.argmax(Y[nb]))]
nf2 = int(np.sum(np.linalg.norm(X - X[j], axis=1) <= visual) - 1)
if Y[j] > Y[i] and nf2 < delta * N:
return move(X[i], X[j])
return None
Xn = X.copy()
for i in range(N):
cands = [c for c in (swarm(i), follow(i)) if c is not None]
best = max(cands, key=lambda c: f(c)) if cands else None
Xn[i] = best if (best is not None and f(best) > Y[i]) else prey(i)
return np.clip(Xn, lo, hi)
A.1.3 為何如此/它在做什麼
AFSA 沒有收斂性證明,它是一個啟發式:其有效性來自三股力的協同,而非任何定理。覓食是帶隨機回退的局部上升,提供探索與「跳出局部最優」的隨機性來源——重試次數 越小,隨機遊走機會越多,越容易逃離局部峰。聚群與追尾是朝參考點(質心、最優鄰居)的吸引,負責資訊共享與利用。擁擠度因子 限制吸引的規模,是它唯一的多樣性保存機制:當局部聚集超過 ,吸引被否決,迫使魚轉向別處。
從本文脊椎的角度看,AFSA 的本質是「吸引(向質心/最優)+隨機回退(覓食失敗時)」的混合,這正是漂移加擴散的離散、語意化版本。它的可讀性高,但代價是把搜索動力學切成數個離散行為分支、以擁擠度數人頭這種粗糙的方式近似多樣性控制——這也是它在崎嶇多峰地形上不穩定的根源。
A.2 退火 Langevin/Fokker–Planck 測度流
A.2.1 形式化
把搜索的主體從個體升格為機率測度 (種群是它的取樣)。過阻尼 Langevin 擴散(對最大化 )為
其中 為 維標準布朗運動, 為溫度。其法則 滿足 Fokker–Planck 方程
穩態分布(Gibbs 測度). 令穩態流 ,得 ,故
當 , 集中於 的全局最大點集——這就是退火的數學意義。
Wasserstein 梯度流身分. 上述 FP 方程是自由能泛函
在 Wasserstein-2 度量下的梯度流(JKO 格式)。第一項(位能)驅動質量湧向高 區(利用),第二項(熵)使質量擴散(探索), 是兩者的權衡。關鍵觀察:AFSA 必須用擁擠度因子手工塞入的「多樣性/反塌縮」機制,在這裡是熵項的自然後果,由 這一擴散項導出,而非憑空設定。
離散化(Euler–Maruyama). 每粒子
退火時間表 。若 不可解析,以中央差分近似 ,每步耗 次評估。
A.2.2 程式範例(Python/NumPy)
import numpy as np
def fd_grad(f, h):
"""中央差分梯度算子;每次呼叫耗 2d 次評估。"""
def g(x):
d = len(x); out = np.zeros(d)
for m in range(d):
e = np.zeros(d); e[m] = h
out[m] = (f(x + e) - f(x - e)) / (2 * h)
return out
return g
def langevin_step(X, grad_f, lo, hi, T, dt=0.01, clip=0.5):
G = np.array([grad_f(x) for x in X]) # 漂移方向(梯度)
drift = dt * G
dn = np.linalg.norm(drift, axis=1, keepdims=True)
drift = drift * np.minimum(1.0, clip / np.maximum(dn, 1e-12)) # 漂移上限(數值穩定)
noise = np.sqrt(2 * T * dt) * np.random.randn(*X.shape) # 擴散項
return np.clip(X + drift + noise, lo, hi)
def anneal(T0, gamma, k, Tmin=0.02):
return max(Tmin, T0 * (gamma ** k))
A.2.3 為何如此(可行性與收斂性)
這套機制之所以「辦得到」,有嚴格理論支撐,而非經驗巧合。其一,穩態存在且明確:法則收斂到 Gibbs 測度 ,故在固定 下,採樣會集中於高適應度區,集中程度由 控制。其二,全局最優可達:經典模擬退火結果(Geman–Geman、Hwang 等)指出,只要退火夠慢(如 ),過程依機率收斂到全局最優;實務上幾何冷卻 是更快但無嚴格保證的折衷。其三,粒子實現合法: 個粒子是 的經驗測度近似, 時它們實現 FP 流;有限 則是其蒙地卡羅版本。
漂移上限(clip)不屬於理論本體,它只是離散化的數值穩定器:在 Rastrigin 這類梯度振幅極大的地形上, 單步可能過大導致發散,clip 將其限幅。它不改變穩態,只保證歐拉離散不爆。本文 Ackley 一戰中測度流昂貴的評估成本,幾乎全來自 fd_grad 的 次評估;若 解析可得,此成本即消失——這是脊椎在「梯度可得」情境下的真實效能,與其在「需數值梯度」情境下被懲罰的表象,必須分開評估。
A.3 AMF(自適應測度流)
A.3.1 形式化
AMF 的設計目標是消除對地形敏感的參數( ),代之以尺度無關、可自我調節的機制。令 為域寬。
方向歸一漂移(尺度無關). 只取梯度方向,不取其大小:
其中 為無量綱溫度因子, 為「每步前進域寬之比例」(預設 ), 為防零除的微量( )。
噪聲(亦尺度無關). 。更新:
自適應溫度時間表(回饋式). 每迭代先幾何冷卻 ;同時監看全局最佳,若連續 步無改善(停滯)則重加熱 並重置停滯計數。預設 、 、 、 。
A.3.2 程式範例(Python/NumPy)
import numpy as np
def amf_step(X, grad_f, lo, hi, tau, span, eta=0.02, sigma=0.045):
G = np.array([grad_f(x) for x in X])
norms = np.linalg.norm(G, axis=1, keepdims=True) + 1e-9
drift = eta * span * tau * (G / norms) # 僅方向,尺度無關
noise = sigma * span * tau * np.random.randn(*X.shape)
return np.clip(X + drift + noise, lo, hi)
def amf_update_tau(tau, improved, stag, W=25, cool=0.99, reheat=3.0, tmin=0.02):
tau = max(tmin, tau * cool) # 幾何冷卻
if improved:
stag = 0
else:
stag += 1
if stag > W: # 停滯重加熱
tau = min(1.0, tau * reheat)
stag = 0
return tau, stag
A.3.3 為何如此(尺度不變性、重加熱、精度稅與修補)
尺度不變性的論證. 適應度線性重標 ( )下,方向歸一漂移 不變,噪聲不依賴 亦不變,故軌跡分布不變——這使同一組 能跨越適應度尺度迥異的地形。域尺度重標 下,漂移與噪聲皆隨 等比縮放,動力學相似。這正是「一組元參數零重調打多張地形」在原理上成立的根據。
方向歸一治平原. Ackley 的平原上 ,純 Langevin 的漂移 隨之消失、退化為盲目擴散;但 即使在微小梯度下仍給出方向,使 AMF 以固定的域寬比例穩定內進。這是 AMF 在 Ackley 上比手調 Langevin 更省評估的結構性原因。
重加熱即自適應逃生. 固定退火時間表無法因地形調整;停滯重加熱則讓溫度由「是否卡住」這個運行時訊號驅動:陷入停滯時抬高 ,重新膨脹探索半徑,類比於自適應模擬退火的再加熱。代價是評估次數——逃生能力是用 買來的(本文 Rastrigin 上 AMF 評估近乎翻倍即源於此)。
精度稅的形式化與修補. 病灶在於:靠近最優時改善終將停滯於容差帶內,於是重加熱不斷把 踢離 ,殘餘噪聲量級 持續擾動,使解無法收緊——這就是 AMF 最終差距普遍劣於專家的根源。修補方向(待形式化與實作):引入終局相,以多樣性塌縮(如下節 )配合全局最佳穩定改善為觸發條件,判定真盆地已鎖定後關閉重加熱、強制 硬退火精修,等於把「探索者」與「收割者」分為前後兩個人格。預期可退回大部分精度稅而不需人手切換。
A.4 共同基礎設施與延伸焊接(待形式化)
以下為支撐對打的基礎設施與本文提及、尚待形式化的改良方向,列其數學骨架以誌後續。
評估公平軸. 以一個計數包裝器攔截所有對 的呼叫,分演算法累加 ;收斂曲線以 對 繪製。此為對打公平性的技術保證。
多樣性診斷(取代擁擠度 ). 對種群建半徑圖 ,度矩陣 ,Laplacian 。代數連通度 (第二小特徵值)為連續、幾何感知的多樣性/早熟感測器: 表示種群塌成單一連通團。可作為 commit 相觸發訊號,亦可取代 的二元數人頭。
持續同調 niching(多峰覆蓋). 對適應度場的超水平集過濾 計算 barcode,每根高持續性條對應一個顯著盆地及其 prominence;據此把子群分配到不同高持續盆地,可證地覆蓋所有超過持續性門檻的峰。
資訊幾何/自然梯度(各向異性步長). 把局部子群視為高斯,沿 Fisher 度量做自然梯度更新,使步長升格為度量量、自動適配局部曲率與協方差——即 CMA-ES 的核心,置於正確的抽象層級。
終局相(精度修補). 如 A.3.3,以 塌縮 + 全局最佳穩定改善為觸發,關閉重加熱並硬退火,回收 AMF 的精度稅。
本附錄為 v0.1 草稿。下一步:補齊 A.2.3 收斂性陳述的條件與引用、為 A.4 各延伸方向各立子附錄、並將程式範例整合為可重現的對打腳本。