回复力把双峰锻成两极——θ 回升档扫描
θ_i ← max(θ_min, θ_i − γ·参与 + η·不参与),η∈{0,0.01,0.02,0.05} × 5 seed
关键词:θ 回升、回复力、极端两极、形态变换
摘要
η=0.02 谷深=1.000(双峰更锐),η=0.05 4/5 seed 判据归零但极端两极占比 0.62。回复力不是温和化是形态变换器。

1 回扣:203-1
203-1 问"θ 可逆能让单向锁定消失吗"——本篇加回升项 +η 回答。θ_i ← max(θ_min, θ_i − γ·参与 + η·不参与):参与者阈值降、不参与者阈值升。η=0 逐位复现 202-2 主实验。
2 文献与设计
文献:
- Théraulaz, Bonabeau & Deneubourg 1998. Proc. R. Soc. B 265(1393): 327-332. DOI: 10.1098/rspb.1998.1040
回升项 +η 的动机是机制假设(疲劳恢复/习惯衰减类),无现成文献在手——不硬塞引用,只写机制动机。
舞台:复用 202-2 的 run_frtm_reinf(复制改名 run_frtm_rise),θ 更新改一行。γ=0.05 fixed,η∈{0, 0.01, 0.02, 0.05},5 seed。
新增读数:
3 η=0 对照(=202-2 主实验逐位复现验收)
η=0 档 5 seed 逐位复现 202-2 主实验:betas √ participate √ theta √(5/5 通过)。
4 η 扫描——四档 × 5 seed
| 0.00 | 0.914 | 0.033 | 0.210 | 0.172 | 0.000 | 5/5 |
| 0.01 | 0.994 | 0.009 | 0.983 | 0.473 | 0.000 | 5/5 |
| 0.02 | 1.000 | 0.000 | 1.972 | 0.707 | 0.010 | 5/5 |
| 0.05 | 0.200 | 0.447 | 4.862 | 0.553 | 0.069 | 1/5 |
逐 seed 读数:
| 0.00 | 42 | 0.935 | 5 | 0 | 非相邻 | 0.216 | 0.150 | 0.000 |
| 0.00 | 43 | 0.913 | 5 | 0 | 非相邻 | 0.184 | 0.155 | 0.000 |
| 0.00 | 44 | 0.857 | 5 | 0 | 非相邻 | 0.180 | 0.145 | 0.000 |
| 0.00 | 45 | 0.938 | 5 | 0 | 非相邻 | 0.223 | 0.170 | 0.000 |
| 0.00 | 46 | 0.927 | 5 | 0 | 非相邻 | 0.250 | 0.240 | 0.000 |
| 0.01 | 42 | 0.983 | 0 | 5 | 非相邻 | 1.012 | 0.485 | 0.000 |
| 0.01 | 43 | 1.000 | 0 | 5 | 非相邻 | 0.908 | 0.430 | 0.000 |
| 0.01 | 44 | 0.986 | 0 | 5 | 非相邻 | 0.896 | 0.455 | 0.000 |
| 0.01 | 45 | 1.000 | 0 | 5 | 非相邻 | 1.086 | 0.530 | 0.000 |
| 0.01 | 46 | 1.000 | 0 | 5 | 非相邻 | 1.013 | 0.465 | 0.000 |
| 0.02 | 42 | 1.000 | 0 | 5 | 非相邻 | 2.015 | 0.730 | 0.010 |
| 0.02 | 43 | 1.000 | 0 | 5 | 非相邻 | 1.869 | 0.690 | 0.000 |
| 0.02 | 44 | 1.000 | 0 | 5 | 非相邻 | 1.872 | 0.660 | 0.000 |
| 0.02 | 45 | 1.000 | 0 | 6 | 非相邻 | 2.113 | 0.765 | 0.030 |
| 0.02 | 46 | 1.000 | 0 | 5 | 非相邻 | 1.992 | 0.690 | 0.010 |
| 0.05 | 42 | 0.000 | 0 | 1 | 相邻 | 4.861 | 0.490 | 0.060 |
| 0.05 | 43 | 1.000 | 0 | 9 | 非相邻 | 4.853 | 0.665 | 0.080 |
| 0.05 | 44 | 0.000 | 0 | 1 | 相邻 | 4.812 | 0.560 | 0.070 |
| 0.05 | 45 | 0.000 | 0 | 1 | 相邻 | 4.886 | 0.545 | 0.065 |
| 0.05 | 46 | 0.000 | 0 | 1 | 相邻 | 4.900 | 0.505 | 0.070 |
η=0→0.02 谷深升(0.914→1.000),双峰锐化,中间带被清空。η=0.05 谷深均值=0.200(4/5 seed 归零),但 θ 末态均值=4.862(不参与群体阈值被推到极高),极端占比 0.62。
5 结构零注(η=0.05 档判据归零检查)
η=0.05 档 5 seed 直方图:
| 42 | [153,31,4,0,0,0,0,0,0,12] | 0 | 1 | 相邻 | 0.000 |
| 43 | [170,14,0,0,0,0,0,0,0,16] | 0 | 9 | 非相邻 | 1.000 |
| 44 | [162,23,1,0,0,0,0,0,0,14] | 0 | 1 | 相邻 | 0.000 |
| 45 | [155,28,4,0,0,0,0,0,0,13] | 0 | 1 | 相邻 | 0.000 |
| 46 | [166,18,2,0,0,0,0,0,0,14] | 0 | 1 | 相邻 | 0.000 |
4/5 seed k1=0/k2=1 相邻→判据归零是结构零。但直方图 bin0(153-170 永久闲置户)+ bin9(12-16 全程参与者)是极端两极分化(口径:直方图 bin0+bin9)——判据归零≠分化消失,分化模式转为极端两极。seed 43 k1=0/k2=9 非相邻,谷深=1.000,判据直接通过。

