天赐范式第183天:让平衡开始定量——收缩与选择的平衡点位置公式验证

天赐范式第183天第二篇:让平衡开始定量------收缩与选择的平衡点位置公式验证

版本 V3.3.21.0 | PID: TC-183B-V3.3.21.0 | 2026-10-02

摘要

多seed CI+β扫描+非线性归因三项验证Δ*=β·h²·S/(1-β):20个seed比值mean≈1.00(σ_v≥0.005)公式无系统偏差,单seed偏高是漂变非偏差。

一、接续183-1------从单seed到多seed

183-1用单seed验证了Δ*=β·h²·S/(1-β)。中间段(σ_v=0.0050.200)比值1.021.05,公式成立。但单seed有漂变噪声------多seed下公式还成立吗?大σ_v时单seed比值偏高1.04~1.16------系统偏差还是随机漂变?

183-2做三件事:

  1. 多seed CI:20个seed报比值mean±std,确认公式非偶然
  2. β扫描:固定σ_v=0.05,扫β=0.1~0.9,确认公式跨收缩强度成立
  3. 非线性归因:线性fitness vs 高斯fitness对照,大σ_v单seed比值偏高归因fitness非线性

二、多seed CI扫描------20个seed报比值稳定性

200个个体,500代,β=0.3,σ_e=0.02,选择比例0.3,20个seed。(口径:每个seed独立算比值再取mean±std)

σ_v 比值mean 比值std +1σ下界 +1σ上界 n_valid
0.001 0.9791 0.2147 0.7644 1.1938 20
0.005 1.0062 0.0461 0.9601 1.0523 20
0.010 1.0037 0.0223 0.9815 1.0260 20
0.020 1.0051 0.0139 0.9912 1.0190 20
0.050 1.0027 0.0110 0.9917 1.0137 20
0.100 1.0008 0.0110 0.9898 1.0118 20
0.200 1.0003 0.0129 0.9874 1.0132 20
0.400 0.9999 0.0241 0.9758 1.0240 20
0.800 1.0001 0.0468 0.9533 1.0469 20
1.500 1.0051 0.0867 0.9185 1.0918 20

→ 所有σ_v(除0.001)比值mean≈1.00,公式无系统偏差------183-1单seed偏高是漂变。

  • std随σ_v增大:大σ_v单seed波动大,但多seed均值稳定在1.0
  • 小σ_v(0.001)比值波动大------Δ和理论都接近0,比值不稳定但无意义
  • σ_v=0.001的CI=0.7644,1.1938跨过1.0:因Δ和理论都接近0,比值由噪声主导,不具统计意义
  • 大σ_v单seed偏高经6seed窗口后移测试确认为漂变(见降调8)

三、β扫描------固定σ_v=0.05,扫β=0.1~0.9

固定σ_v=0.05(h²≈0.86,选择生效区),扫β验证公式跨收缩强度成立。每个β跑5个seed取均值(5个而非20个,计算成本考量:9个β点×20个seed=180次演化,5个seed=45次)。(口径:先取Δ和theory的跨seed均值,再算均值比值------与第二节不同)

β h²(力) S(差) Δ(实测) β·h²·S/(1-β) 比值
0.1 0.8608 +0.062217 +0.005977 +0.00595055 1.0045
0.2 0.8621 +0.062499 +0.013521 +0.01346936 1.0038
0.3 0.8642 +0.063006 +0.023459 +0.02333587 1.0053
0.4 0.8672 +0.063739 +0.036970 +0.03684777 1.0033
0.5 0.8711 +0.064759 +0.056603 +0.05641311 1.0034
0.6 0.8759 +0.066048 +0.087196 +0.08677796 1.0048
0.7 0.8820 +0.067805 +0.140120 +0.13953996 1.0042
0.8 0.8821 +0.062227 +0.220373 +0.21956398 1.0037
0.9 0.8780 +0.033419 +0.263919 +0.26406464 0.9994

→ 所有β下比值≈1.00,公式跨收缩强度成立。大β(≥0.7)时Δ大(收缩弱,选择位移大),但比值仍稳定。β=0.9时S从约0.064降到0.033:均值逼近fitness峰0.8,选择梯度自然减弱。

四、非线性归因------线性fitness vs 高斯fitness对照

大σ_v时单seed比值偏高:是fitness非线性导致还是模型错误?

对照实验:

  • 高斯fitness: exp(-(x-0.8)²/(2·0.1²))(非线性,183-1用的)
  • 线性fitness: x(线性,选择差直接正比于表型)
σ_v 高斯比值 线性比值 归因
0.050 1.0214 1.0214 都好(线性区)
0.200 1.0222 1.0184 都好(线性区)
0.400 1.0417 1.0184 高斯非线性致偏高
0.800 1.0821 1.0184 高斯非线性致偏高
1.500 1.1612 1.0183 高斯非线性致偏高

→ 线性fitness单seed比值稳定≈1.02:非线性弱,漂变小。高斯fitness单seed比值随σ_v增大:非线性强,放大单seed漂变。

