天赐范式 ·第214天 第一篇:撤掉外加 λ,存活交给个体自己累积的产出
——E_i 累积退出 × 继承 vs 不继承 × 四组 × 5 seed
摘要
211-3 缺口①:适应度→存活通道不存在。212-1 用 κ 做适应度依赖死亡(λ_i=λ0(1−κ·q_eff/q_max)),是装件(外加公式),213-1 已证明回报不由 κ 通道产生——κ 是瞬时概率调制,在 q_eff≈0.996 触顶、个体短寿的系统里被稀释。今天换成长成式:撤掉外加 λ,退出改由个体自己累积的产出 E_i=δ·E_i+q_eff 决定(末位 10% 退出)。核心对照是 E 遗不遗传。结果:5seed 下 A−B 未超噪声(t=−2.24),加压 30seed 后显著负(t=−5.27)——往对走不是"没检出回报",是"显著更差"。 不翻转 ρ(恒 +1)则 A−B 显著正(t=+7.43)——F1 方向被 ρ 翻转绑死,"演化组低于 θ 锁死组"是"参与即受罚"的结构性结果。随机退 10% 替代 E_exit 排序则 A−B 归零(t=+0.43)——差异完全来自 E_exit 排序逻辑,不是"参与/不参与"本身。继承 E vs 不继承 E 无差异(t=+0.34)。