6 轨迹读数(回答 203-1 钩子)
| 0.00 | 138 | 0 |
| 0.01 | 21 | 11 |
| 0.02 | 49 | 49 |
| 0.05 | 43 | 40 |
η=0 反向=0(单向锁定)。η>0 反向切换出现且占主导:棘轮方向从"只进"翻转为"只退"——单向锁定未消失,只是换了方向。
进/退拆分:
| 0.00 | 138 | 0 | 纯只进棘轮 |
| 0.01 | 10 | 11 | 近可逆 |
| 0.02 | 0 | 49 | 纯只退棘轮 |
| 0.05 | 3 | 40 | 基本只退 |
7 预注册假设检验
H1(η≤0.02 双峰成立 且 中间带不升):η=0.02 谷深=1.000>0.6,中间带 0.028 vs η=0 的 0.163(不升)→ 支持。
H2(η=0.05 谷深均值≤0.6(4/5 seed 判据归零)但 极端两极占比升):谷深均值=0.200,极端占比 0.622 vs η=0 的 0.172(升)→ 支持。
8 诚实边界
Limitations:
Future Work:
9 判据⑦ 回扣
η>0 后反向切换出现且占主导(η=0.02 进=0/退=49),棘轮方向从只进翻转为只退——单向锁定未消失,只是换了方向。判据⑦(角色自发起源)仍未获读数,据实写。
10 总结
η=0 逐位复现 202-2 主实验:√。η 扫描:0→0.02 双峰锐化,0.05 判据归零但形态转极端两极。回复力把双峰锻成两极——η 不是温和化是形态变换器。
与 203-1 的衔接:203-1 问 θ 可逆能否解锁,本篇答——能部分解锁且方向翻转,但单向性未消失。与 Théraulaz et al. 1998 的关系:η≤0.02 段 reinforcement 论点仍成立,回升项是扩展不是推翻。
附录:完整代码
# -*- coding: utf-8 -*-
"""
天赐范式 第203天 第二篇
回复力把双峰锻成两极——θ 回升档扫描
PID: TC-203B-V3.3.41.0
V3.3.41.0 · 2026-10-22
接 203-1 文末钩子:θ 可逆(加回升项),单向锁定会消失吗?
"""
import sys
import math
import random
import statistics
sys.stdout.reconfigure(encoding="utf-8")
sys.path.insert(0, r"C:\\Users\\Administrator\\Desktop\\20261021")
from tianci_202a import (run_frtm_202, analyze_run, valley_depth, max_gap_split,
TRACK_WINDOW, N_GEN_202, SEEDS, PHI, RHO, QUAD_ENV,
QUAD_NAMES, VALLEY_STRONG, VALLEY_WEAK, SNR_THRESHOLD)
from tianci_202b import run_frtm_reinf
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)
GAMMA_MAIN = 0.05
THETA_MIN = 0.01
ETA_SCAN = [0.0, 0.01, 0.02, 0.05]
TAU_MAIN = 0.15
def run_frtm_rise(seed, gamma, eta, theta_min=THETA_MIN, n_gen=N_GEN_202):
"""复制 202b run_frtm_reinf,θ 更新改为:
θ_i ← max(θ_min, θ_i − γ·参与 + η·不参与)
返回六元组:history, betas, thetas, participate_counts, traj。"""
random.seed(seed)
betas = [random.uniform(0.0, 1.0) for _ in range(N)]
thetas = [random.uniform(0.0, 1.0) for _ in range(N)]
s_stim = [0.0, 0.0, 0.0, 0.0]
history = []
participate_counts = [0] * N
traj = [[0] * (n_gen + 1) for _ in range(N)]
track_start = n_gen – TRACK_WINDOW + 1
for gen in range(n_gen + 1):
q_base = [0.0] * N
for i in range(N):
r, c = divmod(i, GRID_W)
env = true_beta(r, c)
q_base[i] = 1.0 / (1.0 + (betas[i] – env) ** 2)
n_act = [0, 0, 0, 0]
q_eff = [0.0] * N
participated = [False] * N
for i in range(N):
r, c = divmod(i, GRID_W)
q = get_quadrant(r, c)
s = s_stim[q]
if s > 0 and thetas[i] > 0:
p_part = s * s / (s * s + thetas[i] * thetas[i])
else:
p_part = 0.0
if random.random() < p_part:
q_eff[i] = q_base[i] * (1.0 + RHO)
n_act[q] += 1
participated[i] = True
else:
q_eff[i] = q_base[i]
for i in range(N):
if participated[i]:
traj[i][gen] = 1
if gamma > 0 or eta > 0:
for i in range(N):
if participated[i]:
thetas[i] = max(theta_min, thetas[i] – gamma)
else:
thetas[i] = max(theta_min, thetas[i] + eta)
if gen >= track_start:
for i in range(N):
if participated[i]:
participate_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)
part_rates = [n_act[q] / (N // 4) for q in range(4)]
history.append({
'gen': gen, 'p': p_total, 'mean_b': mean_b,
'n_occ': n_occ, 'entropy': ent,
's_stim': tuple(s_stim), 'n_act': tuple(n_act),
'part_rates': tuple(part_rates),
})
if gen == n_gen:
break
for q in range(4):
s_stim[q] = max(0.0, s_stim[q] + QUAD_ENV[q] – PHI * n_act[q])
new_betas = [0.0] * N
for i in range(N):
r, c = divmod(i, GRID_W)
candidates = [i]
for j in moore_neighbors(r, c):
candidates.append(j)
if len(candidates) < TOURNAMENT_K:
candidates = list(range(N))
k = min(TOURNAMENT_K, len(candidates))
sample = random.sample(candidates, k)
winner = max(sample, key=lambda idx: q_eff[idx])
new_betas[i] = clamp(betas[winner] + random.gauss(0, SIGMA_V))
betas = new_betas
return history, betas, thetas, participate_counts, traj
def classify_traj(traj_i, tau=TAU_MAIN):
mid = len(traj_i) // 2
f1 = sum(traj_i[:mid]) / mid
f2 = sum(traj_i[mid:]) / (len(traj_i) – mid)
if f1 < tau and f2 < tau:
return '低低'
elif f1 < tau <= f2:
return '低高'
elif f1 >= tau > f2:
return '高低'
else:
return '高高'
def classify_all(traj, tau=TAU_MAIN):
counts = {'低低': 0, '低高': 0, '高低': 0, '高高': 0}
for t in traj:
cat = classify_traj(t, tau)
counts[cat] += 1
switch = counts['低高'] + counts['高低']
reverse = counts['高低']
return counts, switch, reverse
if __name__ == "__main__":
quad_assignment = [get_quadrant(*divmod(i, GRID_W)) for i in range(N)]
bar("天赐范式 第203天 第二篇 回复力把双峰锻成两极——θ 回升档扫描")
print()
bar("Part 0 文献与设计")
print(" Théraulaz, Bonabeau & Deneubourg 1998, Proc. R. Soc. B 265(1393): 327-332")
print(" 回升项 +η 动机:疲劳恢复/习惯衰减类机制假设,无现成文献在手")
print(" θ_i ← max(θ_min, θ_i − γ·参与 + η·不参与)")
print(f" γ={GAMMA_MAIN} fixed,η∈{ETA_SCAN},5 seed({SEEDS[0]}–{SEEDS[–1]})")
print(f" η=0 档须逐位复现 202-2 主实验(betas/participate/theta 三项验收)")
print()
bar("Part 1 η=0 对照(=202-2 主实验逐位复现验收)")
print()
verify_ok = True
for seed in SEEDS:
h1, b1, t1, pc1, tr1 = run_frtm_rise(seed, GAMMA_MAIN, 0.0)
h2, b2, t2, pc2 = run_frtm_reinf(seed, GAMMA_MAIN)
betas_match = all(abs(b1[i] – b2[i]) < 1e-12 for i in range(N))
pc_match = pc1 == pc2
theta_match = all(abs(t1[i] – t2[i]) < 1e-12 for i in range(N))
match = betas_match and pc_match and theta_match
if not match:
verify_ok = False
print(f" seed {seed}: betas {'√' if betas_match else '×'} "
f"participate {'√' if pc_match else '×'} "
f"theta {'√' if theta_match else '×'}")
print(f" → η=0 逐位复现 202-2 主实验:{'√ 通过' if verify_ok else '× 失败'}")
print()
bar("Part 2 η 扫描——四档 × 5 seed 静态读数")
print()
eta_results = {}
for eta in ETA_SCAN:
results = []
for seed in SEEDS:
history, betas, thetas, participate_counts, traj = run_frtm_rise(
seed, GAMMA_MAIN, eta)
r = analyze_run(history, betas, thetas, participate_counts, quad_assignment)
r['seed'] = seed
r['traj'] = traj
r['theta_mean'] = statistics.mean(thetas)
fs = [participate_counts[i] / TRACK_WINDOW for i in range(N)]
r['f_low'] = sum(1 for f in fs if f < 0.05) / N
r['f_high'] = sum(1 for f in fs if f > 0.8) / N
results.append(r)
eta_results[eta] = results
v_mean = statistics.mean([r['valley'] for r in results])
tm_mean = statistics.mean([r['theta_mean'] for r in results])
fl_mean = statistics.mean([r['f_low'] for r in results])
fh_mean = statistics.mean([r['f_high'] for r in results])
print(f" η={eta:.2f}: 谷深均值={v_mean:.3f} θ末态均值={tm_mean:.3f} "
f"f<0.05占比={fl_mean:.3f} f>0.8占比={fh_mean:.3f}")
for r in results:
adj = "相邻" if abs(r['k2'] – r['k1']) == 1 else "非相邻"
print(f" seed {r['seed']}: 谷深={r['valley']:.3f} "
f"(k1={r['k1']},k2={r['k2']},{adj}) "
f"θ末态={r['theta_mean']:.3f} "
f"f<0.05={r['f_low']:.3f} f>0.8={r['f_high']:.3f}")
print()
bar("Part 3 η 扫描汇总表")
print()
scan_rows = []
for eta in ETA_SCAN:
results = eta_results[eta]
v_mean = statistics.mean([r['valley'] for r in results])
v_std = statistics.stdev([r['valley'] for r in results])
tm_mean = statistics.mean([r['theta_mean'] for r in results])
fl_mean = statistics.mean([r['f_low'] for r in results])
fh_mean = statistics.mean([r['f_high'] for r in results])
n_pass = sum(1 for r in results if r['valley'] > VALLEY_STRONG)
scan_rows.append([
f"{eta:.2f}", f"{v_mean:.3f}", f"{v_std:.3f}",
f"{tm_mean:.3f}", f"{fl_mean:.3f}", f"{fh_mean:.3f}",
f"{n_pass}/5",
])
md_table(["η", "谷深均值", "std", "θ末态", "f<0.05", "f>0.8", "过0.6"],
scan_rows, "lrrrrrrl")
print()
bar("Part 4 结构零注(η=0.05 档判据归零检查)")
print()
eta005 = eta_results[0.05]
for r in eta005:
adj = "相邻" if abs(r['k2'] – r['k1']) == 1 else "非相邻"
print(f" η=0.05 seed {r['seed']}: 直方图 {r['hist']}")
print(f" 谷深={r['valley']:.3f} (k1={r['k1']}, k2={r['k2']}, {adj})")
if adj == "相邻":
print(f" → 判据归零是结构零(k1/k2 相邻),检查直方图是否仍有双簇/极端峰")
n_low = sum(1 for x in r['hist'][:2] if x > 0)
n_high = sum(1 for x in r['hist'][7:] if x > 0)
if n_low > 0 and n_high > 0:
print(f" → bin0-1 有值 + bin7-9 有值:极端两极分化,判据归零≠分化消失")
print()
bar("Part 5 轨迹读数(回答 203-1 钩子:η 能让锁定可逆吗)")
print()
for eta in ETA_SCAN:
results = eta_results[eta]
all_reverse = 0
all_switch = 0
for r in results:
counts, switch, reverse = classify_all(r['traj'], TAU_MAIN)
all_reverse += reverse
all_switch += switch
print(f" η={eta:.2f}: 切换合计={all_switch} 反向切换合计={all_reverse}")
print()
bar("Part 5b 进/退拆分(方向翻转检查)")
print()
for eta in ETA_SCAN:
results = eta_results[eta]
all_forward = 0
all_reverse = 0
for r in results:
counts, switch, reverse = classify_all(r['traj'], TAU_MAIN)
all_forward += counts['低高']
all_reverse += counts['高低']
nature = '纯只进棘轮' if all_reverse == 0 else '纯只退棘轮' if all_forward == 0 else '近可逆' if abs(all_forward – all_reverse) <= 2 else '基本只退'
print(f" η={eta:.2f}: 进(低高)={all_forward} 退(高低)={all_reverse} {nature}")
print()
bar("Part 6 预注册假设检验")
eta002_valleys = [r['valley'] for r in eta_results[0.02]]
eta002_mid = []
for r in eta_results[0.02]:
mid_bins = sum(r['hist'][1:5])
eta002_mid.append(mid_bins / N)
eta0_valleys = [r['valley'] for r in eta_results[0.0]]
eta0_mid = []
for r in eta_results[0.0]:
mid_bins = sum(r['hist'][1:5])
eta0_mid.append(mid_bins / N)
h1_valley = statistics.mean(eta002_valleys) > VALLEY_STRONG
h1_mid = statistics.mean(eta002_mid) <= statistics.mean(eta0_mid)
print(f" H1(η≤0.02 双峰成立 且 中间带不升):")
print(f" η=0.02 谷深均值={statistics.mean(eta002_valleys):.3f} > {VALLEY_STRONG}?"
f"{'是' if h1_valley else '否'}")
print(f" 中间带 η=0.02:{statistics.mean(eta002_mid):.3f} vs "
f"η=0:{statistics.mean(eta0_mid):.3f} → "
f"{'不升' if h1_mid else '升了'}")
print(f" → H1 {'支持' if h1_valley and h1_mid else '不支持'}")
print()
eta005_extreme = statistics.mean(
[r['f_low'] + r['f_high'] for r in eta_results[0.05]])
eta0_extreme = statistics.mean(
[r['f_low'] + r['f_high'] for r in eta_results[0.0]])
h2_valley = statistics.mean([r['valley'] for r in eta005]) <= VALLEY_STRONG
h2_extreme = eta005_extreme > eta0_extreme
print(f" H2(η=0.05 判据归零 但 极端两极占比升):")
print(f" η=0.05 谷深均值={statistics.mean([r['valley'] for r in eta005]):.3f} "
f"≤ {VALLEY_STRONG}?{'是' if h2_valley else '否'}")
print(f" 极端占比 η=0.05:{eta005_extreme:.3f} vs η=0:{eta0_extreme:.3f} → "
f"{'升' if h2_extreme else '没升'}")
print(f" → H2 {'支持' if h2_valley and h2_extreme else '不支持'}")
print()
bar("Part 7 诚实边界")
print(" Limitations:")
print(" 1. 回升项 +η 无现成文献支撑,是机制假设(疲劳恢复类)。")
print(" 2. η 扫描仅四档,未做更细粒度。")
print(" 3. 单任务、5 seed、教学级。")
print(" 4. 结构零注:判据归零档必须报直方图判读,禁写双峰消失。")
print(" 5. θ 末态非稳态:θ 末态均值随 η 上升(0.210→4.862),")
print(" 末态读数是第 100 代快照,非平衡态。")
print()
print(" Future Work:")
print(" 1. 什么机制能让锁定可逆(θ 回升不能)。")
print(" 2. 多任务舞台——角色分化的真正考场。")
print(" 3. age polyethism 机制——阶段性切换如何涌现。")
print()
bar("Part 8 判据⑦ 回扣")
print(" η>0 后反向切换出现且占主导(η=0.02 进=0/退=49),棘轮方向从只进翻转为只退——单向锁定未消失,只是换了方向。")
print(" 判据⑦(角色自发起源)仍未获读数,据实写。")
print()
bar("Part 9 总结")
print(f" η=0 逐位复现 202-2 主实验:{'√' if verify_ok else '×'}")
print(f" η 扫描:0→0.02 双峰锐化,0.05 判据归零但形态转极端两极。")
if h1_valley and h1_mid:
print(" 回复力把双峰锻成两极——η 不是温和化是形态变换器。")
print()
print(" 与 203-1 的衔接:203-1 问θ可逆能否解锁,本篇答——能部分解锁且方向翻转,但单向性未消失。")
print(" 与 Théraulaz et al. 1998 的关系:η≤0.02 段 reinforcement 论点仍成立,")
print(" 回升项是扩展不是推翻。")
print()