初步归因:大σ_v单seed比值偏高是fitness非线性放大漂变,多seed均值仍≈1.0(见第二节)。单seed对照未做多seed验证。

五、降调声明

  1. 本篇是demo演示。公式从更新规则严格推导(见183-1第三节),按147-2实测定义demo是模拟不是实证。
  2. 多seed CI用±1σ(20个seed),非严格95%置信区间------seed数有限,目的是报稳定性非统计推断。
  3. β扫描固定σ_v=0.05,不同σ_v下β扫描结果可能不同------这里验证一个代表点。
  4. 线性fitness=x无上界,实际fitness应有上界------这里用作非线性归因的对照,不是实际模型。
  5. 非线性归因只做了单seed对照,多seed下结论应一致但未验证。
  6. 与183-1降调一致:fitness是设定的、无重组无交配、有限种群有漂变。
  7. 本验证本质是自洽性检查:公式Δ*=β·h²·S/(1-β)是平均更新规则的不动点,S和h²都从同一模拟测出,ratio≈1构造上注定。这不是独立预测------要让公式有预测力,需让S由适应度景观独立算出而非从模拟测。
  8. 大σ_v偏高归因经6seed窗口后移测试验证:窗口起点100/200/300/500,窗长400,跨seed均值偏差均<1 SE(0.68/0.75/0.85σ),慢暂态假说未复现,维持漂变归因。测试代码见下方附录(窗口后移三方判决测试代码)。
  9. 育种者方程Δ*=β·h²·S/(1-β)是Lush(1937)标准结果。本篇贡献是验证其在多seed下的稳定性,不是发现新公式。

六、七条前提条件------平衡位移定量验证

  • 条件1 独立性 ✅ 每个体独立变异独立被选
  • 条件2 隐私性 ✅ 纯数学验证,不涉及隐私
  • 条件3 繁衍性 🟡 种群代际循环是繁衍的简化模型,非完整繁衍验证
  • 条件4 安全性 ✅ β有界,种群有界
  • 条件5 不可篡改 --- 本demo不涉及篡改场景
  • 条件6 可继承 🟡 育种者方程可移植,非系列定义的基因跨代传递
  • 条件7 可终止 ✅ 有限代终止(数学语境映射,非体系达标)

结语

183-2接续183-1,对Δ*=β·h²·S/(1-β)做定量验证。

三项验证结果:

  1. 多seed CI:所有σ_v(σ_v≥0.005)比值mean≈1.00,公式无系统偏差
  2. β扫描:所有β下比值≈1.00,公式跨收缩强度成立
  3. 非线性归因:高斯fitness放大单seed漂变,线性fitness漂变小------非模型错误

公式Δ*=β·h²·S/(1-β)在多seed下无系统偏差,单seed偏差是漂变------如实报。

183-1给公式,183-2验公式。多seed下比值mean约1.00无系统偏差,单seed偏高是漂变------公式站住。

这个系列还在逐步建设中,完善也是咱们和伙伴们的努力方向。

代码附录

python 复制代码
# -*- coding: utf-8 -*-
"""
天赐范式第183天第二篇:让平衡开始定量 V3.3.21.0
接续183-1,对Delta*=beta*h^2*S/(1-beta)做多seed CI + beta扫描 + 非线性归因验证

模型(同183-1):
  表型 x = g + e, e ~ N(0, sigma_e^2)
  子代基因 g' = TARGET + beta*(g_sel - TARGET) + v, v ~ N(0, sigma_v^2)
  Delta* = beta * h^2 * S / (1 - beta)

三项验证:
  1. 多seed CI:20个seed报比值mean+-std,确认公式非偶然
  2. beta扫描:固定sigma_v=0.05,扫beta=0.1~0.9,确认公式跨收缩强度成立
  3. 非线性归因:线性fitness vs 高斯fitness对照,大sigma_v比值偏高归因fitness非线性
"""

import sys
import random
import math
import numpy as np

if hasattr(sys.stdout, 'reconfigure'):
    sys.stdout.reconfigure(encoding='utf-8')

PID = "TC-183B-V3.3.21.0"

TARGET = 0.5
FITNESS_PEAK = 0.8
BETA = 0.3
SIGMA_E = 0.02
N_POP = 200
N_GENERATIONS = 500
SELECT_FRAC = 0.3
N_SEEDS = 20

SIGMA_GRID = [0.001, 0.005, 0.01, 0.02, 0.05, 0.10, 0.20, 0.40, 0.80, 1.50]
BETA_GRID = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]


def bar(title):
    print("=" * 72)
    print("  " + title)
    print("=" * 72)
    print()


def sub(title):
    print("【" + title)
    print("-" * 72)


def fitness(x, mode='gauss', width=0.10):
    if mode == 'linear':
        return x
    return math.exp(-(x - FITNESS_PEAK) ** 2 / (2 * width ** 2))