§一 问题
211-3 留了三件兵器:统一追问(“更自己会动了还是多加功能?”)、长成原则(“材料都是上一层长出来的”)、缺口清单(①适应度→存活通道不存在 ②突变来源外加 σ_θ ③适应后果只测到单向)。
用这三件兵器量 212/213:
| 212-1 κ | 缺口① | 方向对;但 κ 是装件(外加 λ(q_eff) 公式)→ 213-1 已证明回报不由该通道产生 |
| 212-2 mutator | 缺口② | 长成✔(突变率成为可遗传性状) |
| 213-1 四把尺子 | 缺口③ | 纯测量(换尺子重测 210 的阴性)→ 零推进 |
| 213-2 β_m | 不在清单 | 装件 + 围文献(为对账 182 的 D* 而加)→ 偏离 |
今天起:不换尺子重测,不为外部公式装件。方向是撤装件、换长成。
κ 是瞬时概率调制:λ_i=λ0(1−κ·q_eff/q_max),每代重掷骰子。在 q_eff≈0.996 触顶、个体平均寿命短(λ=0.10)的系统里,"少死一点"的优势每代被稀释。今天换成累积式:E_i=δ·E_i+q_eff,退出由 E_i 排序末位决定。关键对照是 E 遗不遗传——继承档补位时 E_child=α·E_winner,不继承档 E_child=0。
§二 预注册假设
E_i 累积:E_i = δ·E_i + q_eff[i],δ=0.95 钉死不扫档(扫档=又一个外加旋钮)。
退出:每代按 E_i 排序,末位 exit_frac=10% 退出(确定性,不消耗随机数)。exit_frac=0.10 钉死,匹配 λ=0.10 的平均退出率。
E 继承:补位时 E_child = α·E_winner(继承档)或 0(不继承档),α=0.5 钉死不扫档。
四组:A(演化+继承E) / A0(演化+不继承E) / B(θ锁死+不继承E) / D(中性+继承E)。
预注册三条:
- H0(恒等):death_mode=‘lambda’ 逐位对 212a(κ=0),不一致即停。
- H1(主判据):往对走(A−B)在继承档是否检出回报 → 直接答 211-3 的下一关。
- H2:继承档 vs 不继承档之差 → 适应度→存活通道是否因此成立。
预注册结局:A→继承档检出回报且显著大于不继承档→缺口①打通;B→仍未检出→硬阴性;C→撤 λ 后种群归零→"存续仍依赖外加退出率"。
§三 恒等性自检
death_mode=‘lambda’ 与 212a(κ=0) 逐位比对(p_total / n_alive,151 代全序列,四组 × 5 seed):PASS。
lambda 模式退化为 212 基座(κ=0),E 跟踪不消耗随机数 → 必然逐位一致。
§四 主表:E_i 累积退出 × 四组 × 5 seed
| A | 演化+继承E | 0.8531±0.0471 | 0.5970±0.0125 |
| A0 | 演化+不继承E | 0.8453±0.0372 | 0.5960±0.0129 |
| B | θ锁死+不继承E | 0.9219±0.0671 | 0.6020±0.0104 |
| D | 中性+继承E | 0.8833±0.0704 | 0.6000±0.0137 |
B(θ锁死)F1 高于 A(演化)——往对走方向为负。
§五 H1:往对走(A−B)在继承档 vs 不继承档
5 seed → df=4,临界 |t|>2.776
| A−B (继承E) | −0.0688±0.0688 | −2.24 | 未超噪声 |
| A0−B (不继承E) | −0.0766±0.0934 | −1.83 | 未超噪声 |
5seed 下两档均负未超噪声。但 5seed 是教学级样本量——加压 30seed:
| A−B (继承E, 30seed) | −0.0753±0.0782 | −5.27 | 显著负 |
加压后往对走显著更差,不是"没检出回报"。差值几乎没动(−0.069→−0.075),变的只是样本量。
§五b 三把对照:F1 方向被 ρ 翻转绑死,差异来自 E_exit 排序
| 翻转(原版, 30seed) | −0.0753 | −5.27 | 显著负 |
| 不翻转(ρ 恒 +1, 30seed) | +0.2781 | +7.43 | 显著正 |
| 随机退 10%(替代 E_exit, 30seed) | +0.0068 | +0.43 | 差异归零 |
三把对照坐实两件事:
F1 方向被 ρ 翻转绑死:同一个 F1,翻转时"A 显著差"、不翻转时"A 显著好"。末代 ρ=−0.5,参与 → q_eff×0.5,参与者产出恰好是未参与者的一半。A 组(演化→θ 降→参与多)受罚多 → F1 低;B 组(θ 锁死)参与少 → F1 高。"演化组 F1 低于 θ 锁死组"是"参与即受罚"的结构性结果,不是适应度证据。
差异完全来自 E_exit 排序:把退出换成随机退 10%,A−B 归零(t=+0.43)。这 0.075 的差是 E_exit 逻辑的自造物,不是"参与/不参与"本身。
§六 H2:继承档 vs 不继承档之差
A(继承E) − A0(不继承E): +0.0078±0.0513, t=+0.34
继承 E 与不继承 E 未超噪声(|t|<2.776)。适应度→存活通道未因 E 继承而成立。
§七 存续检查
| A | 0.5970±0.0125 | 存续 |
| A0 | 0.5960±0.0129 | 存续 |
| B | 0.6020±0.0104 | 存续 |
| D | 0.6000±0.0137 | 存续 |
撤掉外加 λ 后种群不归零(存续率≈0.60)。结局不是 C。
§八 结论
四件事摆在一起:
一句话:撤掉外加 λ 换成个体自己累积的产出决定退出,种群能活,但往对走显著更差——且这个"更差"不是适应度证据,是 ρ 翻转下"参与即受罚"的结构性结果,差异完全来自 E_exit 排序逻辑。 承接 210 的机制归因:q_eff≈0.996 触顶,选择把 θ 推高 → 参与率下降 → 产出下降,演化组反而低于 θ 锁死组。
仍缺的
§九 诚实边界
Limitations
Reproducibility
脚本:tianci_214a.py(20261102 工作目录),依赖 212a / 209a / 202a / 200b 四个历史模块(路径见脚本头部)。
复跑命令:py tianci_214a.py > out_214a.txt 2>&1
环境:Windows 10, Python 3.13, py launcher
输出:out_214a.txt
结果:exit=0;death_mode=‘lambda’ 恒等性自检 PASS(与 212a(κ=0) 逐位一致);E_i 累积退出 × 四组 × 5seed + 30seed 加压 + 不翻转对照 + 随机退对照 全部完成。版本 v3.3.52.0,2026-11-02。
211-2 追问:这一步是让它更"自己会动"了,还是只多加了一个功能?答:撤掉了实验者每代掷的骰子(λ),退出标准内生化了(真推进)。但装上的是 δ=0.95、exit_frac=0.10、α=0.5 三个确定性常数,且 exit_frac 是"每代固定淘汰末位 10%"——比随机死亡更强的定向控制。退出标准内生化了,淘汰配额与累积/继承规则仍是外加常数。
附录:代码
# -*- coding: utf-8 -*-
"""
天赐范式 第214天 第一篇
撤掉外加 λ,存活交给个体自己累积的产出
PID: TC-214A-V3.3.52.0
V3.3.52.0 · 2026-11-02
接 211-3 缺口①(适应度→存活通道不存在)+ 211-3 定的下一关(往对走能否检出回报)。
212-1 用 κ 做适应度依赖死亡(λ_i = λ0(1−κ·q_eff/q_max)),是**装件**(外加公式)。
213-1 已证明回报不由 κ 通道产生——κ 是瞬时概率调制,在 q_eff≈0.996 触顶、
个体短寿的系统里被稀释。
今天换成长成式:退出不再由实验者每代掷骰子决定,而由**个体自己累积的产出**
E_i = δ·E_i + q_eff 决定。材料 100% 来自上一层(q_eff 已有、退出/补位已有),
不新增状态变量。
核心对照是 E 遗不遗传(继承档 vs 不继承档)——"活得好的谱系能不能把优势传下去"。
这是缺口①真正的问法(不是"死亡挑不挑人",是"优势能不能代际传递")。
恒等性自检:death_mode='lambda' 退化为 run_frtm_212(κ=0),逐位一致。
"""
import sys
import random
import statistics
sys.stdout.reconfigure(encoding="utf-8")
sys.path.insert(0, r"C:\\Users\\Administrator\\Desktop\\20261021")
from tianci_202a import (SEEDS, RHO, QUAD_ENV, PHI, TRACK_WINDOW)
sys.path.insert(0, r"C:\\Users\\Administrator\\Desktop\\20261019")
from tianci_200b import (GRID_W, GRID_H, N, N_GEN, SIGMA_V, TOURNAMENT_K,
N_BUCKETS, true_beta, get_quadrant, moore_neighbors,
get_bucket, shannon_entropy, clamp, bar, md_table)
sys.path.insert(0, r"C:\\Users\\Administrator\\Desktop\\20261028")
from tianci_209a import (THETA_MIN, THETA_MAX, GAMMA_MAIN, LAMBDA_MAIN,
_clamp_theta)
sys.path.insert(0, r"C:\\Users\\Administrator\\Desktop\\20261031")
from tianci_212a import (run_frtm_212, N_GEN_212, FLIP_GEN_212,
get_p_and_alive_at, get_part_rate_at)
N_GEN_214 = N_GEN_212
FLIP_GEN_214 = FLIP_GEN_212
FILL_DELAY_214 = 5
RHO_NEW_214 = –0.5
SIGMA_THETA = 0.10
LAM_BASE = 0.10
DELTA_E = 0.95
EXIT_FRAC = 0.10
ALPHA_E = 0.5
SEEDS_30 = SEEDS + [47, 53, 59, 61, 67, 71, 73, 79, 83, 89,
97, 101, 103, 107, 109, 113, 127, 131, 137, 139,
149, 151, 157, 163, 167]
GROUPS_214A = [
('A', 'normal', True, True, '演化+继承E'),
('A0', 'normal', True, False, '演化+不继承E'),
('B', 'normal', False, False, 'θ锁死+不继承E'),
('D', 'neutral', True, True, '中性+继承E'),
]
def run_frtm_214a(seed, gamma, sigma_theta, lam=0.0,
death_mode='lambda', inherit_E=True,
n_gen=N_GEN_214, flip_gen=FLIP_GEN_214, flip_mode='rho',
inherit_theta=True, sel_mode='normal', rho_new=RHO_NEW_214,
delta=DELTA_E, exit_frac=EXIT_FRAC, alpha=ALPHA_E):
"""212 基座 + E_i 累积退出。
death_mode:
'lambda' λ 常数随机死亡,随机数路径与 run_frtm_212(κ=0) 完全相同
'E_exit' 按 E_i 排序,末位 exit_frac 退出(确定性,不消耗随机数)
inherit_E: 补位时 E 是否从 winner 继承
True E[i] = alpha * E[winner]
False E[i] = 0.0
E_i = delta * E_i + q_eff[i](每代,存活个体)
返回与 run_frtm_212 相同的 12 元组。
"""
random.seed(seed)
rho_val = 1.0
betas = [random.uniform(0.0, 1.0) for _ in range(N)]
thetas_A = [random.uniform(0.0, 1.0) for _ in range(N)]
thetas_B = [random.uniform(0.0, 1.0) for _ in range(N)]
s_stim_A = [0.0, 0.0, 0.0, 0.0]
s_stim_B = [0.0, 0.0, 0.0, 0.0]
history = []
part_A_counts = [0] * N
part_B_counts = [0] * N
alive = [True] * N
death_gen = [None] * N
snaps = []
scale_traj = []
track_start = n_gen – TRACK_WINDOW + 1
cross_copy = 0
cross_fill = 0
copy_total = 0
fill_total = 0
fill_count = 0
death_z = []
q_eff_prev = [0.0] * N
E = [0.0] * N
env_A = list(QUAD_ENV)
env_B = list(QUAD_ENV)
for gen in range(n_gen + 1):
if flip_mode == 'rho' and flip_gen is not None and gen == flip_gen:
rho_val = rho_new
if death_mode == 'lambda' and lam > 0:
for i in range(N):
if alive[i] and random.random() < lam:
alive[i] = False
death_gen[i] = gen
death_z.append(0.0)
elif death_mode == 'E_exit':
live_idx = [i for i in range(N) if alive[i]]
if len(live_idx) > 1:
live_idx.sort(key=lambda idx: E[idx])
n_exit = int(len(live_idx) * exit_frac)
for idx in live_idx[:n_exit]:
alive[idx] = False
death_gen[idx] = gen
death_z.append(E[idx])
elif death_mode == 'random_exit':
live_idx = [i for i in range(N) if alive[i]]
if len(live_idx) > 1:
n_exit = int(len(live_idx) * exit_frac)
exit_set = random.sample(live_idx, n_exit)
for idx in exit_set:
alive[idx] = False
death_gen[idx] = gen
death_z.append(E[idx])
n_alive = sum(alive)
scale_traj.append(n_alive)
live_tA = [thetas_A[i] for i in range(N) if alive[i]]
live_tB = [thetas_B[i] for i in range(N) if alive[i]]
if len(live_tA) > 1:
mean_tA = statistics.mean(live_tA)
mean_tB = statistics.mean(live_tB)
snaps.append((gen, mean_tA, mean_tB,
statistics.stdev(live_tA),
statistics.stdev(live_tB)))
else:
mean_tA = live_tA[0] if live_tA else 0.0
mean_tB = live_tB[0] if live_tB else 0.0
snaps.append((gen, mean_tA, mean_tB, 0.0, 0.0))
q_base = [0.0] * N
for i in range(N):
if not alive[i]:
continue
r, c = divmod(i, GRID_W)
env = true_beta(r, c)
q_base[i] = 1.0 / (1.0 + (betas[i] – env) ** 2)
n_act_A = [0, 0, 0, 0]
n_act_B = [0, 0, 0, 0]
q_eff = [0.0] * N
participated_A = [False] * N
participated_B = [False] * N
n_part = 0
for i in range(N):
if not alive[i]:
continue
r, c = divmod(i, GRID_W)
q = get_quadrant(r, c)
sA = s_stim_A[q]
sB = s_stim_B[q]
if sel_mode == 'neutral':
thA_for_p = mean_tA
thB_for_p = mean_tB
else:
thA_for_p = thetas_A[i]
thB_for_p = thetas_B[i]
if sA > 0 and thA_for_p > 0:
pA = sA * sA / (sA * sA + thA_for_p * thA_for_p)
else:
pA = 0.0
if random.random() < pA:
participated_A[i] = True
n_act_A[q] += 1
if sB > 0 and thB_for_p > 0:
pB = sB * sB / (sB * sB + thB_for_p * thB_for_p)
else:
pB = 0.0
if random.random() < pB:
participated_B[i] = True
n_act_B[q] += 1
if participated_A[i] or participated_B[i]:
n_part += 1
q_eff[i] = q_base[i] * (1.0 + rho_val)
else:
q_eff[i] = q_base[i]
if gamma > 0:
for i in range(N):
if not alive[i]:
continue
if participated_A[i]:
thetas_A[i] = _clamp_theta(thetas_A[i] – gamma)
if participated_B[i]:
thetas_B[i] = _clamp_theta(thetas_B[i] – gamma)
for i in range(N):
if alive[i]:
E[i] = delta * E[i] + q_eff[i]
if gen >= track_start:
for i in range(N):
if participated_A[i]:
part_A_counts[i] += 1
if participated_B[i]:
part_B_counts[i] += 1
p_total = sum(q_eff)
mean_b = sum(betas) / N
bucket_c = [0] * N_BUCKETS
for b in betas:
bucket_c[get_bucket(b)] += 1
n_occ = sum(1 for cnt in bucket_c if cnt > 0)
ent = shannon_entropy(bucket_c, N)
history.append({
'gen': gen, 'p': p_total, 'mean_b': mean_b,
'n_occ': n_occ, 'entropy': ent,
's_stim_A': tuple(s_stim_A), 's_stim_B': tuple(s_stim_B),
'n_act_A': tuple(n_act_A), 'n_act_B': tuple(n_act_B),
'n_alive': n_alive, 'n_part': n_part,
})
if gen == n_gen:
qmax_cur = 0.0
for i in range(N):
if alive[i] and q_eff[i] > qmax_cur:
qmax_cur = q_eff[i]
surv_z = [q_eff[i] / qmax_cur for i in range(N) if alive[i]] \\
if qmax_cur > 0 else []
break
for q in range(4):
s_stim_A[q] = max(0.0, s_stim_A[q] + env_A[q] – PHI * n_act_A[q])
s_stim_B[q] = max(0.0, s_stim_B[q] + env_B[q] – PHI * n_act_B[q])
new_betas = [0.0] * N
new_thetas_A = [0.0] * N
new_thetas_B = [0.0] * N
for i in range(N):
if not alive[i]:
new_betas[i] = betas[i]
new_thetas_A[i] = thetas_A[i]
new_thetas_B[i] = thetas_B[i]
continue
r, c = divmod(i, GRID_W)
candidates = [i]
for j in moore_neighbors(r, c):
if alive[j]:
candidates.append(j)
k = min(TOURNAMENT_K, len(candidates))
sample = random.sample(candidates, k)
if sel_mode == 'anti':
winner = min(sample, key=lambda idx: q_eff[idx])
else:
winner = max(sample, key=lambda idx: q_eff[idx])
new_betas[i] = clamp(betas[winner] + random.gauss(0, SIGMA_V))
if inherit_theta:
new_thetas_A[i] = _clamp_theta(
thetas_A[winner] + random.gauss(0, sigma_theta))
new_thetas_B[i] = _clamp_theta(
thetas_B[winner] + random.gauss(0, sigma_theta))
else:
new_thetas_A[i] = thetas_A[i]
new_thetas_B[i] = thetas_B[i]
copy_total += 1
if winner != i:
cross_copy += 1
if death_mode == 'lambda' and lam > 0 and True:
for i in range(N):
if (not alive[i]) and death_gen[i] is not None \\
and (gen – death_gen[i]) >= FILL_DELAY_214:
r, c = divmod(i, GRID_W)
neighbors = [j for j in moore_neighbors(r, c)
if alive[j]]
if neighbors:
w = max(neighbors, key=lambda idx: q_eff[idx])
new_betas[i] = clamp(
betas[w] + random.gauss(0, SIGMA_V))
thA_mut = thetas_A[w] + random.gauss(0, sigma_theta)
thB_mut = thetas_B[w] + random.gauss(0, sigma_theta)
if inherit_theta:
new_thetas_A[i] = _clamp_theta(thA_mut)
new_thetas_B[i] = _clamp_theta(thB_mut)
else:
new_thetas_A[i] = random.uniform(0.0, 1.0)
new_thetas_B[i] = random.uniform(0.0, 1.0)
alive[i] = True
death_gen[i] = None
E[i] = alpha * E[w] if inherit_E else 0.0
fill_count += 1
fill_total += 1
cross_fill += 1
part_A_counts[i] = 0
part_B_counts[i] = 0
elif death_mode == 'E_exit':
for i in range(N):
if (not alive[i]) and death_gen[i] is not None \\
and (gen – death_gen[i]) >= FILL_DELAY_214:
r, c = divmod(i, GRID_W)
neighbors = [j for j in moore_neighbors(r, c)
if alive[j]]
if neighbors:
w = max(neighbors, key=lambda idx: q_eff[idx])
new_betas[i] = clamp(
betas[w] + random.gauss(0, SIGMA_V))
thA_mut = thetas_A[w] + random.gauss(0, sigma_theta)
thB_mut = thetas_B[w] + random.gauss(0, sigma_theta)
if inherit_theta:
new_thetas_A[i] = _clamp_theta(thA_mut)
new_thetas_B[i] = _clamp_theta(thB_mut)
else:
new_thetas_A[i] = random.uniform(0.0, 1.0)
new_thetas_B[i] = random.uniform(0.0, 1.0)
alive[i] = True
death_gen[i] = None
E[i] = alpha * E[w] if inherit_E else 0.0
fill_count += 1
fill_total += 1
cross_fill += 1
part_A_counts[i] = 0
part_B_counts[i] = 0
betas = new_betas
thetas_A = new_thetas_A
thetas_B = new_thetas_B
q_eff_prev = list(q_eff)
flow_stats = {
'cross_copy': cross_copy, 'cross_fill': cross_fill,
'copy_total': copy_total, 'fill_total': fill_total,
'flow_rate': (cross_copy + cross_fill) / (copy_total + fill_total)
if (copy_total + fill_total) > 0 else 0.0,
'copy_flow_rate': cross_copy / copy_total
if copy_total > 0 else 0.0,
}
return (history, betas, thetas_A, thetas_B, part_A_counts, part_B_counts,
alive, scale_traj, snaps, flow_stats, death_z, surv_z)
def mean_std(xs):
if len(xs) < 2:
return (xs[0] if xs else 0.0), 0.0
return statistics.mean(xs), statistics.stdev(xs)
def paired_t(a, b):
d = [x – y for x, y in zip(a, b)]
dm, dstd = mean_std(d)
dd = dm / dstd if dstd > 0 else None
t = dd * (len(d) ** 0.5) if dd is not None else None
return dm, dstd, dd, t
def f1_per_capita(history):
rec = history[–1]
return rec['p'] / rec['n_alive'] if rec['n_alive'] > 0 else 0.0
def survival_rate(history):
rec = history[–1]
return rec['n_alive'] / N
if __name__ == "__main__":
bar("天赐范式 第214天 第一篇:撤掉外加 λ,存活交给个体自己累积的产出")
# —————- Part 0 恒等性自检 —————-
bar("Part 0 恒等性自检:death_mode='lambda' 须与 212a(κ=0) 逐位一致")
ident_all = True
for gname, sel, inh, inhE, desc in GROUPS_214A:
for seed in SEEDS:
r_new = run_frtm_214a(seed, GAMMA_MAIN, SIGMA_THETA,
lam=LAM_BASE, death_mode='lambda',
inherit_theta=inh, inherit_E=inhE,
sel_mode=sel)
r_old = run_frtm_212(seed, GAMMA_MAIN, SIGMA_THETA,
lam=LAM_BASE, kappa=0.0,
n_gen=N_GEN_212, flip_gen=FLIP_GEN_212,
flip_mode='rho',
inherit_theta=inh, sel_mode=sel)
h_new = r_new[0]
h_old = r_old[0]
ok = len(h_new) == len(h_old)
if ok:
for rn, ro in zip(h_new, h_old):
if (abs(rn['p'] – ro['p']) > 1e-12 or
rn['n_alive'] != ro['n_alive'] or
rn['n_part'] != ro['n_part']):
ok = False
break
ident_all &= ok
if not ok:
print(f" {gname} seed={seed}: 不一致!禁止继续。")
sys.exit(1)
print(f" death_mode='lambda' 与 212a(κ=0) 逐位一致 = {ident_all}")
print(f" 说明:lambda 模式退化为 212 基座(κ=0),E 跟踪不消耗随机数。")
print()
# —————- Part 1 主表:E_exit × 四组 × 5 seed —————-
bar("Part 1 E_i 累积退出:四组 × 5 seed")
print(f" δ={DELTA_E}, exit_frac={EXIT_FRAC}, α={ALPHA_E}, σ_θ={SIGMA_THETA}")
print()
rows_main = []
f1_store = {}
surv_store = {}
for gname, sel, inh, inhE, desc in GROUPS_214A:
f1s, survs = [], []
for seed in SEEDS:
r = run_frtm_214a(seed, GAMMA_MAIN, SIGMA_THETA,
lam=0.0, death_mode='E_exit',
inherit_theta=inh, inherit_E=inhE,
sel_mode=sel)
f1s.append(f1_per_capita(r[0]))
survs.append(survival_rate(r[0]))
f1_store[gname] = f1s
surv_store[gname] = survs
fm, fs = mean_std(f1s)
sm, ss = mean_std(survs)
rows_main.append([gname, desc,
f"{fm:.4f}±{fs:.4f}",
f"{sm:.4f}±{ss:.4f}"])
md_table(["组", "说明", "F1 人均产出", "存续率"], rows_main, ["r"] * 4)
print()
# —————- Part 2 H1:往对走是否检出回报 —————-
bar("Part 2 H1:往对走(A−B)在继承档 vs 不继承档")
print(f" 5 seed → df=4, 临界 |t|>2.776")
print()
rows_h1 = []
for label, g1, g2 in [('A−B (继承E)', 'A', 'B'),
('A0−B (不继承E)', 'A0', 'B')]:
a = f1_store[g1]
b = f1_store[g2]
dm, ds, dd, t = paired_t(a, b)
rows_h1.append([label,
f"{dm:+.4f}±{ds:.4f}",
f"{t:+.2f}" if t is not None else "n/a",
"检出" if (t is not None and abs(t) > 2.776) else "未超噪声"])
md_table(["对照", "配对差", "t(df=4)", "判定"], rows_h1, ["r"] * 4)
print()
# —————- Part 3 H2:继承 vs 不继承之差 —————-
bar("Part 3 H2:继承档 vs 不继承档之差(适应度→存活通道是否成立)")
a_inh = f1_store['A']
a_noinh = f1_store['A0']
dm, ds, dd, t = paired_t(a_inh, a_noinh)
print(f" A(继承E) − A0(不继承E): {dm:+.4f}±{ds:.4f}, t={t:+.2f}" if t is not None else " n/a")
if t is not None and abs(t) > 2.776:
print(f" → 继承E显著{'高于' if dm > 0 else '低于'}不继承E (|t|>2.776)")
else:
print(f" → 继承E与不继承E未超噪声 (|t|<2.776)")
print()
# —————- Part 4 存续检查 —————-
bar("Part 4 存续检查:撤掉外加 λ 后种群是否归零")
rows_surv = []
for gname, sel, inh, inhE, desc in GROUPS_214A:
ss = surv_store[gname]
sm, sstd = mean_std(ss)
rows_surv.append([gname, f"{sm:.4f}±{sstd:.4f}",
"归零" if sm < 0.01 else "存续"])
md_table(["组", "末代存续率", "判定"], rows_surv, ["r"] * 3)
print()
# —————- Part 5 E_i 分布快照 —————-
bar("Part 5 E_i 分布快照(gen=50/100/150, A组继承E, seed=42)")
r_snap = run_frtm_214a(42, GAMMA_MAIN, SIGMA_THETA,
lam=0.0, death_mode='E_exit',
inherit_theta=True, inherit_E=True,
sel_mode='normal')
scale = r_snap[7]
print(f" 存活轨迹: g0={scale[0]} g25={scale[25]} g50={scale[50]} "
f"g75={scale[75]} g100={scale[100]} g125={scale[125]} g150={scale[150]}")
print()
# —————- Part 7 30seed 加压 —————-
bar("Part 7 30seed 加压:A−B(E_exit, 继承E, 翻转)")
print(f" 30 seed → df=29, 临界 |t|>2.045")
print()
f1_A_30, f1_B_30 = [], []
for seed in SEEDS_30:
rA = run_frtm_214a(seed, GAMMA_MAIN, SIGMA_THETA,
lam=0.0, death_mode='E_exit',
inherit_theta=True, inherit_E=True,
sel_mode='normal')
rB = run_frtm_214a(seed, GAMMA_MAIN, SIGMA_THETA,
lam=0.0, death_mode='E_exit',
inherit_theta=False, inherit_E=False,
sel_mode='normal')
f1_A_30.append(f1_per_capita(rA[0]))
f1_B_30.append(f1_per_capita(rB[0]))
dm, ds, dd, t = paired_t(f1_A_30, f1_B_30)
print(f" A−B: {dm:+.4f}±{ds:.4f}, t={t:+.2f} (df=29)")
print(f" 判定: {'显著负' if (t is not None and t < –2.045) else '未超噪声'}")
print()
# —————- Part 8 不翻转对照 —————-
bar("Part 8 不翻转对照:rho 恒 +1,A−B(E_exit, 继承E, 30seed)")
f1_A_nf, f1_B_nf = [], []
for seed in SEEDS_30:
rA = run_frtm_214a(seed, GAMMA_MAIN, SIGMA_THETA,
lam=0.0, death_mode='E_exit',
inherit_theta=True, inherit_E=True,
sel_mode='normal', flip_gen=None)
rB = run_frtm_214a(seed, GAMMA_MAIN, SIGMA_THETA,
lam=0.0, death_mode='E_exit',
inherit_theta=False, inherit_E=False,
sel_mode='normal', flip_gen=None)
f1_A_nf.append(f1_per_capita(rA[0]))
f1_B_nf.append(f1_per_capita(rB[0]))
dm, ds, dd, t = paired_t(f1_A_nf, f1_B_nf)
print(f" A−B (不翻转): {dm:+.4f}±{ds:.4f}, t={t:+.2f} (df=29)")
print(f" 判定: {'显著正' if (t is not None and t > 2.045) else '未超噪声'}")
print()
# —————- Part 9 随机退对照 —————-
bar("Part 9 随机退对照:random_exit 替代 E_exit,A−B(继承E, 翻转, 30seed)")
f1_A_rx, f1_B_rx = [], []
for seed in SEEDS_30:
rA = run_frtm_214a(seed, GAMMA_MAIN, SIGMA_THETA,
lam=0.0, death_mode='random_exit',
inherit_theta=True, inherit_E=True,
sel_mode='normal')
rB = run_frtm_214a(seed, GAMMA_MAIN, SIGMA_THETA,
lam=0.0, death_mode='random_exit',
inherit_theta=False, inherit_E=False,
sel_mode='normal')
f1_A_rx.append(f1_per_capita(rA[0]))
f1_B_rx.append(f1_per_capita(rB[0]))
dm, ds, dd, t = paired_t(f1_A_rx, f1_B_rx)
print(f" A−B (随机退): {dm:+.4f}±{ds:.4f}, t={t:+.2f} (df=29)")
print(f" 判定: {'显著' if (t is not None and abs(t) > 2.045) else '差异归零'}")
print()
# —————- Part 6 诚实边界 —————-
bar("Part 6 诚实边界")
print(" 1. 恒等性自检 PASS:death_mode='lambda' 与 212a(κ=0) 逐位一致。")
print(" 2. E_i = δ·E_i + q_eff,δ=0.95 钉死不扫档(扫档=又一个外加旋钮)。")
print(" 3. exit_frac=0.10 钉死,匹配 λ=0.10 的平均退出率。")
print(" 4. α=0.5 钉死不扫档(继承比例扫档=又一个外加旋钮)。")
print(" 5. E_exit 是确定性退出(末位分位),不消耗随机数;")
print(" 与 λ 随机死亡不同——这是机制差异,不是 bug。")
print(" 6. 5seed 未超噪声是样本量假象,30seed 显著负(t=−5.27)。")
print(" 7. F1 方向被 ρ 翻转绑死,不翻转时显著正——结论只在翻转下成立。")
print()
print(" 211-2 追问:这一步是让它更'自己会动'了,还是只多加了一个功能?")
print(" 答:撤掉了实验者每代掷的骰子(λ),退出标准内生化了(真推进)。")
print(" 但装上 δ=0.95、exit_frac=0.10、α=0.5 三个确定性常数,")
print(" exit_frac 是'每代固定淘汰末位 10%'——比随机死亡更强的定向控制。")
print(" 退出标准内生化了,淘汰配额与累积/继承规则仍是外加常数。")

网硕互联帮助中心





评论前必须登录!
注册