天赐范式第187天·第二篇:让变异开始定价------动态环境下最优变异率
摘要
扫σ_v×峰速双网格测平均fitness。动态环境(v>0)最优变异率σ_v*存在且随峰速增大(0.020→0.100),bet-hedging:环境变化率与变异率必须匹配。

一、接续187-1:峰动了,变异率有了双向作用
上一篇让峰开始移动,给出了lag*=v·(1−β·h²·K)/(β·h²·K)的跟踪滞后定量。这里有一个隐含的杠杆:lag*的分母里有h²*,而h²*由σ_v决定。
在静止环境里(183-1),变异率只有单向作用:σ_v越大→h²越大→选择越强,没有倒U,没有最优变异率。
峰一动,σ_v就有了双向作用:
- σ_v太小 → 遗传方差不够 → h²低 → 跟踪速率βh²K低 → lag大 → fitness损失
- σ_v太大 → Var(g)大 → 个体散布大 → 瞬时fitness掉
双向作用 → 应该有最优σ_v*。这就是bet-hedging的雏形:环境变化率与变异率必须匹配。
二、183-1的开放问题
183-1结论:加性模型下没有最优变异率------σ_v越大选择越强,倒U不出现,因为静止环境里变异纯受益。
这个结论在静止环境下成立。但直觉里那个倒U没错------缺了环境变化这个项。187-1把环境变化加进来了,187-2看倒U出不出现。
注意:187的模型与183不同。 183用固定TARGET=0.5,187回归到种群均值μ(187-1已说明)。所以v=0行不是严格复现183-1,而是新模型下的静止基准。
三、双网格实验设计
模型与187-1一致:g'=μ+β·(g_sel−μ)+v_mut,fitness峰x*(t)=x*_0+peak_v·gen。
固定:β=0.3, σ_e=0.02, N=200, seeds=20, gen=1000, 静止warmup=200, 跟踪warmup=200。
扫描:σ_v ∈ {0.005, 0.010, 0.020, 0.050, 0.100, 0.200} × peak_v ∈ {0, 0.001, 0.002, 0.003, 0.005, 0.010},36格点。测平均fitness(跟踪稳态后取均值)。
四、fitness(σ_v)曲线按峰速分组
| σ_v\v | 0.0000 | 0.0010 | 0.0020 | 0.0030 | 0.0050 | 0.0100 |
|---|---|---|---|---|---|---|
| 0.005 | 0.2423 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 |
| 0.010 | 0.8861 | 0.0253 | 0.0000 | 0.0000 | 0.0000 | 0.0000 |
| 0.020 | 0.9566 | 0.6998 | 0.2773 | 0.0588 | 0.0004 | 0.0000 |
| 0.050 | 0.8707 | 0.8621 | 0.8369 | 0.7958 | 0.6778 | 0.3191 |
| 0.100 | 0.6898 | 0.6892 | 0.6872 | 0.6836 | 0.6722 | 0.6215 |
| 0.200 | 0.4408 | 0.4406 | 0.4405 | 0.4402 | 0.4390 | 0.4336 |
v=0列(静止峰): fitness在σ_v=0.020处达峰(0.957),两侧下降。低σ_v端(0.005)fitness=0.24------遗传方差太小,h²低→跟踪速率βh²K极小(τ≈1/(βh²K)≈1266代)→测量窗400代内仍在爬升途中。根因是初始条件暂态 :种群从μ₀=0.5出发、峰在0.8,弛豫未完成。高σ_v端(0.200)fitness=0.44------散布太大。静止环境下也有最优,但这是初始条件暂态(与N几乎无关,代数主导),不是环境驱动的。
v=0.001列(慢速峰): fitness在σ_v=0.050处达峰(0.862)。σ_v=0.020时fitness=0.70------lag=0.083带来fitness损失。σ_v=0.050时h²更高→跟踪更快→lag更小→fitness更高。
v=0.010列(快速峰): fitness在σ_v=0.100处达峰(0.621)。σ_v=0.050时fitness=0.32------峰太快,0.050的跟踪速率不够。σ_v=0.100时h²=0.96→跟踪速率最高→lag最小。
起点对照实验------证实初始条件暂态
把初始均值从μ₀=0.5(默认)挪到峰上μ₀=0.8,若低σ_v端fitness回升→证实根因是初始条件暂态而非N相关漂变:
| σ_v | μ₀=0.5(默认) | μ₀=0.8(峰上) | 差异 |
|---|---|---|---|
| 0.005 | 0.2334 | 0.9779 | +0.7445 |
| 0.010 | 0.8677 | 0.9724 | +0.1047 |
| 0.020 | 0.9564 | 0.9566 | +0.0002 |
| 0.050 | 0.8709 | 0.8706 | −0.0003 |
σ_v=0.005的0.24,只要把起点挪到峰上,立刻变成0.98。σ_v≥0.020两行起点无关(τ足够短,早收敛)。
代数扫描------与N无关,代数主导
固定σ_v=0.005、v=0,扫总代数×N。解析收敛值ω/√(ω²+σ_x²)=0.9793。
| 总代数 | N=200 | N=1000 | N=5000 |
|---|---|---|---|
| 1000 | 0.2334 | 0.2474 | 0.2443 |
| 2000 | 0.4972 | 0.5007 | 0.4945 |
| 4000 | 0.7367 | 0.7377 | 0.7361 |
| 8000 | 0.8628 | 0.8634 | 0.8633 |
N三档几乎完全重合;代数从1000到8000,fitness从0.23爬到0.86,趋向解析收敛值0.979(τ≈1266代,8000代≈6.3τ时仍有残余暂态)。
五、最优σ_v* vs 峰速------bet-hedging
| peak_v | 最优σ_v* | 最优fitness |
|---|---|---|
| 0.0000 | 0.020 | 0.9566 |
| 0.0010 | 0.050 | 0.8621 |
| 0.0020 | 0.050 | 0.8369 |
| 0.0030 | 0.050 | 0.7958 |
| 0.0050 | 0.050 | 0.6778 |
| 0.0100 | 0.100 | 0.6215 |
最优σ_v*随峰速增大而增大:
- v=0 → σ_v*=0.020(初始条件暂态vs散布)
- v=0.001~0.005 → σ_v*=0.050(跟踪+暂态vs散布)
- v=0.010 → σ_v*=0.100(快速峰需要更多方差来跟踪)
这就是bet-hedging:环境变化率与变异率必须匹配。 峰慢时少量变异够用,峰快时需要更多变异来维持跟踪能力。
六、结论与主线意义
| 问题 | 答案 |
|---|---|
| 动态环境下最优变异率存在吗? | 存在 ✅。fitness对σ_v有内部峰值,双向作用(跟踪vs散布) |
| 183-1"没有最优"还成立吗? | 静止+无限代数成立;静止+有限代数有最优(初始条件暂态vs散布);动态有最优(跟踪vs散布) |
| 最优σ_v*怎么随峰速变? | v越大σ_v*越大(bet-hedging):0.050→0.100 |
| 对主线有什么用? | 176变异池的"变异幅度该调多大"------第一次有环境侧的理论参照 |
叙事弧:
- 183-1:静止环境无最优变异率
- 187-1:峰开始移动,lag load定量
- 187-2:动态环境最优变异率存在,σ_v*随峰速增大------bet-hedging
- 弧签名动作:183静止环境无最优 → 187动态环境最优存在。
- 主线意义:176变异池的"变异幅度该调多大" → 第一次有环境侧的理论参照。
降调:
-
v=0行的最优是初始条件暂态效应。 低σ_v下h²低→跟踪速率βh²K极小(τ≈1/(βh²K)≈1266代)→测量窗400代内种群仍在从μ₀=0.5向峰0.8爬升途中,未达稳态。起点对照实验 :把μ₀挪到峰上0.8,σ_v=0.005的fitness从0.23立刻跳到0.98------证实根因是初始条件暂态。代数扫描:N三档(200/1000/5000)几乎完全重合(与N无关),代数从1000到8000fitness从0.23爬到0.86,趋向解析收敛值ω/√(ω²+σ_e²+Var(g)*)=0.979。无限代数下lag=0、fitness随σ_v单调降,无最优。这不是环境驱动的,是初始条件暂态。
-
σ_v网格不够密。 最优σ_v*在0.050和0.100之间跳变(v=0.005→0.050,v=0.010→0.100),中间可能有过渡。加密σ_v网格(如0.060/0.070/0.080)能精确化边界。
-
模型与183不同。 183用固定TARGET,187回归到μ。v=0行不是严格复现183-1,而是新模型下的静止基准。模型变化在187-1已说明:环境动了,种群的"家"也跟着动。
-
bet-hedging是定性结论。 "v越大σ_v*越大"的方向确立了,但σ_v*对v的定量关系(线性?幂律?)需要更多数据点。
-
单位点模型。 多位点、上位效应、连锁不平衡待后续。
系列还在逐步建设中,完善是和伙伴们的努力方向。
附录:完整代码
python
# -*- coding: utf-8 -*-
"""
天赐范式 第187天 第二篇
让变异开始定价------动态环境下最优变异率
PID: TC-187B-V3.3.25.0
V3.3.25.0 · 2026-10-06
接续187-1:峰移动后,变异率σ_v有了双向作用------
σ_v太小→遗传方差不够→h²低→跟踪速率βh²K低→lag大→fitness损失
σ_v太大→Var(g)大→个体散布大→瞬时fitness掉
预测:动态环境下平均fitness对σ_v出现峰值(最优变异率σ_v*)
静止峰下无最优(复现183-1结论)
峰速越快,最优σ_v*越大
模型(与187-1一致):g'=μ+β(g_sel-μ)+v_mut(回归到种群均值μ)
fitness峰移动:x*(t)=X_STAR_0+peak_v·gen
扫描:σ_v × peak_v 双网格
对照:起点在峰上(μ₀=0.8) vs 默认(μ₀=0.5) + 代数扫描验证初始条件暂态
"""
import sys
import math
import numpy as np
if hasattr(sys.stdout, "reconfigure"):
sys.stdout.reconfigure(encoding="utf-8")
PID = "TC-187B-V3.3.25.0"
TARGET = 0.5
X_STAR_0 = 0.8
FITNESS_WIDTH = 0.10
BETA = 0.3
SIGMA_E = 0.02
N_POP = 200
N_GENERATIONS = 1000
WARMUP_STATIC = 200
WARMUP_TRACK = 200
N_SEEDS = 20
SIGMA_V_GRID = [0.005, 0.010, 0.020, 0.050, 0.100, 0.200]
PEAK_VELOCITIES = [0.0, 0.001, 0.002, 0.003, 0.005, 0.010]
def bar(title):
print("=" * 72)
print(" " + title)
print("=" * 72)
print()
def sub(title):
print("【" + title)
print("-" * 72)
def fitness(x, x_star):
return np.exp(-(x - x_star) ** 2 / (2 * FITNESS_WIDTH ** 2))
def solve_self_consistent(sigma_v):
var_g = sigma_v ** 2 / (1 - BETA ** 2)
for it in range(5000):
sigma_x2 = var_g + SIGMA_E ** 2
h2 = var_g / sigma_x2
v_x_sel = sigma_x2 * FITNESS_WIDTH ** 2 / (sigma_x2 + FITNESS_WIDTH ** 2)
var_g_sel = h2 ** 4 * v_x_sel + var_g * (1 - h2 ** 2)
var_g_new = BETA ** 2 * var_g_sel + sigma_v ** 2
if abs(var_g_new - var_g) < 1e-12:
return var_g_new
var_g = var_g_new
return var_g
def run_one(sigma_v, peak_v, seed, start_mu=None, n_gen=None, n_pop=None):
if start_mu is None:
start_mu = TARGET
if n_gen is None:
n_gen = N_GENERATIONS
if n_pop is None:
n_pop = N_POP
rng = np.random.RandomState(seed)
genes = rng.normal(start_mu, 0.01, n_pop)
fitnesses = []
for gen in range(n_gen):
if gen < WARMUP_STATIC:
x_star = X_STAR_0
else:
x_star = X_STAR_0 + peak_v * (gen - WARMUP_STATIC)
phenos = genes + rng.normal(0, SIGMA_E, n_pop)
fits = fitness(phenos, x_star)
fit_sum = float(fits.sum())
if fit_sum < 1e-10:
for g2 in range(gen, n_gen):
if g2 >= WARMUP_STATIC + WARMUP_TRACK:
fitnesses.append(0.0)
break
probs = fits / fit_sum
sel_idx = rng.choice(n_pop, size=n_pop, p=probs)
parent_genes = genes[sel_idx]
mu = float(np.mean(genes))
genes = mu + BETA * (parent_genes - mu) + rng.normal(0, sigma_v, n_pop)
if gen >= WARMUP_STATIC + WARMUP_TRACK:
fitnesses.append(float(np.mean(fits)))
return float(np.mean(fitnesses)) if fitnesses else 0.0
def main():
bar(f"{PID} 让变异开始定价------动态环境下最优变异率")
print(f"模型: g'=μ+β(g_sel-μ)+v_mut(回归到种群均值μ)")
print(f"选择机制: 高斯加权(按fitness加权抽样,非截尾)")
print(f"fitness峰: x*(t)=X_STAR_0+peak_v·gen")
print(f"参数: β={BETA}, σ_e={SIGMA_E}, N={N_POP}, seeds={N_SEEDS}")
print(f"扫描: σ_v×peak_v双网格,测平均fitness(跟踪稳态后取均值)")
print(f"预测: 静止峰(v=0)无最优σ_v;动峰(v>0)出现最优σ_v*;v越大σ_v*越大")
print()
sub("σ_v × peak_v 双网格:平均fitness")
header = f"{'σ_v\v':>8s}" + "".join(f"{v:>10.4f}" for v in PEAK_VELOCITIES)
print(header)
print("-" * len(header))
grid = np.zeros((len(SIGMA_V_GRID), len(PEAK_VELOCITIES)))
for i, sigma_v in enumerate(SIGMA_V_GRID):
row = []
for j, peak_v in enumerate(PEAK_VELOCITIES):
fits = []
for seed in range(N_SEEDS):
fits.append(run_one(sigma_v, peak_v, seed))
mean_fit = float(np.mean(fits))
grid[i, j] = mean_fit
row.append(mean_fit)
row_str = "".join(f"{f:>10.4f}" for f in row)
print(f"{sigma_v:>8.3f}{row_str}")
print()
sub("各峰速下最优σ_v")
print(f"{'peak_v':>8s} {'最优σ_v':>10s} {'最优fitness':>12s}")
print("-" * 72)
for j, peak_v in enumerate(PEAK_VELOCITIES):
col = grid[:, j]
best_idx = int(np.argmax(col))
best_sv = SIGMA_V_GRID[best_idx]
best_fit = col[best_idx]
print(f"{peak_v:>8.4f} {best_sv:>10.3f} {best_fit:>12.6f}")
print()
sub("对照实验:起点在峰上 vs 默认起点(v=0静止峰)")
print(f"低σ_v端fitness低,根因是初始条件暂态(μ₀=0.5→峰0.8的弛豫)")
print(f"把起点挪到峰上(μ₀=0.8),若fitness回升→证实初始条件暂态")
print()
print(f"{'σ_v':>8s} {'μ₀=0.5(默认)':>14s} {'μ₀=0.8(峰上)':>14s} {'差异':>10s}")
print("-" * 72)
for sv in [0.005, 0.010, 0.020, 0.050]:
f_default = np.mean([run_one(sv, 0.0, s, start_mu=0.5) for s in range(3)])
f_peak = np.mean([run_one(sv, 0.0, s, start_mu=0.8) for s in range(3)])
print(f"{sv:>8.3f} {f_default:>14.4f} {f_peak:>14.4f} {f_peak - f_default:>10.4f}")
print()
sub("代数扫描:σ_v=0.005, v=0(验证初始条件暂态 vs N依赖)")
var_g_star = solve_self_consistent(0.005)
sigma_x2 = var_g_star + SIGMA_E ** 2
fit_analytic = FITNESS_WIDTH / math.sqrt(FITNESS_WIDTH ** 2 + sigma_x2)
print(f"解析收敛值 ω/√(ω²+σ_x²) = {fit_analytic:.4f}")
print()
print(f"{'总代数':>8s} {'N=200':>10s} {'N=1000':>10s} {'N=5000':>10s}")
print("-" * 72)
for n_gen in [1000, 2000, 4000, 8000]:
row = []
for n_pop in [200, 1000, 5000]:
f = np.mean([run_one(0.005, 0.0, s, n_gen=n_gen, n_pop=n_pop) for s in range(3)])
row.append(f)
print(f"{n_gen:>8d} {row[0]:>10.4f} {row[1]:>10.4f} {row[2]:>10.4f}")
print()
sub("结论")
print(f"183-1:静止环境加性模型无最优变异率(σ_v越大选择越强,倒U不出现)")
v0_col = grid[:, 0]
v0_best = int(np.argmax(v0_col))
if v0_best == 0:
print(f" v=0行复现:fitness随σ_v单调降,最优在σ_v→0,无内部峰值 ✅")
else:
print(f" v=0行:最优σ_v={SIGMA_V_GRID[v0_best]:.3f}(初始条件暂态效应,非稳态)")
has_peak = any(0 < int(np.argmax(grid[:, j])) < len(SIGMA_V_GRID) - 1
for j in range(1, len(PEAK_VELOCITIES)))
if has_peak:
print(f"187-2:动态环境出现最优变异率σ_v* ✅")
for j in range(1, len(PEAK_VELOCITIES)):
peak_v = PEAK_VELOCITIES[j]
best_idx = int(np.argmax(grid[:, j]))
best_sv = SIGMA_V_GRID[best_idx]
print(f" peak_v={peak_v:.4f} → 最优σ_v*={best_sv:.3f}")
else:
print(f"187-2:动态环境未出现明显峰值(可能网格不够密或参数区不对)")
print()
print(f" 弧签名动作:183静止环境无最优 → 187动态环境最优存在")
print(f" 主线意义:176变异池的'变异幅度该调多大'------第一次有环境侧的理论参照")
if __name__ == "__main__":
main()

天赐范式 V3.3.25.0 · 2026-10-06