def run_generation(genes, sigma_v, sigma_e, beta, rng, mode='gauss', width=0.10):
    phenos = [g + rng.gauss(0, sigma_e) for g in genes]
    n_select = max(2, int(len(genes) * SELECT_FRAC))
    fits = [fitness(x, mode=mode, width=width) for x in phenos]
    ranked = sorted(range(len(genes)), key=lambda i: fits[i], reverse=True)
    selected_idx = ranked[:n_select]

    mean_parents_x = float(np.mean(phenos))
    mean_selected_x = float(np.mean([phenos[i] for i in selected_idx]))
    S = mean_selected_x - mean_parents_x

    offspring = []
    for _ in range(len(genes)):
        parent_g = genes[rng.choice(selected_idx)]
        child_g = TARGET + beta * (parent_g - TARGET) + rng.gauss(0, sigma_v)
        offspring.append(child_g)

    mean_offspring_x = float(np.mean(offspring))
    var_g = float(np.var(genes))
    h2 = var_g / (var_g + sigma_e ** 2) if (var_g + sigma_e ** 2) > 1e-15 else 0.0

    return offspring, S, h2, mean_offspring_x, var_g


def run_evolution(sigma_v, n_pop, n_gen, beta, sigma_e, seed=42,
                  mode='gauss', width=0.10, warmup=100):
    rng = random.Random(seed)
    genes = [TARGET + rng.gauss(0, 0.1) for _ in range(n_pop)]

    Ss, h2s, means_x = [], [], []

    for gen in range(n_gen):
        genes, S, h2, mean_x, var_g = run_generation(
            genes, sigma_v, sigma_e, beta, rng, mode=mode, width=width)
        if gen >= warmup:
            Ss.append(S)
            h2s.append(h2)
            means_x.append(mean_x)

    return {
        'S_mean': float(np.mean(Ss)),
        'h2_mean': float(np.mean(h2s)),
        'mean_stable': float(np.mean(means_x)),
    }


def main():
    bar("天赐范式第183天第二篇:让平衡开始定量 V3.3.21.0")
    print("  PID: {}".format(PID))
    print()

    sub("步骤0】接续183-1------从单seed到多seed")
    print("  183-1用单seed验证了Delta* = beta * h^2 * S / (1 - beta)。")
    print("  中间段(sigma_v=0.005~0.200)比值1.02~1.05,公式成立。")
    print("  但单seed有漂变噪声------多seed下公式还成立吗?")
    print("  大sigma_v时比值偏高1.04~1.16------系统偏差还是随机漂变?")
    print()
    print("  183-2做三件事:")
    print("    (1) 多seed CI:20个seed报比值mean+-std,确认公式非偶然")
    print("    (2) beta扫描:固定sigma_v=0.05,扫beta=0.1~0.9,确认公式跨收缩强度成立")
    print("    (3) 非线性归因:线性fitness vs 高斯fitness对照,大sigma_v比值偏高归因fitness非线性")
    print()

    sub("步骤1】多seed CI扫描------20个seed报比值稳定性")
    print("  {}个个体,{}代,beta={},sigma_e={},选择比例{},{}个seed".format(
        N_POP, N_GENERATIONS, BETA, SIGMA_E, SELECT_FRAC, N_SEEDS))
    print("  (口径:每个seed独立算比值再取mean+-std)")
    print()
    print("  | sigma_v | 比值mean | 比值std  | +1σ下界 | +1σ上界 | n_valid |")
    print("  |---------|----------|----------|---------|---------|---------|")
    for sigma_v in SIGMA_GRID:
        ratios = []
        for seed in range(N_SEEDS):
            res = run_evolution(sigma_v, N_POP, N_GENERATIONS, BETA, SIGMA_E, seed=seed)
            delta = res['mean_stable'] - TARGET
            delta_theory = BETA * res['h2_mean'] * res['S_mean'] / (1 - BETA)
            if abs(delta_theory) > 1e-8:
                ratios.append(delta / delta_theory)
        if len(ratios) > 0:
            r_mean = float(np.mean(ratios))
            r_std = float(np.std(ratios))
            ci_lo = r_mean - r_std
            ci_hi = r_mean + r_std
            print("  | {:.3f}   | {:8.4f} | {:8.4f} | {:7.4f} | {:7.4f} | {:7d} |".format(
                sigma_v, r_mean, r_std, ci_lo, ci_hi, len(ratios)))
    print()
    print("  -> 所有sigma_v(除0.001)比值mean约1.00,公式无系统偏差------183-1单seed偏高是漂变")
    print("  -> std随sigma_v增大:大sigma_v单seed波动大,但多seed均值稳定在1.0")
    print("  -> 小sigma_v(0.001)比值波动大------Delta和理论都接近0,比值不稳定但无意义")
    print("  -> sigma_v=0.001的CI=[0.7644,1.1938]跨过1.0:因Delta和理论都接近0,")
    print("     比值由噪声主导,不具统计意义")
    print("  -> 大sigma_v单seed偏高经6seed窗口后移测试确认为漂变(见降调8)")
    print()

    sub("步骤2】beta扫描------固定sigma_v=0.05,扫beta=0.1~0.9")
    print("  固定sigma_v=0.05(h^2约0.86,选择生效区),扫beta验证公式跨收缩强度成立")
    print("  每个beta跑5个seed取均值(5个而非20个,计算成本考量:")
    print("     9个beta点x20个seed=180次演化,5个seed=45次)")
    print("  (口径:先取Delta和theory的跨seed均值,再算均值比值------与步骤1不同)")
    print()
    print("  | beta | h^2(力) | S(差)   | Delta(实测) | b*h2*S/(1-b) | 比值   |")
    print("  |------|---------|---------|------------|--------------|--------|")
    for beta_val in BETA_GRID:
        deltas, deltas_theory = [], []
        h2s, Ss = [], []
        for seed in range(5):
            res = run_evolution(0.05, N_POP, N_GENERATIONS, beta_val, SIGMA_E, seed=seed)
            delta = res['mean_stable'] - TARGET
            delta_theory = beta_val * res['h2_mean'] * res['S_mean'] / (1 - beta_val)
            deltas.append(delta)
            deltas_theory.append(delta_theory)
            h2s.append(res['h2_mean'])
            Ss.append(res['S_mean'])
        d_mean = float(np.mean(deltas))
        dt_mean = float(np.mean(deltas_theory))
        h2_mean = float(np.mean(h2s))
        S_mean = float(np.mean(Ss))
        ratio = d_mean / dt_mean if abs(dt_mean) > 1e-8 else 0
        print("  | {:.1f}  | {:.4f}  | {:+.6f}|  {:+.6f}  |  {:+.8f} | {:6.4f} |".format(
            beta_val, h2_mean, S_mean, d_mean, dt_mean, ratio))
    print()
    print("  -> 所有beta下比值约1.00,公式跨收缩强度成立")
    print("  -> 大beta(>=0.7)时Delta大(收缩弱,选择位移大),但比值仍稳定")
    print("  -> beta=0.9时S从约0.064降到0.033:均值逼近fitness峰0.8,选择梯度自然减弱")
    print()

    sub("步骤3】非线性归因------线性fitness vs 高斯fitness对照")
    print("  大sigma_v时比值偏高:是fitness非线性导致还是模型错误?")
    print("  对照实验:")
    print("    高斯fitness: exp(-(x-0.8)^2/(2*0.1^2))(非线性,183-1用的)")
    print("    线性fitness: x(线性,选择差直接正比于表型)")
    print("  预期:线性fitness下比值约1.0(线性回归精确),高斯下大sigma_v比值>1.0")
    print()
    print("  | sigma_v | 高斯比值 | 线性比值 | 归因               |")
    print("  |---------|----------|----------|--------------------|")
    test_sigmas = [0.05, 0.20, 0.40, 0.80, 1.50]
    for sigma_v in test_sigmas:
        res_g = run_evolution(sigma_v, N_POP, N_GENERATIONS, BETA, SIGMA_E,
                              seed=42, mode='gauss')
        res_l = run_evolution(sigma_v, N_POP, N_GENERATIONS, BETA, SIGMA_E,
                              seed=42, mode='linear')
        d_g = res_g['mean_stable'] - TARGET
        dt_g = BETA * res_g['h2_mean'] * res_g['S_mean'] / (1 - BETA)
        ratio_g = d_g / dt_g if abs(dt_g) > 1e-8 else 0
        d_l = res_l['mean_stable'] - TARGET
        dt_l = BETA * res_l['h2_mean'] * res_l['S_mean'] / (1 - BETA)
        ratio_l = d_l / dt_l if abs(dt_l) > 1e-8 else 0
        if sigma_v <= 0.20:
            attribution = "都好(线性区)"
        else:
            attribution = "高斯非线性致偏高" if ratio_g > 1.03 else "都好"
        print("  | {:.3f}   | {:8.4f} | {:8.4f} | {} |".format(
            sigma_v, ratio_g, ratio_l, attribution))
    print()
    print("  -> 线性fitness单seed比值稳定约1.02:非线性弱,漂变小")
    print("  -> 高斯fitness单seed比值随sigma_v增大:非线性强,放大单seed漂变")
    print("  -> 初步归因:大sigma_v单seed比值偏高是fitness非线性放大漂变,")
    print("     多seed均值仍约1.0(见步骤1)。单seed对照未做多seed验证。")
    print()

    sub("步骤4】降调声明")
    print("  1. 本篇是demo演示。公式从更新规则严格推导(见183-1步骤2),按147-2实测定义demo是模拟不是实证。")
    print("  2. 多seed CI用+-1sigma(20个seed),非严格95%置信区间------seed数有限,目的是报稳定性非统计推断。")
    print("  3. beta扫描固定sigma_v=0.05,不同sigma_v下beta扫描结果可能不同------这里验证一个代表点。")
    print("  4. 线性fitness=x无上界,实际fitness应有上界------这里用作非线性归因的对照,不是实际模型。")
    print("  5. 非线性归因只做了单seed对照,多seed下结论应一致但未验证。")
    print("  6. 与183-1降调一致:fitness是设定的、无重组无交配、有限种群有漂变。")
    print("  7. 本验证本质是自洽性检查:公式Delta*=beta*h^2*S/(1-beta)是平均更新规则的不动点,")
    print("     S和h^2都从同一模拟测出,ratio约1构造上注定。这不是独立预测------")
    print("     要让公式有预测力,需让S由适应度景观独立算出而非从模拟测。")
    print("  8. 大sigma_v偏高归因经6seed窗口后移测试验证:")
    print("     窗口起点100/200/300/500,窗长400,跨seed均值偏差均<1 SE")
    print("     (0.68/0.75/0.85 sigma),慢暂态假说未复现,维持漂变归因。")
    print("     测试代码见下方附录(窗口后移三方判决测试代码)。")
    print("  9. 育种者方程Delta*=beta*h^2*S/(1-beta)是Lush(1937)标准结果。")
    print("     本篇贡献是验证其在多seed下的稳定性,不是发现新公式。")
    print()

    sub("步骤5】七条前提条件------平衡位移定量验证")
    print("  条件1 独立性 ✅  每个体独立变异独立被选")
    print("  条件2 隐私性 ✅  纯数学验证,不涉及隐私")
    print("  条件3 繁衍性 🟡  种群代际循环是繁衍的简化模型,非完整繁衍验证")
    print("  条件4 安全性 ✅  beta有界,种群有界")
    print("  条件5 不可篡改 ---  本demo不涉及篡改场景")
    print("  条件6 可继承 🟡  育种者方程可移植,非系列定义的基因跨代传递")
    print("  条件7 可终止 ✅  有限代终止(数学语境映射,非体系达标)")
    print()

    bar("结语")
    print("  183-2接续183-1,对Delta* = beta * h^2 * S / (1 - beta)做定量验证。")
    print()
    print("  三项验证结果:")
    print("    (1) 多seed CI:所有sigma_v(sigma_v>=0.005)比值mean约1.00,公式无系统偏差")
    print("    (2) beta扫描:所有beta下比值约1.00,公式跨收缩强度成立")
    print("    (3) 非线性归因:高斯fitness放大单seed漂变,线性fitness漂变小------非模型错误")
    print()
    print("  公式Delta*=beta*h^2*S/(1-beta)在多seed下无系统偏差,单seed偏差是漂变------如实报。")
    print()
    print("  183-1给公式,183-2验公式。多seed下比值mean约1.00无系统偏差,单seed偏高是漂变------公式站住。")
    print()
    print("  这个系列还在逐步建设中,完善也是咱们和伙伴们的努力方向。")
    print("=" * 72)


if __name__ == "__main__":
    main()

附录:窗口后移三方判决测试

大σ_v单seed比值偏高的归因,伙伴独立验证提出"慢暂态/窗口敏感"假说。本篇对此做了三方判决测试,预登记判据先写死再跑数。

三个假说对窗口后移的预测:

假说 窗口后移时比值行为
慢暂态 单调向1收敛
Jensen/协方差系统偏差 稳定偏离1,不随窗口动
纯漂变 单seed附近随机游走,无趋势

测试设计:seed=42+seed 0--4,σ_v∈{0.40,0.80,1.50},窗口起点100/200/300/500,窗长400,总代数900。

跨6个seed均值序列(核心判决表):

σ_v w=100 w=200 w=300 w=500 偏差/SE
0.40 1.0067 1.0044 0.9993 1.0059 0.68σ
0.80 1.0146 1.0093 0.9996 1.0095 0.75σ
1.50 1.0299 1.0205 0.9986 1.0138 0.85σ

判决结果:

  • 慢暂态❌:w300→w500三个σ_v全反弹,单调收敛假说不允许反弹;6个seed只有2个呈收敛趋势,伙伴看到的是cherry-pick
  • 系统偏差❌:w300跨seed均值全回到≈1.0(0.9993/0.9996/0.9986),不是稳定偏离
  • 纯漂变✅:所有偏差<1 SE(0.68/0.75/0.85σ),统计不显著

论证顺序:偏差<1 SE是决定性证据(跨seed均值的直接统计陈述),非单调作为辅助(四个窗口共享数据段,估计值高度相关,非单调性证据强度打折)。

结论:维持漂变归因,慢暂态未复现。β=0.3时warmup=100是70+个时间常数,暂态理论上早死透。测试脚本tianci_183_window_test.py及完整输出window_test_output.txt随文留档。

窗口后移三方判决测试代码

python 复制代码
# -*- coding: utf-8 -*-
"""
天赐范式第183天:窗口后移三方判决测试
预登记判据 -> 跑数 -> 判归属

三个假说对窗口后移的预测各不相同:
  慢暂态        : 比值随窗口起点单调向1收敛
  系统偏差(Jensen): 稳定偏离1,不随窗口动
  纯漂变        : 单seed值附近随机游走,无趋势

测试设计(预登记):
  复现基点 : seed=42 + seed 0-4
  取点     : sigma_v in {0.40, 0.80, 1.50}
  窗口起点 : 100 / 200 / 300 / 500
  窗长     : 400
  总代数   : 900 (500 + 400)
"""

import sys
import random
import math
import numpy as np

if hasattr(sys.stdout, 'reconfigure'):
    sys.stdout.reconfigure(encoding='utf-8')

PID = "TC-183-WINDOW-TEST"

TARGET = 0.5
FITNESS_PEAK = 0.8
BETA = 0.3
SIGMA_E = 0.02
N_POP = 200
SELECT_FRAC = 0.3

TEST_SIGMAS = [0.40, 0.80, 1.50]
TEST_SEEDS = [42, 0, 1, 2, 3, 4]
WINDOW_STARTS = [100, 200, 300, 500]
WINDOW_LEN = 400
N_TOTAL_GEN = 900


def bar(title):
    print("=" * 78)
    print("  " + title)
    print("=" * 78)
    print()


def sub(title):
    print("【" + title)
    print("-" * 78)


def fitness(x, mode='gauss', width=0.10):
    if mode == 'linear':
        return x
    return math.exp(-(x - FITNESS_PEAK) ** 2 / (2 * width ** 2))


def run_generation_record(genes, sigma_v, sigma_e, beta, rng,
                          mode='gauss', width=0.10):
    phenos = [g + rng.gauss(0, sigma_e) for g in genes]
    n_select = max(2, int(len(genes) * SELECT_FRAC))
    fits = [fitness(x, mode=mode, width=width) for x in phenos]
    ranked = sorted(range(len(genes)), key=lambda i: fits[i], reverse=True)
    selected_idx = ranked[:n_select]

    mean_parents_x = float(np.mean(phenos))
    mean_selected_x = float(np.mean([phenos[i] for i in selected_idx]))
    S = mean_selected_x - mean_parents_x

    offspring = []
    for _ in range(len(genes)):
        parent_g = genes[rng.choice(selected_idx)]
        child_g = TARGET + beta * (parent_g - TARGET) + rng.gauss(0, sigma_v)
        offspring.append(child_g)

    mean_offspring_x = float(np.mean(offspring))
    var_g = float(np.var(genes))
    h2 = var_g / (var_g + sigma_e ** 2) if (var_g + sigma_e ** 2) > 1e-15 else 0.0

    return offspring, S, h2, mean_offspring_x


def run_evolution_full(sigma_v, n_pop, n_gen, beta, sigma_e, seed=42,
                       mode='gauss', width=0.10):
    rng = random.Random(seed)
    genes = [TARGET + rng.gauss(0, 0.1) for _ in range(n_pop)]

    Ss, h2s, means_x = [], [], []
    for gen in range(n_gen):
        genes, S, h2, mean_x = run_generation_record(
            genes, sigma_v, sigma_e, beta, rng, mode=mode, width=width)
        Ss.append(S)
        h2s.append(h2)
        means_x.append(mean_x)

    return Ss, h2s, means_x


def window_ratio(Ss, h2s, means_x, w_start, w_len, beta, target):
    seg_S = Ss[w_start:w_start + w_len]
    seg_h2 = h2s[w_start:w_start + w_len]
    seg_mx = means_x[w_start:w_start + w_len]
    S_mean = float(np.mean(seg_S))
    h2_mean = float(np.mean(seg_h2))
    mx_mean = float(np.mean(seg_mx))
    delta = mx_mean - target
    delta_theory = beta * h2_mean * S_mean / (1 - beta)
    if abs(delta_theory) < 1e-12:
        return float('nan'), S_mean, h2_mean, delta, delta_theory
    return delta / delta_theory, S_mean, h2_mean, delta, delta_theory


def check_monotone_to_one(values, tol=0.02):
    diffs = [values[i+1] - values[i] for i in range(len(values) - 1)]
    n_toward = sum(1 for d in diffs if d < 0)
    last = values[-1]
    if n_toward == len(diffs) and abs(last - 1.0) < tol:
        return "单调向1收敛"
    if n_toward >= len(diffs) - 1 and abs(last - 1.0) < tol:
        return "近单调向1收敛"
    return "非单调"


def check_stable_offset(values, tol=0.01):
    mean_v = float(np.mean(values))
    spread = max(values) - min(values)
    if spread < tol and abs(mean_v - 1.0) > 0.02:
        return "稳定偏离1 (offset={:.4f})".format(mean_v - 1.0)
    return "非稳定偏离"


def check_random_walk(values, tol=0.02):
    diffs = [values[i+1] - values[i] for i in range(len(values) - 1)]
    signs = [1 if d > 0 else -1 for d in diffs]
    sign_changes = sum(1 for i in range(len(signs) - 1) if signs[i] != signs[i+1])
    spread = max(values) - min(values)
    if sign_changes >= len(diffs) // 2 and spread > tol:
        return "无趋势随机游走 (spread={:.4f})".format(spread)
    return "非随机游走"


def main():
    bar("天赐范式第183天:窗口后移三方判决测试")
    print("  PID: {}".format(PID))
    print()

    sub("预登记】三个假说对窗口后移的预测")
    print("  假说A 慢暂态        : 比值随窗口起点单调向1收敛")
    print("  假说B 系统偏差(Jensen): 稳定偏离1,不随窗口动")
    print("  假说C 纯漂变        : 单seed值附近随机游走,无趋势")
    print()
    print("  测试参数:")
    print("    sigma_v  in {0.40, 0.80, 1.50}")
    print("    seeds    = [42, 0, 1, 2, 3, 4]  (6个)")
    print("    窗口起点 = [100, 200, 300, 500]")
    print("    窗长     = 400")
    print("    总代数   = {}".format(N_TOTAL_GEN))
    print("    beta={}, sigma_e={}, N_pop={}, select_frac={}".format(
        BETA, SIGMA_E, N_POP, SELECT_FRAC))
    print()
    print("  理论疑问(用户提出):")
    print("    beta=0.3时均值位移时间常数≈1/(1-beta)≈1.4代")
    print("    方差时间常数≈1/(1-beta^2)≈1.1代")
    print("    warmup=100是约70个时间常数,暂态理论上早死透")
    print("    伙伴观察到的'单调向1收敛'可能是噪声呈现的假趋势")
    print()

    sub("步骤1】逐seed逐窗口比值表")
    print("  每个seed跑一次{}代,在不同窗口起点切片取均值算比值".format(N_TOTAL_GEN))
    print()

    all_results = {}
    for sigma_v in TEST_SIGMAS:
        print("  --- sigma_v = {:.2f} ---".format(sigma_v))
        print("  | seed | w=100   | w=200   | w=300   | w=500   | 趋势检查 |")
        print("  |------|---------|---------|---------|---------|----------|")
        seed_ratios = []
        for seed in TEST_SEEDS:
            Ss, h2s, means_x = run_evolution_full(
                sigma_v, N_POP, N_TOTAL_GEN, BETA, SIGMA_E, seed=seed)
            ratios = []
            for w_start in WINDOW_STARTS:
                r, _, _, _, _ = window_ratio(
                    Ss, h2s, means_x, w_start, WINDOW_LEN, BETA, TARGET)
                ratios.append(r)
            seed_ratios.append(ratios)
            trend = check_monotone_to_one(ratios)
            print("  | {:>4d} | {:7.4f} | {:7.4f} | {:7.4f} | {:7.4f} | {} |".format(
                seed, ratios[0], ratios[1], ratios[2], ratios[3], trend))
        print()
        all_results[sigma_v] = seed_ratios

    sub("步骤2】跨seed汇总------每个sigma_v各窗口起点的mean+-std")
    print("  (跨6个seed的统计;这是判决的核心表)")
    print()
    print("  | sigma_v | w=100 mean+-std       | w=200 mean+-std       | w=300 mean+-std       | w=500 mean+-std       |")
    print("  |---------|----------------------|----------------------|----------------------|----------------------|")
    summary = {}
    for sigma_v in TEST_SIGMAS:
        seed_ratios = all_results[sigma_v]
        cols = []
        for j in range(len(WINDOW_STARTS)):
            col_vals = [seed_ratios[i][j] for i in range(len(seed_ratios))]
            cols.append(col_vals)
        parts = []
        for col_vals in cols:
            m = float(np.mean(col_vals))
            s = float(np.std(col_vals))
            parts.append((m, s))
        summary[sigma_v] = parts
        print("  | {:.2f}    | {:7.4f} +- {:7.4f}   | {:7.4f} +- {:7.4f}   | {:7.4f} +- {:7.4f}   | {:7.4f} +- {:7.4f}   |".format(
            sigma_v,
            parts[0][0], parts[0][1],
            parts[1][0], parts[1][1],
            parts[2][0], parts[2][1],
            parts[3][0], parts[3][1]))
    print()

    sub("步骤3】判决辅助------三个假说逐一检验")
    print("  对每个sigma_v,看跨seed均值的窗口序列 [w100, w200, w300, w500]")
    print()
    for sigma_v in TEST_SIGMAS:
        parts = summary[sigma_v]
        means_seq = [p[0] for p in parts]
        print("  sigma_v = {:.2f}:".format(sigma_v))
        print("    跨seed均值序列: [{:.4f}, {:.4f}, {:.4f}, {:.4f}]".format(
            means_seq[0], means_seq[1], means_seq[2], means_seq[3]))
        print("    距1.0的偏差   : [{:+.4f}, {:+.4f}, {:+.4f}, {:+.4f}]".format(
            means_seq[0]-1, means_seq[1]-1, means_seq[2]-1, means_seq[3]-1))
        mono = check_monotone_to_one(means_seq)
        stable = check_stable_offset(means_seq)
        rw = check_random_walk(means_seq)
        print("    假说A 慢暂态        : {}".format(mono))
        print("    假说B 系统偏差      : {}".format(stable))
        print("    假说C 纯漂变        : {}".format(rw))
        spread = max(means_seq) - min(means_seq)
        print("    窗口间spread       : {:.4f}".format(spread))
        last_dev = abs(means_seq[-1] - 1.0)
        first_dev = abs(means_seq[0] - 1.0)
        print("    |偏差|从{:.4f}(w100)到{:.4f}(w500)".format(first_dev, last_dev))
        if last_dev < first_dev and mono.startswith("单调"):
            print("    -> 偏差随窗口后移减小且单调:支持慢暂态")
        elif spread < 0.005 and abs(float(np.mean(means_seq)) - 1.0) > 0.02:
            print("    -> 窗口间几乎不动且偏离1:支持系统偏差")
        else:
            print("    -> 需人工判断(看趋势+spread+偏差方向)")
        print()

    sub("步骤4】单seed轨迹细看------seed=42(原偏差就是这颗出的)")
    print("  看seed=42在每个sigma_v下的逐窗口比值,判断是趋势还是噪声")
    print()
    print("  | sigma_v | w=100   | w=200   | w=300   | w=500   | 单调? |")
    print("  |---------|---------|---------|---------|---------|-------|")
    for sigma_v in TEST_SIGMAS:
        seed_idx = TEST_SEEDS.index(42)
        ratios = all_results[sigma_v][seed_idx]
        mono = check_monotone_to_one(ratios)
        print("  | {:.2f}    | {:7.4f} | {:7.4f} | {:7.4f} | {:7.4f} | {} |".format(
            sigma_v, ratios[0], ratios[1], ratios[2], ratios[3], mono))
    print()

    sub("步骤5】更细窗口切片------每100代一个比值(seed=42)")
    print("  窗口起点从100到500每50代步进,看曲线形状")
    print()
    fine_starts = list(range(100, 501, 50))
    for sigma_v in TEST_SIGMAS:
        print("  --- sigma_v = {:.2f}, seed=42 ---".format(sigma_v))
        Ss, h2s, means_x = run_evolution_full(
            sigma_v, N_POP, N_TOTAL_GEN, BETA, SIGMA_E, seed=42)
        fine_ratios = []
        for w_start in fine_starts:
            r, _, _, _, _ = window_ratio(
                Ss, h2s, means_x, w_start, WINDOW_LEN, BETA, TARGET)
            fine_ratios.append(r)
        print("  | w_start | ratio   | dev from 1 |")
        print("  |---------|---------|------------|")
        for i, w_start in enumerate(fine_starts):
            r = fine_ratios[i]
            print("  | {:>7d} | {:7.4f} | {:+10.4f} |".format(w_start, r, r - 1.0))
        diffs = [fine_ratios[i+1] - fine_ratios[i] for i in range(len(fine_ratios)-1)]
        n_down = sum(1 for d in diffs if d < 0)
        n_up = sum(1 for d in diffs if d > 0)
        print("  逐50代步进:{}步下降,{}步上升(共{}步)".format(n_down, n_up, len(diffs)))
        print()

    bar("三方判决结果汇总")
    print("  将上述数据交给用户做最终判决。")
    print()
    print("  判决规则(预登记):")
    print("    若跨seed均值随窗口起点单调向1收敛 -> 假说A慢暂态成立")
    print("    若跨seed均值稳定偏离1且窗口间spread<0.005 -> 假说B系统偏差成立")
    print("    若跨seed均值无趋势且窗口间波动大 -> 假说C纯漂变成立")
    print()
    print("  连带警告:若慢暂态被证实,主实验warmup=100偏短,")
    print("  所有表格需按新warmup重新生成,183-1正文也需同步。")
    print("=" * 78)


if __name__ == "__main__":
    main()
相关推荐
天赐范式1 天前
天赐范式第183天:让选择开始生效——育种者方程与选择生效条件
python·数字生命·天赐范式·动态运行时·育种者方程·选择压力·遗传力
天赐范式2 天前
天赐范式第181天:让视图开始切换——PBFT视图切换与从safety到liveness的跨越
python·pbft·数字生命·天赐范式·动态运行时·拜占庭容错
天赐范式3 天前
天赐范式第181天:让耦合开始失稳——竞争耦合与线性失稳边界
python·数字生命·天赐范式·lyapunov指数·动态运行时·耦合失稳·laplacian矩阵
天赐范式3 天前
天赐范式第182天:让变异开始存活——主线重启与变异存续条件
python·ar模型·数字生命·天赐范式·动态运行时·稳态方差·变异存续
天赐范式7 天前
天赐范式第175天:让活着的成员互相验证——异质互验与重放反伪造
python·数字生命·天赐范式·动态运行时·互验·重放反伪造
天赐范式14 天前
天赐范式第165天:让理开始生根——第一性原理:双层架构是稳定学习系统的必然收敛解
天赐范式·动态运行时·必然≠唯一·收敛≠终点·稳定≠永恒·同态≠同构·必要条件≠充分条件
天赐范式16 天前
天赐范式第168天:让子代开始从父代肩膀上演化——跨代β传递demo与完整代码
python·数字生命·天赐范式·动态运行时·跨代β传递·可继承性验证·digitallife
天赐范式21 天前
天赐范式第163天:让信仰开始自生长——信仰从机制中涌现,不由咱们定义
边界·天赐范式·动态运行时·信仰自涌现·系统性信念·拜占庭门控·verify不问动机
天赐范式25 天前
天赐范式第159天:让广播走出本机——HTTP通道发出第一声
python·broadcast·urllib·http.server·天赐范式·动态运行时·http通道