diff --git a/README.md b/README.md
index f6076a3..82577f1 100644
--- a/README.md
+++ b/README.md
@@ -44,8 +44,8 @@ afem/
- **入射波**: 沿 -x 方向的平面波 `u_inc = exp(i·k·x)`
- **散射体**: 圆形介质柱(ε_r 随机采样),位置和半径可配
- **边界条件**: SBC (Sommerfeld) `∂u/∂n = i·k·u`
-- **域**: 可配矩形域,初始网格密度自适应 + domain area 线性缩放:`N_init = N_base × (k/k_ref)^k_exponent × domain_area`。k_ref 和 k_exponent 均可通过 helmholtz config 配置(默认 k_exponent=1.5, k_ref=6.0),保证不同域尺寸下每单位面积单元数一致
-- 可配 exponent:^2 = P1 Helmholtz 理论最优 (污染误差 ∝ k²),^1.5 = 工程折中。建议 N_base 配合 exponent 调整,使 N_init 约为 COMSOL 目标 (λ/10√ε_r) 的 30-50%,为 RL agent 留出充分细化空间
+- **域**: 可配矩形域,初始网格密度自适应 + domain area 线性缩放:`N_init = N_base × (k/k_ref)^k_exponent × domain_area`。k_ref 和 k_exponent 均可通过 helmholtz config 配置(默认 k_exponent=2.0, k_ref=6.0),保证不同域尺寸下每单位面积单元数一致
+- 可配 exponent:^2 = P1 Helmholtz 理论最优 (污染误差 ∝ k²)。建议 N_base 配合 exponent 调整,使 N_init 约为 COMSOL 目标 (λ/10√ε_r) 的 30-50%,为 RL agent 留出充分细化空间
- **介质区前渐近区边缘约束**: 介质内 λ_d = 2π/(k√ε_r) 更短,强制迭代细化至 h ≤ λ_d/N(默认 N=1.5,helmholtz.pre_asymptotic_N 可配)。约 1.5 点/波长,刚好跨过渐近区门槛,赋予初始网格基本相位解析能力但不过度消耗物理预算,为 RL agent 留出充分的选择性细化空间
- **后验误差**: 残差型 indicator(Ainsworth & Oden 风格),含单元内部残差 + 梯度跳变 + SBC 边界残差
@@ -54,7 +54,7 @@ afem/
| 概念 | 对应实体 |
|------|---------|
| **智能体** | 每个三角形网格单元 |
-| **状态** | GNN 节点特征(几何 + PDE 残差 + 复数场分解 + 物理参数,节点 12 维 + 边 1 维) |
+| **状态** | GNN 节点特征(几何 + PDE 残差 + 振幅 + 相位方向 + 物理参数,节点 13 维 + 边 1 维) |
| **动作** | 1 维连续标量 x_i → score = -x_i 排序,在物理预算内 top-k 选细化单元(x 越小优先级越高) |
| **奖励** | 局部子单元 η 的 log-ratio 改善(spatial: sum 聚合 / spatial_max: max 聚合)+ α 衰减全局 η log-ratio shaping |
| **终止** | 达到最大步数或超过最大单元数 |
@@ -68,10 +68,12 @@ afem/
```
图观测 → MessagePassingBase → MLP → 动作分布 / value 标量
├─ nn.Linear(嵌入)
- ├─ MessagePassingStack(2 层消息传递,inner 残差 + LayerNorm)
- │ └─ MessagePassingStep × N
- │ ├─ EdgeModule: MLP([src | dst | edge_attr])
- │ └─ NodeModule: MLP([node | scatter(入边)])
+ ├─ MessagePassingStack(2 层消息传递 + GVN 全局广播,inner 残差 + LayerNorm)
+ │ ├─ MessagePassingStep × N
+ │ │ ├─ EdgeModule: MLP([src | dst | edge_attr])
+ │ │ └─ NodeModule: MLP([node | scatter(入边)])
+ │ └─ GlobalVirtualNode (GVN): η_K 加权注意力池化 → 注意力门控广播
+ │ h_V = Σ(η_v/Ση)·h_v,α_v = σ(W_att[h_v || h_V]),h_v ← h_v + α_v ⊙ W_V·h_V
└─ 输出: 节点隐向量
```
@@ -101,31 +103,32 @@ afem/
## 输入特征
-### 节点特征(12 维)
+### 节点特征(13 维)
| 维度 | 来源 | 名称 | 说明 |
|------|------|------|------|
| 1 | cfg | `volume` | 无量纲单元面积:volume / λ² |
-| 3 | cfg | `internal_residual` / `gradient_jump` / `sbc_residual` | PDE 残差三分量(无量纲化,经 log₁₀ 压缩):
`(h_K/k_local)·√V·|r|` / `√(½Σ h_e·\|jump\|²/k_local)` / `(h_bnd/k_local)·\|SBC\|` |
+| 3 | cfg | `internal_residual` / `gradient_jump` / `sbc_residual` | PDE 残差三分量(真空波数 k 归一化,经 log₁₀ 压缩):
`(h_K/k)·√V·|r|` / `√(½Σ h_e·\|jump\|²/k)` / `(h_bnd/k)·\|SBC\|` |
| 1 | cfg | `element_penalty` | 单元惩罚系数 λ |
| 1 | cfg | `timestep` | 当前 rollout 步数 |
-| 1 | cfg | `wave_number` | Helmholtz 波数 k |
-| 1 | cfg | `k_local_sqrt_vol` | k × √体积(局域波数 × 特征长度) |
+| 1 | cfg | `k_local_sqrt_vol` | k × √(ε_r) × √(V)(局域波数 × 特征长度) |
| 1 | cfg | `is_sbc_boundary` | 是否与 SBC 吸收边界相邻 (0/1) |
| 1 | cfg | `dist_to_interface` | 到介质圆柱边界的带符号距离,无量纲化后经 sign·ln(1+|d|) 压缩:`sign(d)·ln(1+|(dist-radius)/λ|)` — 近场近似线性保留分辨力,远场对数压缩避免 OOD,与残差 log₁₀ 风格一致 |
| 1 | fix | `epsilon_r` | 单元中点相对介电常数(圆柱内 = εᵣ,外 = 1.0) |
-| 1 | fix | `total_solution_magnitude` | 散射场复数解的振幅 |
+| 1 | fix | `total_solution_magnitude` | 散射场振幅 \|u_scat\|(per-element 均值) |
+| 1 | fix | `cos_phase` | Re(u) / (\|u\| + 1e-8),相位方向余弦,∈ [−1, 1],无分支切割 |
+| 1 | fix | `sin_phase` | Im(u) / (\|u\| + 1e-8),相位方向正弦,与 cos 联合编码相位 |
> - **cfg**: 由 `element_features` 配置控制
-> - **fix**: 始终启用(Helmholtz 复数场分解,硬编码)
+> - **fix**: 始终启用(Helmholtz 振幅 + 相位方向,硬编码)
>
-> GNN 输入用 `_compute_residual_components`(k_local 无量纲化,log₁₀ 压缩)。Reward 用逐单元 η_K(`_eta_indicator`),与 GNN 特征公式一致但不经 log 压缩。
+> GNN 输入用 `_compute_residual_components`(真空波数 k 归一化,log₁₀ 压缩)。Reward 用逐单元 η_K(`_eta_indicator`),与 GNN 特征公式一致但不经 log 压缩。SBC 边界条件保留 `k_local`。
### 边特征(1 维)
| 维度 | 名称 | 说明 |
|------|------|------|
-| 1 | `euclidean_distance` | 相邻单元中点欧几里得距离 / λ(无量纲边特征) |
+| 1 | `phase_distance` | 相邻单元中点相位距离 = d × √(k_local_src·k_local_dst) / 2π — 介质内短波长自然放大,赋予 GNN k 不变性 |
---
@@ -144,7 +147,7 @@ main.py --mode train/test/viz
└─ [train] → ppo.PPOTrainer.fit_iteration() 循环
├─ collect_rollouts() # 256 步 rollout
│ └─ buffer.compute_returns_and_advantage()
- │ └─ 单路 GAE # 逐 agent 时序差分(scatter_add 处理网格细化),奖励含势函数塑形项
+ │ └─ 单路 GAE # 逐 agent 时序差分(scatter_add 处理网格细化)
│ └─ Return / value 归一化
└─ train_step() # 多 epoch PPO 更新
├─ policy_loss() # Clipped PPO
@@ -186,7 +189,7 @@ it | loss ev agents reward x<0 elig sel time
|------|------|---------|
| `x<0` | `mean(x_i < 0)`,负值动作比例(纯诊断) | 越负的单元优先级越高 |
| `elig` | 通过双过滤器的候选占比 | 排除数值退化 + 低误差的单元 |
-| `mask` | 被 Dörfler-P95 掩码 (η<0.05·η_P95) 滤掉的占比 | 因场景而异,非固定比例 |
+| `mask` | 被 Reverse Dörfler 剔除的噪声尾部占比(累积能量 <1% 总误差的底部单元) | 因场景而异,非固定比例 |
| `sel` | 实际选中的细化单元数 | 每步最多 N_current // 4 |
| `n_budget` | 全局物理预算(每 episode 固定) | k=30 → ~1800 |
@@ -226,24 +229,25 @@ python src/main.py --mode viz --checkpoint checkpoints/model_final.pt --k-test 3
对 P1 三角单元 K,三项残差分量为:
-$$r_{\text{int}} = \frac{h_K}{k_{local}} \sqrt{V_K} \cdot \left| k^2\varepsilon_r u + k^2(\varepsilon_r-1)u_{inc} \right|_K \tag{1}$$
+$$r_{\text{int}} = \frac{h_K}{k} \sqrt{V_K} \cdot \left| k^2\varepsilon_r u + k^2(\varepsilon_r-1)u_{inc} \right|_K \tag{1}$$
-$$r_{\text{jump}} = \sqrt{\frac{1}{2}\sum_{e\in\partial K} \frac{h_e}{k_{local}} \cdot \left| [[\nabla u \cdot n]] \right|^2_e} \tag{2}$$
+$$r_{\text{jump}} = \sqrt{\frac{1}{2}\sum_{e\in\partial K} \frac{h_e}{k} \cdot \left| [[\nabla u \cdot n]] \right|^2_e} \tag{2}$$
-$$r_{\text{sbc}} = \frac{h_{bnd}}{k_{local}} \cdot \left| \frac{\partial u}{\partial n} - ik_{local}u \right| \tag{3}$$
+$$r_{\text{sbc}} = \frac{h_{bnd}}{k} \cdot \left| \frac{\partial u}{\partial n} - ik_{local}u \right| \tag{3}$$
**逐单元误差指示子**:
$$\eta_K = \sqrt{r_{\text{int}}^2 + r_{\text{jump}}^2 + r_{\text{sbc}}^2}$$
-量纲分析($k_{local} \sim [L]^{-1}$,$h_e \sim [L]$,$|\text{jump}|^2 \sim [L]^{-2}$):
-三项均严格无量纲:$h_e/k_{local} \cdot |\text{jump}|^2 \sim [L]^2 \cdot [L]^{-2} = 1$。
-细化后 $h_e$ 缩小直接降低跳变项,为 RL agent 提供可感知的正向 reward 信号。
+量纲分析($k \sim [L]^{-1}$,$h_e \sim [L]$,$|\text{jump}|^2 \sim [L]^{-2}$):
+三项均严格无量纲:$h_e/k \cdot |\text{jump}|^2 \sim [L]^2 \cdot [L]^{-2} = 1$。
+SBC 边界条件仍用 $k_{local}$(物理正确),仅归一化因子改用 $k$。
+介质内残差不再被 $\sqrt{\varepsilon_r}$ 压低,Agent 获得正确的介质内/外优先级信号。
`η_K` 的计算(`_compute_residual_indicator`)与 GNN 输入特征(`_compute_residual_components`)公式完全一致,特征仅多一层 log₁₀ 压缩。关键验证点:
-- 内部残差:P1 元 ∇²u_h ≡ 0,仅含反应项 `k²ε_r·u + k²(ε_r-1)·u_inc`,除以 `k_local` 后跨介质公平可比
-- 梯度跳变:`(h_e/k_local)·|jump|²`,½ 分配给相邻左右单元;$h_e$ 保留边积分路径,细化后自然衰减
-- SBC 项在 η_K² 中为 `(h_bnd²/k_local²)·|B|²`,分量 `r_sbc = (h_bnd/k_local)·|B|`
+- 内部残差:P1 元 ∇²u_h ≡ 0,仅含反应项 `k²ε_r·u + k²(ε_r-1)·u_inc`,真空波数 k 归一化
+- 梯度跳变:`(h_e/k)·|jump|²`,½ 分配给相邻左右单元;$h_e$ 保留边积分路径,细化后自然衰减
+- SBC 项归一化用 k,物理条件保留 k_local:`(h_bnd²/k²)·|∂u/∂n − i·k_local·u|²`
### 连续尺寸场策略(score-based + 物理预算约束 + 动作掩码)
@@ -258,7 +262,7 @@ N_phys = ⌈ Σ |K_i| / A_budget_i ⌉ // 全局物理预算(k=30 真
remaining = N_budget − N_current
V_min_safeguard = 1e-10 × domain_area // 纯数值底线(防止 FEM 求解器退化)
-eligible: area > V_min_safeguard AND η_K ≥ 0.05·η_P95 // 数值底线 + Dörfler-P95
+eligible: area > V_min_safeguard AND η_K ∈ Reverse Dörfler 保留集 // 数值底线 + 能量尾部淘汰 (ε_noise=0.01, ≥20% floor)
num = min(|eligible|, N_current//4, remaining//3)
selected = top-k by score = -x_i → 1-to-4 切分
```
@@ -266,9 +270,9 @@ selected = top-k by score = -x_i → 1-to-4 切分
- score = -x_i:x 越小 ⇒ 优先级越高(纯排序,不设正负门槛)
- 不再使用 `0.25·A_budget` 启发式面积地板:RL 应自主学会"细化到多细",而非被人类经验 (12 点/波长) 限制。仅保留数值底线 V_min_safeguard = 1e-10 × domain_area 防止浮点精度问题。
- per-step cap 从固定 200 改为自适应 `N_current // 4`,随网格规模缩放但增速更缓,避免大网格时单步消耗过多预算。rho_min 从 3.0 提升到 5.0,赋予更多预算余量。
-- **sel=0 提前终止**:当 agent 选中 0 个单元细化(预算耗尽或 Dörfler 屏蔽所有候选)时 episode 自动结束,不再浪费 FEM 求解
-- **k_exponent 可配**:初始网格缩放指数可通过 `helmholtz.k_exponent` 配置(默认 1.5),² 为 P1 Helmholtz 理论最优
-- **动作掩码 (Dörfler-P95)**:η_K < 0.05·η_P95 的单元移出候选池。P95 锚定物理误差尺度,免疫远场噪声稀释(与 median/mean 不同),确保只有误差达标的区域消耗细化预算
+- **sel=0 提前终止**:当 agent 选中 0 个单元细化(预算耗尽或 Reverse Dörfler 屏蔽所有候选)时 episode 自动结束,不再浪费 FEM 求解
+- **k_exponent 可配**:初始网格缩放指数可通过 `helmholtz.k_exponent` 配置(默认 2.0),² 为 P1 Helmholtz 理论最优;对 k=30 的 $N_{init}$ 为 k=6 的 25× 倍
+- **动作掩码 (Reverse Dörfler)**:按 η_K 升序排列,剔除累积平方误差贡献 < ε_noise·Ση² 的底部单元(数值噪声/已收敛区)。基于能量分布而非密度分位数,在重尾和均匀误差分布下均自适应。保留率不低于 20% 确保 Agent 始终有充分的选择空间
### 奖励计算
@@ -303,10 +307,12 @@ score = -x // x 越小 ⇒ 优先级越
remaining = N_budget − N_old
max_by_budget = max(0, remaining // 3)
-// 数值底线 + Dörfler-P95 掩码
+// 数值底线 + Reverse Dörfler 能量尾部淘汰
V_min_safeguard = 1e-10 × domain_area // 纯数值安全底线,防止 FEM 退化
-η_p95 = percentile(η_old, 95)
-eligible = {i | V_old[i] > V_min_safeguard AND η_old_i ≥ 0.05·η_p95}
+η_sq = η_old²; total_energy = Σ η_sq
+k_dorfler = searchsorted(cumsum(sort_asc(η_sq)), ε_noise·total_energy) // ε_noise=0.01
+k = min(k_dorfler, N − max(1, N//5)) // ≥20% floor
+eligible = {i | V_old[i] > V_min_safeguard AND i ∈ sort_asc_idx[k:] }
num = min(|eligible|, N_old//3, max_by_budget)
elements_to_refine = top-k of eligible by score
@@ -320,42 +326,32 @@ M_new[j] ∈ {0,…,N_old-1} // 子→父映射
||u_h_new|| ← 新解 L₂ 范数
```
-**Step 3 — 局部奖励**(动态截断 ε_dynamic)
+**Step 3 — 因果奖励**(零和预算审查)
-ε_dynamic = max(0.01 × η_P95, 1e-6) // P95 锚定,免疫远场噪声稀释
-ε_dynamic = max(0.05 × mean(η_new), 1e-6) // 自适应钳制,切断远场低 η 区 reward hacking
-spatial: r_local_i = log(η_old_i + ε_dynamic) − log( √(Σ_{j: M_new[j]=i} η_new_j²) + ε_dynamic )
-spatial_max: r_local_i = log(η_old_i + ε_dynamic) − log( max_{j: M_new[j]=i} η_new_j + ε_dynamic )
-```
+ε_dynamic = max(0.01 × η_P95, 1e-6)
-> **L₂ 聚合保证 r_local ≥ 0**: 对 1-to-4 切分:
-> ```
-> Σ η_child² = int²/4 + jump² + sbc² ≤ η_parent² = int² + jump² + sbc²
-> → r_local = ½[log(η_parent²) − log(Σ η_child²)] ≥ 0
-> ```
-> - 纯 int 主导: r_local = log(2) ≈ 0.69(强正奖励)
-> - 纯 jump/sbc 主导: r_local = 0(中性,不惩罚不奖励)
-> - **永远不会惩罚细化**——与 L₁ sum 不同,L₂ 天然避免了对 jump/sbc 主导区的结构性负偏置。
+// Refined parents: r_local + zero-sum bonus − penalty
+if i ∈ refined_parents:
+ r_i = log(η_old + ε) − log(√(Σ η_child²) + ε) // r_local ≥ 0 (L₂ 聚合)
+ + 0.3 × (η_old / μ − 1.0) // zero-sum bonus (Σ = 0)
+ − 0.06 // action penalty
-**Step 4 — 动作惩罚**
+// Unrefined parents: causal isolation
+else:
+ r_i = 0
-```
-penalty_i = λ · (n_i − 1) // λ = 0.06
- + (λ_limit / N_old) · 𝟙[达到最大单元数上限] // λ_limit = 10000
+> **零和奖金**:α·(η/μ−1) 全场求和为零。细化高于均值的单元得正奖金,低于均值的倒扣。
+> 这是 Dörfler 准则的 RL 对偶:Agent 必须选出误差超过全均水平的单元。
+> **因果隔离**:未细化单元 r ≡ 0。零和奖金本身足够强(介质内 +0.51)、
+> 不再需要忽视惩罚的推力,排序机制自动淘汰不划算的单元。
+> **L₂ 聚合**:√(Σ η_child²) ≤ η_parent 天然成立,r_local ≥ 0 永不惩罚细化。
-r_local_i ← r_local_i − penalty_i
-```
+**Step 4 — 全局误差(仅诊断)**
-**Step 5 — 全局势函数塑形**(仅发给被细化的父单元)
+global_bonus = α·[log(E_old) − log(E_new)],α = 0.5
-```
-E_global = √(Σ_K η_K²) / ||u_h||_{L₂(Ω)}
-global_bonus = α · [ log(E_global_old) − log(E_global_new) ] // α = 0.2
-
-r_i = r_local_i − penalty_i + global_bonus · 𝟙[i 被细化] // 未细化的单元 reward ≈ 0
-```
-
-> 全局改进信号只分配给实际参与细化的单元,避免被未细化单元稀释。
+不注入 Actor reward。Helmholtz 污染误差可使 E_new > E_old 在正确细化后发生,
+注入 global_bonus 导致因果断裂。Actor 仅优化 Step 3 的 per-element reward。
---
@@ -378,19 +374,21 @@ r_i = r_local_i − penalty_i + global_bonus · 𝟙[i 被细化]
| 组件 | 聚合 | 作用 |
|------|------|------|
-| 局部项 `log(η_old / √(Σ η_child²))` | scatter_add(子→父求平方和再开方) | L₂ 聚合保证 r_local ≥ 0:不惩罚任何细化,int 主导区获强正奖励 (≈+0.69),纯 jump/sbc 区中性 |
-| 动作惩罚 `λ(n_i−1)` λ=0.02 | per-parent | 轻微抑制网格膨胀(1-to-4 切分扣 0.06,仅占 r_local 的 ~16%) |
-| 元素上限惩罚 | 达到 20000 上限时触发 | 极端情况兜底,λ_limit / N_old ≈ 0.05~0.5 per agent |
-| 全局项 `α·ΔlogE` α=0.2 | 仅细化父单元 | L₂ 无量纲全局误差下降趋势,只发给实际参与细化的单元,避免被未细化单元稀释 |
+| 局部项 `log(η_old / √(Σ η_child²))` | scatter_add,仅 refined parents | L₂ 保证 r_local ≥ 0;int 主导 +0.69 |
+| 零和奖金 `0.3×(η/μ−1)` | 仅 refined parents | Σ=0;高于 μ 得正奖,低于 μ 倒扣 (Dörfler 准则的 RL 对偶) |
+| 动作惩罚 `λ=0.06` | per-refined-parent | 轻微抑制网格膨胀(1-to-4 扣 0.06) |
+| 因果隔离 `r=0` | unrefined parents | 零和奖金足够强,不需额外推力 |
+| 全局项 `α·ΔlogE` α=0.5 | 仅诊断 | 不注入 Actor,避免污染误差因果断裂 |
---
## PPO 关键细节
-- **单路 GAE**: 势函数塑形后的奖励已包含全局改进信号,用 `scatter_add` 将细化后的子单元值聚合回父单元,单路 GAE 即可
+- **单路 GAE**: r_local 自身已闭合因果(细化单元的局部误差改善),不需要势函数塑形。用 `scatter_add` 将细化后的子单元值聚合回父单元,单路 GAE 即可
- **奖励归一化**: rollout 内 reward 做 z-score 归一化(std < 1e-8 则跳过)
- **Value clipping**: 默认 clip_range=0.2
- **梯度裁剪**: max_grad_norm=0.5
-- **log_std clamp**: 每步 `optimizer.step()` 后将 `log_std` clamp 到 `[-4.0, -1.0]`,std ∈ [0.018, 0.368]
- 初始化 `-2.0` (std≈0.135),避免 `continuous_sizing_field` 有效范围 [-3, 3] 内噪声过大
-- **熵正则**: `entropy_coefficient=0.001`,防止 log_std 过早收敛
+- **log_std clamp**: 每步 `optimizer.step()` 后将 `log_std` clamp 到 `[-3.0, -1.0]`,σ ∈ [0.05, 0.37]
+ 初始化 `-2.0` (σ≈0.135),放宽下限防止策略过早确定化
+- **熵正则**: `entropy_coefficient=0.005`,施加有意义的探索压力防止 x<0 崩塌
+- **epochs_per_iteration**: 3,减少对同一 rollout 的过拟合
diff --git a/checkpoints/model_final.pt b/checkpoints/model_final.pt
index ad28a58..96c9f34 100644
Binary files a/checkpoints/model_final.pt and b/checkpoints/model_final.pt differ
diff --git a/checkpoints/model_iter0050.pt b/checkpoints/model_iter0050.pt
index b1a73cc..2d73588 100644
Binary files a/checkpoints/model_iter0050.pt and b/checkpoints/model_iter0050.pt differ
diff --git a/checkpoints/model_iter0100.pt b/checkpoints/model_iter0100.pt
index 3195245..18ec256 100644
Binary files a/checkpoints/model_iter0100.pt and b/checkpoints/model_iter0100.pt differ
diff --git a/checkpoints/model_iter0150.pt b/checkpoints/model_iter0150.pt
index b87bc5d..16dc8c9 100644
Binary files a/checkpoints/model_iter0150.pt and b/checkpoints/model_iter0150.pt differ
diff --git a/checkpoints/model_iter0200.pt b/checkpoints/model_iter0200.pt
index a461fa7..344a1cc 100644
Binary files a/checkpoints/model_iter0200.pt and b/checkpoints/model_iter0200.pt differ
diff --git a/checkpoints/model_iter0250.pt b/checkpoints/model_iter0250.pt
index e4d1695..11a8dfd 100644
Binary files a/checkpoints/model_iter0250.pt and b/checkpoints/model_iter0250.pt differ
diff --git a/checkpoints/model_iter0300.pt b/checkpoints/model_iter0300.pt
index 5b7aeae..5853b18 100644
Binary files a/checkpoints/model_iter0300.pt and b/checkpoints/model_iter0300.pt differ
diff --git a/checkpoints/model_iter0350.pt b/checkpoints/model_iter0350.pt
index 2814b5c..9cdcabd 100644
Binary files a/checkpoints/model_iter0350.pt and b/checkpoints/model_iter0350.pt differ
diff --git a/checkpoints/model_iter0400.pt b/checkpoints/model_iter0400.pt
index 27924d6..1ef54ce 100644
Binary files a/checkpoints/model_iter0400.pt and b/checkpoints/model_iter0400.pt differ
diff --git a/checkpoints/model_iter0401.pt b/checkpoints/model_iter0401.pt
index dfe6856..4be1ab7 100644
Binary files a/checkpoints/model_iter0401.pt and b/checkpoints/model_iter0401.pt differ
diff --git a/checkpoints_beforegvn/model_final.pt b/checkpoints_beforegvn/model_final.pt
new file mode 100644
index 0000000..00a4524
Binary files /dev/null and b/checkpoints_beforegvn/model_final.pt differ
diff --git a/checkpoints_beforegvn/model_iter0050.pt b/checkpoints_beforegvn/model_iter0050.pt
new file mode 100644
index 0000000..3a35cc4
Binary files /dev/null and b/checkpoints_beforegvn/model_iter0050.pt differ
diff --git a/checkpoints_beforegvn/model_iter0100.pt b/checkpoints_beforegvn/model_iter0100.pt
new file mode 100644
index 0000000..7e42abf
Binary files /dev/null and b/checkpoints_beforegvn/model_iter0100.pt differ
diff --git a/checkpoints_beforegvn/model_iter0150.pt b/checkpoints_beforegvn/model_iter0150.pt
new file mode 100644
index 0000000..41e992c
Binary files /dev/null and b/checkpoints_beforegvn/model_iter0150.pt differ
diff --git a/checkpoints_beforegvn/model_iter0200.pt b/checkpoints_beforegvn/model_iter0200.pt
new file mode 100644
index 0000000..2016191
Binary files /dev/null and b/checkpoints_beforegvn/model_iter0200.pt differ
diff --git a/checkpoints_beforegvn/model_iter0250.pt b/checkpoints_beforegvn/model_iter0250.pt
new file mode 100644
index 0000000..4e64f21
Binary files /dev/null and b/checkpoints_beforegvn/model_iter0250.pt differ
diff --git a/checkpoints_stop150/model_iter0050.pt b/checkpoints_stop150/model_iter0050.pt
new file mode 100644
index 0000000..fed4e78
Binary files /dev/null and b/checkpoints_stop150/model_iter0050.pt differ
diff --git a/checkpoints_stop150/model_iter0100.pt b/checkpoints_stop150/model_iter0100.pt
new file mode 100644
index 0000000..eb08959
Binary files /dev/null and b/checkpoints_stop150/model_iter0100.pt differ
diff --git a/checkpoints_stop150/model_iter0150.pt b/checkpoints_stop150/model_iter0150.pt
new file mode 100644
index 0000000..1cfbd59
Binary files /dev/null and b/checkpoints_stop150/model_iter0150.pt differ
diff --git a/environment/__pycache__/domain.cpython-313.pyc b/environment/__pycache__/domain.cpython-313.pyc
index 2d83e81..da40dfa 100644
Binary files a/environment/__pycache__/domain.cpython-313.pyc and b/environment/__pycache__/domain.cpython-313.pyc differ
diff --git a/environment/__pycache__/fem_problem.cpython-310.pyc b/environment/__pycache__/fem_problem.cpython-310.pyc
index 56765dd..3d7dec2 100644
Binary files a/environment/__pycache__/fem_problem.cpython-310.pyc and b/environment/__pycache__/fem_problem.cpython-310.pyc differ
diff --git a/environment/__pycache__/helmholtz.cpython-310.pyc b/environment/__pycache__/helmholtz.cpython-310.pyc
index 0b307bb..953a2d9 100644
Binary files a/environment/__pycache__/helmholtz.cpython-310.pyc and b/environment/__pycache__/helmholtz.cpython-310.pyc differ
diff --git a/environment/__pycache__/helmholtz.cpython-313.pyc b/environment/__pycache__/helmholtz.cpython-313.pyc
index 138a0f3..a33ad3e 100644
Binary files a/environment/__pycache__/helmholtz.cpython-313.pyc and b/environment/__pycache__/helmholtz.cpython-313.pyc differ
diff --git a/environment/__pycache__/mesh_refinement.cpython-310.pyc b/environment/__pycache__/mesh_refinement.cpython-310.pyc
index ddb97f1..e6134d4 100644
Binary files a/environment/__pycache__/mesh_refinement.cpython-310.pyc and b/environment/__pycache__/mesh_refinement.cpython-310.pyc differ
diff --git a/environment/__pycache__/mesh_refinement.cpython-313.pyc b/environment/__pycache__/mesh_refinement.cpython-313.pyc
index b48cc1e..01b631a 100644
Binary files a/environment/__pycache__/mesh_refinement.cpython-313.pyc and b/environment/__pycache__/mesh_refinement.cpython-313.pyc differ
diff --git a/environment/fem_problem.py b/environment/fem_problem.py
index a3f781e..d3392f1 100644
--- a/environment/fem_problem.py
+++ b/environment/fem_problem.py
@@ -142,6 +142,10 @@ class FEMProblemWrapper:
def plot_boundary(self):
return self._plot_boundary
+ @property
+ def last_solve_timing(self) -> Optional[Dict[str, float]]:
+ return getattr(self.fem_problem, "_last_solve_timing", None)
+
# ---- 额外的 plotly 渲染图层 ----
def additional_plots(self) -> Dict:
return self.fem_problem.additional_plots_from_mesh(self._mesh)
diff --git a/environment/helmholtz.py b/environment/helmholtz.py
index 1a2eeb5..9fa85ea 100644
--- a/environment/helmholtz.py
+++ b/environment/helmholtz.py
@@ -1,4 +1,5 @@
import copy
+import time
from typing import Any, Dict, List, Optional, Union
import numpy as np
@@ -71,7 +72,7 @@ class HelmholtzProblem:
boundary = domain_cfg.get("boundary", [0, 0, 1, 1])
domain_area = (boundary[2] - boundary[0]) * (boundary[3] - boundary[1])
k_ref = helmholtz_config.get("k_ref", 6.0)
- k_exponent = helmholtz_config.get("k_exponent", 1.5)
+ k_exponent = helmholtz_config.get("k_exponent", 2.0)
base_elements = domain_cfg.get("initial_num_elements", 400)
scaled_elements = int(base_elements * (self._k / k_ref) ** k_exponent * domain_area)
domain_cfg["initial_num_elements"] = max(scaled_elements, int(base_elements * domain_area))
@@ -104,8 +105,13 @@ class HelmholtzProblem:
return Basis(mesh, ElementTriP1())
def calculate_solution(self, basis: Basis, cache: bool = False) -> np.ndarray:
+ _t = {}
+
+ _t0 = time.perf_counter()
K = asm(self._bilin_form, basis)
+ _t1 = time.perf_counter()
f = asm(self._lin_form_real, basis) + 1j * asm(self._lin_form_imag, basis)
+ _t2 = time.perf_counter()
boundary_facets = basis.mesh.boundary_facets()
facet_basis = FacetBasis(basis.mesh, basis.elem, facets=boundary_facets)
@@ -115,8 +121,18 @@ class HelmholtzProblem:
return u * v
M_boundary = asm(boundary_mass, facet_basis)
+ _t3 = time.perf_counter()
K_total = K.astype(np.complex128) - 1j * self._k * M_boundary
u_scat = solve(K_total, f)
+ _t4 = time.perf_counter()
+
+ _t["assemble_K"] = _t1 - _t0
+ _t["assemble_f"] = _t2 - _t1
+ _t["assemble_boundary"] = _t3 - _t2
+ _t["solve"] = _t4 - _t3
+ _t["total"] = _t4 - _t0
+ _t["n_dof"] = int(basis.mesh.p.shape[1])
+ self._last_solve_timing = _t
return u_scat
@@ -262,20 +278,20 @@ def _compute_residual_indicator(
"""
基于残差的逐单元后验误差估计 — 无量纲化版本。
- 引入局部波数 k_local = k√ε_r 消除纯几何尺度 h 带来的特征偏差,
- 使误差指示子反映"相位分辨率残差"而非"网格粗疏程度"。
+ 使用真空波数 k₀ 归一化(非 k_local),使误差指示子反映"绝对物理误差"
+ 而非"相对局部波长的分辨率"。介质内短波(ε_r>1)的残差在 k_local 下被
+ 压低 √ε_r 倍,改用 k₀ 后介质内 η 自然放大,Agent 获得正确优先级。
P1 单元三项:
- 1. r_int = (h_K/k_local)·√V_K · |k²ε_r·u_h + k²(ε_r-1)·u_inc|
- 2. r_jump = √(½ Σ_{e∈∂K} (h_e/k_local)·|[[∇u_h·n]]|²)
- 3. r_sbc = (h_bnd/k_local)·|∂u/∂n - i·k_local·u|
+ 1. r_int = (h_K/k)·√V_K · |k²ε_r·u_h + k²(ε_r-1)·u_inc|
+ 2. r_jump = √(½ Σ_{e∈∂K} (h_e/k)·|[[∇u_h·n]]|²)
+ 3. r_sbc = (h_bnd/k)·|∂u/∂n - i·k_local·u| (SBC 条件仍用 k_local)
Returns:
eta_elements: shape (num_elements,) 的逐单元误差指标
"""
n_elements = mesh.t.shape[1]
eps_r = np.asarray(eps_r)
- k_local = k * np.sqrt(np.maximum(eps_r, 1.0))
# ── 1. 单元几何量 ──
i0, i1, i2 = mesh.t[0], mesh.t[1], mesh.t[2]
@@ -307,7 +323,7 @@ def _compute_residual_indicator(
f_mid = (k**2) * (eps_r - 1.0) * u_inc_mid
r_mid = f_mid + (k**2) * eps_r * u_mid
- cell_residual_sq = (h_K**2) * element_areas * np.abs(r_mid) ** 2 / (k_local ** 2)
+ cell_residual_sq = (h_K**2) * element_areas * np.abs(r_mid) ** 2 / (k ** 2)
cell_residual_sq[element_areas < 1e-15] = 0.0
# ── 4. 内部边梯度跳变 ──
@@ -327,8 +343,8 @@ def _compute_residual_indicator(
jump_val_sq = jump_val ** 2
jump_residual_sq = np.zeros(n_elements)
- np.add.at(jump_residual_sq, elem_left, 0.5 * h_e * jump_val_sq / k_local[elem_left])
- np.add.at(jump_residual_sq, elem_right, 0.5 * h_e * jump_val_sq / k_local[elem_right])
+ np.add.at(jump_residual_sq, elem_left, 0.5 * h_e * jump_val_sq / k)
+ np.add.at(jump_residual_sq, elem_right, 0.5 * h_e * jump_val_sq / k)
# ── 5. 合并 ──
eta_sq = cell_residual_sq + jump_residual_sq
@@ -356,7 +372,7 @@ def _compute_residual_indicator(
+ u_h[mesh.facets[1, boundary_facets_idx]]
) / 2.0
sbc_residual = du_dn - 1j * k_local * u_edge_mean
- sbc_residual_sq = (h_bnd ** 2) * np.abs(sbc_residual) ** 2 / (k_local ** 2)
+ sbc_residual_sq = (h_bnd ** 2) * np.abs(sbc_residual) ** 2 / (k ** 2)
np.add.at(eta_sq, bnd_elem, sbc_residual_sq)
eta_sq = np.maximum(eta_sq, 0.0)
@@ -373,13 +389,13 @@ def _compute_residual_components(
"""
计算逐单元的三项 PDE 物理残差(分离版,无量纲化)。
- 引入 k_local = k√ε_r 消除几何尺度偏差,使 GNN 跨介质公平感知"相位分辨率残差"。
- 保留源项信息(k²(ε_r-1)·u_inc),确保极粗网格下介质内部巨大物理激励仍可被网络捕捉。
+ 使用真空波数 k₀ 归一化 — 介质内短波残差不再被 k_local 压低,GNN 获得
+ 正确的介质内/外优先级信号。
P1 单元返回:
- internal_residual: (h_K/k_local)·√V_i · |k²ε_r·u + k²(ε_r-1)·u_inc|
- gradient_jump: √(½ Σ_{e∈∂K_i} (h_e/k_local)·|[[∇u·n]]|²)
- sbc_residual: (h_bnd/k_local)·|∂u/∂n - i·k_local·u|
+ internal_residual: (h_K/k)·√V_i · |k²ε_r·u + k²(ε_r-1)·u_inc|
+ gradient_jump: √(½ Σ_{e∈∂K_i} (h_e/k)·|[[∇u·n]]|²)
+ sbc_residual: (h_bnd/k)·|∂u/∂n - i·k_local·u| (SBC 条件仍用 k_local)
element_areas: 单元面积
is_sbc_boundary: 该单元是否与 SBC 边界相邻 (0/1)
@@ -388,7 +404,6 @@ def _compute_residual_components(
"""
n_elements = mesh.t.shape[1]
eps_r = np.asarray(eps_r)
- k_local = k * np.sqrt(np.maximum(eps_r, 1.0))
# ── 1. 单元几何量 ──
i0, i1, i2 = mesh.t[0], mesh.t[1], mesh.t[2]
@@ -421,7 +436,7 @@ def _compute_residual_components(
u_inc_mid = np.exp(1j * k * x_mid)
f_mid = (k**2) * (eps_r - 1.0) * u_inc_mid
r_mid = f_mid + (k**2) * eps_r * u_mid
- internal_residual = (h_K / k_local) * np.sqrt(element_areas) * np.abs(r_mid)
+ internal_residual = (h_K / k) * np.sqrt(element_areas) * np.abs(r_mid)
internal_residual[element_areas < 1e-15] = 0.0
# ── 4. 内部边梯度跳变 (逐单元) ──
@@ -441,8 +456,8 @@ def _compute_residual_components(
gradient_jump = np.zeros(n_elements, dtype=np.float64)
jump_sq_per_edge = jump_val ** 2
- np.add.at(gradient_jump, elem_left, 0.5 * h_e * jump_sq_per_edge / k_local[elem_left])
- np.add.at(gradient_jump, elem_right, 0.5 * h_e * jump_sq_per_edge / k_local[elem_right])
+ np.add.at(gradient_jump, elem_left, 0.5 * h_e * jump_sq_per_edge / k)
+ np.add.at(gradient_jump, elem_right, 0.5 * h_e * jump_sq_per_edge / k)
gradient_jump = np.sqrt(gradient_jump)
# ── 5. SBC 边界残差 + 边界标记 ──
@@ -470,7 +485,7 @@ def _compute_residual_components(
+ u_h[mesh.facets[1, boundary_facets_idx]]
) / 2.0
sbc_val = np.abs(du_dn - 1j * k_local * u_edge_mean)
- np.add.at(sbc_residual, bnd_elem, (h_bnd / k_local) * sbc_val)
+ np.add.at(sbc_residual, bnd_elem, (h_bnd / k) * sbc_val)
is_sbc_boundary[bnd_elem] = 1.0
# ── 对数预处理:压缩跨数量级动态范围(仅 GNN 特征需要)──
diff --git a/environment/mesh_refinement.py b/environment/mesh_refinement.py
index 2947b33..88fe0b1 100644
--- a/environment/mesh_refinement.py
+++ b/environment/mesh_refinement.py
@@ -166,8 +166,11 @@ class MeshRefinement(gym.Env):
feats["dist_to_interface"] = lambda: self._dist_to_interface
# Complex field decomposition (always present for Helmholtz)
+ # amplitude + phase direction (cos/sin ∈ [−1,1]), ε=1e-8 at |u|→0 nodes
feats["epsilon_r"] = lambda: self._epsilon_r_elements
feats["total_solution_magnitude"] = lambda: np.abs(self._complex_solution_mean)
+ feats["cos_phase"] = lambda: np.real(self._complex_solution_mean) / (np.abs(self._complex_solution_mean) + 1e-8)
+ feats["sin_phase"] = lambda: np.imag(self._complex_solution_mean) / (np.abs(self._complex_solution_mean) + 1e-8)
return feats
def reset(self) -> Data:
@@ -218,6 +221,8 @@ class MeshRefinement(gym.Env):
self._reward = 0
self._cumulative_return = 0
self._diag_selected_count = -1 # 防止跨 episode 残留触发 is_terminal
+ self._diag_dorfler_tail_ratio = 0.0
+ self._diag_dorfler_floor_active = False
# reset internal state that tracks statistics over the episode
self._previous_error_per_element = self.error_per_element
@@ -344,6 +349,8 @@ class MeshRefinement(gym.Env):
"eligible_ratio": getattr(self, "_diag_eligible_ratio", 0.0),
"masked_ratio": getattr(self, "_diag_masked_ratio", 0.0),
"selected_count": getattr(self, "_diag_selected_count", 0),
+ "dorfler_tail_ratio": getattr(self, "_diag_dorfler_tail_ratio", 0.0),
+ "dorfler_floor_active": float(getattr(self, "_diag_dorfler_floor_active", False)),
"n_budget": self._n_budget,
}
)
@@ -528,8 +535,9 @@ class MeshRefinement(gym.Env):
# 物理预算 N_budget: Σ area_K / A_budget,其中
# A_budget = ½(λ_local/6)²,对应每局部波长方向 ~6 个尺度点
#
- # 动作掩码 (Dörfler-P95): η_K < 0.05·η_P95 的单元移出候选池,
- # P95 锚定物理误差尺度,免疫远场噪声稀释,强制预算投入误差主导区
+ # 动作掩码 (Reverse Dörfler): 按 η_K 升序排列,剔除累积平方误差
+ # 贡献 < ε_noise·Ση² 的底部单元(数值噪声/已收敛区),保留 ≥20%
+ # 的单元确保 Agent 始终有充分的选择空间
# ================================================================
x = action.flatten()
@@ -542,6 +550,8 @@ class MeshRefinement(gym.Env):
if max_parents_by_budget <= 0:
self._diag_eligible_ratio = 0.0
self._diag_selected_count = 0
+ self._diag_dorfler_tail_ratio = 0.0
+ self._diag_dorfler_floor_active = False
return np.array([], dtype=np.int64)
# 动态计算每单元预算面积(仅用于 N_budget 全局资源上限)
@@ -559,13 +569,31 @@ class MeshRefinement(gym.Env):
# Filter 1: numerical safeguard only — no physics heuristic
area_eligible = np.where(self.element_volumes > V_min_safeguard)[0]
- # Filter 2: Dörfler-style action mask — exclude elements below 5% of η_P95
- # P95 anchors the threshold to physically meaningful error scale,
- # immune to far-field noise dilution (unlike median or mean).
- # η_K < 0.05·η_P95 → not worth the refinement budget.
+ # Filter 2: Reverse Dörfler — eliminate the noise tail, not select the elite.
+ # Sort η_K ascending; remove the smallest elements whose cumulative η²
+ # contributes < ε_noise of total error energy. These are numerically
+ # converged or noise — not worth the agent's attention.
+ # A 20% floor on the eligible ratio guarantees the agent meaningful
+ # choices even in heavy-tailed distributions where energy is concentrated.
eta_current = self._eta_indicator
- eta_p95 = np.percentile(eta_current, 95)
- error_eligible = np.where(eta_current >= 0.05 * eta_p95)[0]
+ eta_sq = eta_current ** 2
+ total_energy = np.sum(eta_sq)
+
+ if total_energy > 0:
+ idx_asc = np.argsort(eta_current) # ascending
+ cumsum_asc = np.cumsum(eta_sq[idx_asc])
+ eps_noise = 0.01 # bottom 1% of energy = noise tail
+ k_dorfler = int(np.searchsorted(cumsum_asc, eps_noise * total_energy))
+ self._diag_dorfler_tail_ratio = float(k_dorfler) / max(self._num_elements, 1)
+ # floor: keep at least 20% of elements for RL agent choice
+ min_keep = max(1, self._num_elements // 5)
+ k = min(k_dorfler, self._num_elements - min_keep)
+ self._diag_dorfler_floor_active = k < k_dorfler
+ error_eligible = idx_asc[k:]
+ else:
+ self._diag_dorfler_tail_ratio = 0.0
+ self._diag_dorfler_floor_active = False
+ error_eligible = np.arange(self._num_elements)
eligible = np.intersect1d(area_eligible, error_eligible)
@@ -687,6 +715,7 @@ class MeshRefinement(gym.Env):
graph_dict = graph_dict | self._get_graph_edges()
observation_graph = Data(**graph_dict)
+ observation_graph.eta = torch.tensor(self._eta_indicator, dtype=torch.float32)
return observation_graph
@@ -755,8 +784,16 @@ class MeshRefinement(gym.Env):
- self._element_midpoints[src_nodes],
axis=1,
)
- lam = 2.0 * np.pi / self._wave_number
- edge_features[:, edge_feature_position] = euclidean_distances / lam
+ # Phase distance: physical edge length in local wavelengths.
+ # k_local = k·√ε_r adapts to the medium — two elements are "farther
+ # apart" in phase inside high-ε regions where the wave oscillates
+ # faster. This gives the GNN a k-invariant metric for generalisation.
+ k_local_src = self._wave_number * np.sqrt(np.maximum(
+ self._epsilon_r_elements[src_nodes], 1.0))
+ k_local_dst = self._wave_number * np.sqrt(np.maximum(
+ self._epsilon_r_elements[dest_nodes], 1.0))
+ k_edge = np.sqrt(k_local_src * k_local_dst) # geometric mean
+ edge_features[:, edge_feature_position] = euclidean_distances * k_edge / (2.0 * np.pi)
edge_feature_position += 1
edge_index = torch.tensor(np.vstack((src_nodes, dest_nodes))).long()
edge_attr = torch.tensor(edge_features, dtype=torch.float32)
@@ -895,8 +932,30 @@ class MeshRefinement(gym.Env):
reward_per_agent = self.project_to_scalar(reward_per_agent_and_dim)
- # apply action/element penalty
+ # ── Causal isolation + bounded signals ──
+ # r_local: clipped to [−1, +1] — prevents pollution-error inversions
+ # (±4.6) from hijacking the Critic's value estimate.
+ # r_bonus: 0.5·tanh(η/μ − 1) — linear near μ (preserves Dörfler),
+ # saturates at ±0.5 for extreme η, bounded and safe.
+ # Unrefined parents: r = 0 (causal isolation).
unique_old, counts = np.unique(self.agent_mapping, return_counts=True)
+ refined_mask = np.zeros(len(reward_per_agent), dtype=bool)
+ refined_mask[unique_old[counts > 1]] = True
+
+ # Clip r_local to prevent outlier-driven value collapse
+ reward_per_agent = np.clip(reward_per_agent, -1.0, 1.0)
+
+ # Bounded state bonus: tanh preserves Dörfler near μ, caps at extreme η
+ eta_raw = self._previous_eta_indicator
+ mu_eta = float(np.mean(eta_raw))
+ reward_per_agent[refined_mask] += 0.5 * np.tanh(
+ eta_raw[refined_mask] / (mu_eta + 1e-8) - 1.0
+ )
+
+ # Unrefined: clean zero (causal isolation)
+ reward_per_agent[~refined_mask] = 0.0
+
+ # apply action/element penalty (refined parents only)
element_penalty = np.zeros(len(reward_per_agent), dtype=reward_per_agent.dtype)
element_penalty[unique_old] = self._element_penalty_lambda * (counts - 1)
element_limit_penalty = (
@@ -908,7 +967,12 @@ class MeshRefinement(gym.Env):
reward_per_agent - element_penalty - element_limit_penalty
)
- # ── Potential-based shaping: only refined parents get the global bonus ──
+ # ── Global error change (diagnostic only, NOT injected into Actor reward) ──
+ # Removing global_bonus from per-element reward eliminates the broken causal
+ # chain: Helmholtz pollution error can make E_new > E_old even when the
+ # selected elements were the right choice, punishing agents for physics
+ # they didn't cause. Actor optimises r_local only; Critic captures global
+ # effects through value estimation.
l2_old = self._previous_solution_l2_norm
l2_new = self._compute_solution_l2_norm()
eta_l2_old = float(np.sqrt(np.sum(old_eta ** 2)))
@@ -917,8 +981,7 @@ class MeshRefinement(gym.Env):
E_old = eta_l2_old / max(l2_old, eps_l2)
E_new = eta_l2_new / max(l2_new, eps_l2)
global_bonus = self._global_reward_alpha * float(np.log(E_old + eps_l2) - np.log(E_new + eps_l2))
- refined_parents = unique_old[counts > 1]
- reward_per_agent[refined_parents] += global_bonus
+ # global_bonus intentionally NOT added to reward_per_agent — see above.
self._reward_per_agent = reward_per_agent
self._cumulative_reward_per_agent = (
@@ -1087,7 +1150,7 @@ class MeshRefinement(gym.Env):
@property
def is_terminal(self) -> bool:
# Agent selected nothing to refine — budget exhausted or
- # Doerfler mask filtered everything. Episode converged naturally.
+ # Reverse Dörfler mask filtered everything. Episode converged naturally.
# -1 = not yet evaluated (reset state), 0 = nothing selected this step.
sc = getattr(self, "_diag_selected_count", -1)
if sc == 0:
diff --git a/git.txt b/git.txt
new file mode 100644
index 0000000..5fd114b
--- /dev/null
+++ b/git.txt
@@ -0,0 +1,8 @@
+linux服务器:scp -r dxw@222.20.97.222:/public/home/dxw/Codes/afem/* ./
+本机:git init
+ git branch -M main
+ git add .
+ git commit -m "first commit"
+ git remote set-url origin http://duxiaowei@222.20.97.33:3000/duxiaowei/afem.git
+ git remote -v(仅确认状态使用)
+ git push -u origin main
\ No newline at end of file
diff --git a/logs/before.out b/logs/before.out
new file mode 100644
index 0000000..81692b3
--- /dev/null
+++ b/logs/before.out
@@ -0,0 +1,418 @@
+Starting training at Thu 28 May 13:25:52 CST 2026
+Running on node: node06
+[Device] cuda
+[Env] node_feats=12 edge_feats=1 act_dim=1
+[Model] params=76,099
+ 1/401 | loss=0.8482 ev=0.001 agents=84 avg_r=-1.5801 sum_r=-404.50 x<0=0.09 elig=0.59 dorfler_tail=0.08 floor=0 sel=35 n_ref=0 r_loc=0.000 8.5s
+ 2/401 | loss=1.0257 ev=0.010 agents=48 avg_r=-2.2743 sum_r=-582.23 x<0=0.07 elig=0.60 dorfler_tail=0.07 floor=0 sel=39 n_ref=0 r_loc=0.000 8.3s
+ 3/401 | loss=0.6731 ev=0.019 agents=156 avg_r=-2.3457 sum_r=-600.50 x<0=0.07 elig=0.58 dorfler_tail=0.09 floor=0 sel=35 n_ref=0 r_loc=0.000 7.8s
+ 4/401 | loss=1.1435 ev=0.036 agents=246 avg_r=-3.6846 sum_r=-943.26 x<0=0.05 elig=0.59 dorfler_tail=0.07 floor=0 sel=36 n_ref=0 r_loc=0.000 7.9s
+ 5/401 | loss=0.6883 ev=0.056 agents=158 avg_r=-1.2686 sum_r=-324.77 x<0=0.05 elig=0.58 dorfler_tail=0.09 floor=0 sel=37 n_ref=0 r_loc=0.000 8.2s
+ 6/401 | loss=0.9416 ev=0.095 agents=142 avg_r=-0.0596 sum_r=-15.24 x<0=0.04 elig=0.59 dorfler_tail=0.07 floor=0 sel=36 n_ref=0 r_loc=0.000 8.2s
+ 7/401 | loss=0.7991 ev=0.105 agents=164 avg_r=-1.2996 sum_r=-332.70 x<0=0.03 elig=0.59 dorfler_tail=0.08 floor=0 sel=36 n_ref=0 r_loc=0.000 8.0s
+ 8/401 | loss=0.7861 ev=0.117 agents=133 avg_r=-0.4898 sum_r=-125.39 x<0=0.02 elig=0.59 dorfler_tail=0.08 floor=0 sel=36 n_ref=0 r_loc=0.000 7.9s
+ 9/401 | loss=0.7722 ev=0.141 agents=141 avg_r=-0.1621 sum_r=-41.50 x<0=0.02 elig=0.59 dorfler_tail=0.08 floor=0 sel=40 n_ref=0 r_loc=0.000 8.3s
+ 10/401 | loss=1.0415 ev=0.134 agents=87 avg_r=-2.4506 sum_r=-627.35 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+ 11/401 | loss=0.6847 ev=0.166 agents=138 avg_r=-0.4086 sum_r=-104.60 x<0=0.01 elig=0.59 dorfler_tail=0.08 floor=0 sel=37 n_ref=0 r_loc=0.000 8.0s
+ 12/401 | loss=0.6900 ev=0.146 agents=144 avg_r=1.5718 sum_r=402.39 x<0=0.01 elig=0.59 dorfler_tail=0.08 floor=0 sel=35 n_ref=0 r_loc=0.000 7.8s
+ 13/401 | loss=0.9037 ev=0.191 agents=158 avg_r=-1.9889 sum_r=-509.15 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.8s
+ 14/401 | loss=0.7577 ev=0.175 agents=175 avg_r=-1.0029 sum_r=-256.74 x<0=0.01 elig=0.59 dorfler_tail=0.08 floor=0 sel=36 n_ref=0 r_loc=0.000 7.8s
+ 15/401 | loss=0.6942 ev=0.208 agents=78 avg_r=-0.8006 sum_r=-204.95 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.9s
+ 16/401 | loss=0.8176 ev=0.205 agents=219 avg_r=1.1625 sum_r=297.59 x<0=0.01 elig=0.59 dorfler_tail=0.08 floor=0 sel=37 n_ref=0 r_loc=0.000 7.9s
+ 17/401 | loss=0.5844 ev=0.178 agents=66 avg_r=-0.4453 sum_r=-114.01 x<0=0.00 elig=0.59 dorfler_tail=0.08 floor=0 sel=35 n_ref=0 r_loc=0.000 7.8s
+ 18/401 | loss=0.9272 ev=0.198 agents=244 avg_r=-2.4742 sum_r=-633.40 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.8s
+ 19/401 | loss=0.6133 ev=0.215 agents=34 avg_r=-1.0759 sum_r=-275.42 x<0=0.01 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 n_ref=0 r_loc=0.000 7.6s
+ 20/401 | loss=0.7286 ev=0.260 agents=86 avg_r=2.3332 sum_r=597.30 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=37 n_ref=0 r_loc=0.000 7.9s
+ 21/401 | loss=0.6750 ev=0.250 agents=102 avg_r=-0.5468 sum_r=-139.98 x<0=0.01 elig=0.59 dorfler_tail=0.08 floor=0 sel=36 n_ref=0 r_loc=0.000 7.8s
+ 22/401 | loss=0.6968 ev=0.188 agents=133 avg_r=-0.2165 sum_r=-55.43 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.6s
+ 23/401 | loss=0.6547 ev=0.251 agents=142 avg_r=0.7932 sum_r=203.07 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.6s
+ 24/401 | loss=0.7206 ev=0.221 agents=82 avg_r=-0.2919 sum_r=-74.74 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.7s
+ 25/401 | loss=0.6633 ev=0.305 agents=235 avg_r=1.9655 sum_r=503.16 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=37 n_ref=0 r_loc=0.000 7.8s
+ 26/401 | loss=0.7285 ev=0.215 agents=235 avg_r=-0.9946 sum_r=-254.60 x<0=0.00 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 27/401 | loss=0.6501 ev=0.264 agents=75 avg_r=-1.4324 sum_r=-366.69 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.6s
+ 28/401 | loss=0.5842 ev=0.262 agents=34 avg_r=0.2413 sum_r=61.77 x<0=0.01 elig=0.59 dorfler_tail=0.08 floor=0 sel=36 n_ref=0 r_loc=0.000 7.7s
+ 29/401 | loss=0.7681 ev=0.295 agents=133 avg_r=0.3315 sum_r=84.86 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.9s
+ 30/401 | loss=0.8179 ev=0.292 agents=133 avg_r=0.4571 sum_r=117.01 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=37 n_ref=0 r_loc=0.000 8.3s
+ 31/401 | loss=0.6542 ev=0.232 agents=131 avg_r=1.6268 sum_r=416.47 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.7s
+ 32/401 | loss=0.5766 ev=0.204 agents=195 avg_r=-0.2509 sum_r=-64.23 x<0=0.02 elig=0.59 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.7s
+ 33/401 | loss=0.6403 ev=0.237 agents=48 avg_r=3.0437 sum_r=779.18 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.6s
+ 34/401 | loss=0.7453 ev=0.291 agents=66 avg_r=-0.5863 sum_r=-150.09 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.6s
+ 35/401 | loss=0.6467 ev=0.303 agents=138 avg_r=1.6192 sum_r=414.51 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.7s
+ 36/401 | loss=0.6302 ev=0.289 agents=64 avg_r=1.1951 sum_r=305.96 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.7s
+ 37/401 | loss=0.7351 ev=0.301 agents=34 avg_r=-0.3947 sum_r=-101.03 x<0=0.01 elig=0.60 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.6s
+ 38/401 | loss=0.6007 ev=0.312 agents=246 avg_r=0.4709 sum_r=120.55 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.6s
+ 39/401 | loss=0.6316 ev=0.318 agents=138 avg_r=1.0463 sum_r=267.85 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.6s
+ 40/401 | loss=0.6016 ev=0.143 agents=34 avg_r=1.0658 sum_r=272.85 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+ 41/401 | loss=0.7033 ev=0.306 agents=60 avg_r=3.5062 sum_r=897.59 x<0=0.01 elig=0.60 dorfler_tail=0.06 floor=0 sel=37 n_ref=0 r_loc=0.000 7.8s
+ 42/401 | loss=0.5702 ev=0.268 agents=175 avg_r=-0.2759 sum_r=-70.64 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+ 43/401 | loss=0.5907 ev=0.324 agents=247 avg_r=0.7705 sum_r=197.25 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+ 44/401 | loss=0.6398 ev=0.306 agents=48 avg_r=1.4337 sum_r=367.03 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.6s
+ 45/401 | loss=0.6173 ev=0.266 agents=34 avg_r=0.4788 sum_r=122.56 x<0=0.00 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.7s
+ 46/401 | loss=0.5942 ev=0.262 agents=244 avg_r=0.2944 sum_r=75.38 x<0=0.01 elig=0.60 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 47/401 | loss=0.6930 ev=0.312 agents=86 avg_r=2.0645 sum_r=528.51 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.8s
+ 48/401 | loss=0.6166 ev=0.265 agents=242 avg_r=-1.3247 sum_r=-339.13 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+ 49/401 | loss=0.6950 ev=0.281 agents=76 avg_r=0.5565 sum_r=142.46 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 50/401 | loss=0.5718 ev=0.306 agents=280 avg_r=1.5020 sum_r=384.52 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+[Checkpoint] saved → checkpoints/model_iter0050.pt
+ 51/401 | loss=0.5765 ev=0.337 agents=48 avg_r=1.0395 sum_r=266.11 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 52/401 | loss=0.7324 ev=0.326 agents=34 avg_r=-0.5879 sum_r=-150.50 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 8.1s
+ 53/401 | loss=0.6879 ev=0.195 agents=133 avg_r=0.2283 sum_r=58.44 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.9s
+ 54/401 | loss=0.5093 ev=0.354 agents=34 avg_r=3.4100 sum_r=872.97 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.6s
+ 55/401 | loss=0.5717 ev=0.241 agents=76 avg_r=0.1396 sum_r=35.73 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 56/401 | loss=0.6966 ev=0.329 agents=55 avg_r=1.8220 sum_r=466.43 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.7s
+ 57/401 | loss=0.6618 ev=0.271 agents=53 avg_r=0.1718 sum_r=43.99 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 58/401 | loss=0.7686 ev=0.308 agents=34 avg_r=-0.3162 sum_r=-80.94 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+ 59/401 | loss=0.6369 ev=0.282 agents=34 avg_r=1.1943 sum_r=305.74 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.7s
+ 60/401 | loss=0.5711 ev=0.316 agents=78 avg_r=0.4311 sum_r=110.36 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 61/401 | loss=0.6055 ev=0.243 agents=141 avg_r=0.7018 sum_r=179.65 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.6s
+ 62/401 | loss=0.5890 ev=0.320 agents=161 avg_r=2.4707 sum_r=632.49 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 63/401 | loss=0.7483 ev=0.299 agents=94 avg_r=-0.1036 sum_r=-26.52 x<0=0.02 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+ 64/401 | loss=0.5846 ev=0.308 agents=142 avg_r=2.2134 sum_r=566.62 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.6s
+ 65/401 | loss=0.6235 ev=0.310 agents=34 avg_r=0.3583 sum_r=91.72 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+ 66/401 | loss=0.7279 ev=0.340 agents=242 avg_r=0.8842 sum_r=226.36 x<0=0.03 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 67/401 | loss=0.6277 ev=0.276 agents=66 avg_r=-0.6905 sum_r=-176.76 x<0=0.04 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 68/401 | loss=0.4957 ev=0.312 agents=155 avg_r=1.7990 sum_r=460.54 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 69/401 | loss=0.6134 ev=0.315 agents=193 avg_r=0.1199 sum_r=30.69 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 70/401 | loss=0.6138 ev=0.320 agents=55 avg_r=-0.0142 sum_r=-3.63 x<0=0.04 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.5s
+ 71/401 | loss=0.7342 ev=0.334 agents=123 avg_r=1.7634 sum_r=451.42 x<0=0.05 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 72/401 | loss=0.6063 ev=0.314 agents=75 avg_r=0.6803 sum_r=174.15 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 73/401 | loss=0.5994 ev=0.304 agents=66 avg_r=0.3545 sum_r=90.76 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.5s
+ 74/401 | loss=0.6456 ev=0.337 agents=155 avg_r=0.7796 sum_r=199.57 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 75/401 | loss=0.7205 ev=0.282 agents=34 avg_r=-1.2208 sum_r=-312.52 x<0=0.05 elig=0.60 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+ 76/401 | loss=0.6423 ev=0.301 agents=133 avg_r=-0.0014 sum_r=-0.35 x<0=0.05 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 8.1s
+ 77/401 | loss=0.5801 ev=0.316 agents=34 avg_r=0.9398 sum_r=240.59 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.6s
+ 78/401 | loss=0.8439 ev=0.291 agents=161 avg_r=0.5240 sum_r=134.15 x<0=0.07 elig=0.60 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 79/401 | loss=0.5819 ev=0.342 agents=224 avg_r=0.4114 sum_r=105.33 x<0=0.07 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.6s
+ 80/401 | loss=0.6512 ev=0.300 agents=193 avg_r=-1.0909 sum_r=-279.28 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 81/401 | loss=0.7695 ev=0.337 agents=87 avg_r=1.4936 sum_r=382.37 x<0=0.10 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 82/401 | loss=0.4945 ev=0.261 agents=103 avg_r=0.7102 sum_r=181.81 x<0=0.09 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.2s
+ 83/401 | loss=0.6859 ev=0.345 agents=34 avg_r=1.0995 sum_r=281.47 x<0=0.16 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.6s
+ 84/401 | loss=0.6656 ev=0.273 agents=111 avg_r=2.1667 sum_r=554.67 x<0=0.18 elig=0.60 dorfler_tail=0.07 floor=0 sel=36 n_ref=0 r_loc=0.000 7.6s
+ 85/401 | loss=0.6877 ev=0.281 agents=85 avg_r=-1.2801 sum_r=-327.71 x<0=0.17 elig=0.60 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 86/401 | loss=0.6557 ev=0.299 agents=174 avg_r=1.0104 sum_r=258.67 x<0=0.18 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 87/401 | loss=0.6198 ev=0.312 agents=158 avg_r=0.2309 sum_r=59.11 x<0=0.17 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 88/401 | loss=0.6287 ev=0.358 agents=48 avg_r=1.5747 sum_r=403.13 x<0=0.17 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 89/401 | loss=0.6695 ev=0.294 agents=34 avg_r=1.2450 sum_r=318.72 x<0=0.20 elig=0.60 dorfler_tail=0.07 floor=0 sel=36 n_ref=0 r_loc=0.000 7.7s
+ 90/401 | loss=0.6368 ev=0.292 agents=34 avg_r=-1.0354 sum_r=-265.05 x<0=0.20 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.1s
+ 91/401 | loss=0.5655 ev=0.267 agents=542 avg_r=1.3067 sum_r=334.51 x<0=0.23 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.6s
+ 92/401 | loss=0.7495 ev=0.331 agents=584 avg_r=-0.3680 sum_r=-94.22 x<0=0.23 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 93/401 | loss=0.6225 ev=0.292 agents=343 avg_r=-1.3500 sum_r=-345.59 x<0=0.24 elig=0.61 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 94/401 | loss=0.6050 ev=0.324 agents=360 avg_r=1.3880 sum_r=355.33 x<0=0.24 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.4s
+ 95/401 | loss=0.6482 ev=0.322 agents=142 avg_r=-0.5954 sum_r=-152.42 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 96/401 | loss=0.5924 ev=0.338 agents=258 avg_r=0.4584 sum_r=117.36 x<0=0.23 elig=0.60 dorfler_tail=0.07 floor=0 sel=36 n_ref=0 r_loc=0.000 7.6s
+ 97/401 | loss=0.6026 ev=0.267 agents=133 avg_r=-0.5686 sum_r=-145.57 x<0=0.24 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.0s
+ 98/401 | loss=0.7563 ev=0.356 agents=665 avg_r=-0.4694 sum_r=-120.17 x<0=0.24 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 99/401 | loss=0.5980 ev=0.296 agents=899 avg_r=1.6428 sum_r=420.56 x<0=0.25 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.7s
+ 100/401 | loss=0.6262 ev=0.318 agents=34 avg_r=-1.1789 sum_r=-301.80 x<0=0.25 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.7s
+[Checkpoint] saved → checkpoints/model_iter0100.pt
+ 101/401 | loss=0.6111 ev=0.312 agents=87 avg_r=-1.0703 sum_r=-274.00 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+ 102/401 | loss=0.6306 ev=0.317 agents=1082 avg_r=2.7796 sum_r=711.58 x<0=0.26 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.5s
+ 103/401 | loss=0.8435 ev=0.283 agents=491 avg_r=-1.3251 sum_r=-339.23 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=34 n_ref=0 r_loc=0.000 7.4s
+ 104/401 | loss=0.6451 ev=0.303 agents=161 avg_r=-2.2744 sum_r=-582.24 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 105/401 | loss=0.6049 ev=0.339 agents=826 avg_r=2.9649 sum_r=759.02 x<0=0.27 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.5s
+ 106/401 | loss=0.6847 ev=0.265 agents=294 avg_r=-3.5720 sum_r=-914.44 x<0=0.27 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 107/401 | loss=0.6118 ev=0.322 agents=188 avg_r=0.9259 sum_r=237.02 x<0=0.27 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 108/401 | loss=0.6254 ev=0.318 agents=349 avg_r=-0.1577 sum_r=-40.38 x<0=0.28 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.5s
+ 109/401 | loss=0.6404 ev=0.344 agents=73 avg_r=0.0348 sum_r=8.91 x<0=0.28 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 110/401 | loss=0.5885 ev=0.342 agents=158 avg_r=0.2726 sum_r=69.79 x<0=0.28 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 111/401 | loss=0.5346 ev=0.361 agents=242 avg_r=0.6142 sum_r=157.23 x<0=0.29 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.5s
+ 112/401 | loss=0.7332 ev=0.326 agents=174 avg_r=-0.6867 sum_r=-175.79 x<0=0.28 elig=0.60 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 113/401 | loss=0.6006 ev=0.370 agents=224 avg_r=0.9889 sum_r=253.17 x<0=0.28 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 114/401 | loss=0.6385 ev=0.329 agents=219 avg_r=-0.5056 sum_r=-129.44 x<0=0.27 elig=0.60 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 115/401 | loss=0.6192 ev=0.354 agents=34 avg_r=0.2074 sum_r=53.10 x<0=0.27 elig=0.60 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 116/401 | loss=0.5917 ev=0.337 agents=48 avg_r=1.4759 sum_r=377.84 x<0=0.28 elig=0.60 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 117/401 | loss=0.7783 ev=0.327 agents=34 avg_r=-1.4926 sum_r=-382.10 x<0=0.27 elig=0.60 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 118/401 | loss=0.6173 ev=0.311 agents=174 avg_r=0.8320 sum_r=212.99 x<0=0.29 elig=0.60 dorfler_tail=0.07 floor=0 sel=36 n_ref=0 r_loc=0.000 7.6s
+ 119/401 | loss=0.5288 ev=0.320 agents=131 avg_r=-0.1760 sum_r=-45.05 x<0=0.28 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.1s
+ 120/401 | loss=0.7693 ev=0.368 agents=223 avg_r=-0.4147 sum_r=-106.15 x<0=0.27 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+ 121/401 | loss=0.6487 ev=0.256 agents=131 avg_r=1.0145 sum_r=259.72 x<0=0.28 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 122/401 | loss=0.6790 ev=0.367 agents=34 avg_r=-1.4039 sum_r=-359.39 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.8s
+ 123/401 | loss=0.5770 ev=0.275 agents=252 avg_r=3.0782 sum_r=788.02 x<0=0.25 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.7s
+ 124/401 | loss=0.7664 ev=0.367 agents=403 avg_r=-1.8521 sum_r=-474.14 x<0=0.24 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.4s
+ 125/401 | loss=0.5949 ev=0.260 agents=620 avg_r=-0.5130 sum_r=-131.34 x<0=0.25 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 126/401 | loss=0.6167 ev=0.382 agents=1119 avg_r=0.2129 sum_r=54.51 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+ 127/401 | loss=0.5372 ev=0.346 agents=1267 avg_r=1.6754 sum_r=428.90 x<0=0.24 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 128/401 | loss=0.7640 ev=0.335 agents=273 avg_r=0.4446 sum_r=113.82 x<0=0.23 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+ 129/401 | loss=0.5504 ev=0.270 agents=1254 avg_r=-0.8846 sum_r=-226.47 x<0=0.24 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 130/401 | loss=0.5687 ev=0.387 agents=111 avg_r=0.7564 sum_r=193.63 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 131/401 | loss=0.7015 ev=0.301 agents=34 avg_r=-1.3658 sum_r=-349.63 x<0=0.22 elig=0.60 dorfler_tail=0.06 floor=0 sel=34 n_ref=0 r_loc=0.000 7.5s
+ 132/401 | loss=0.6005 ev=0.384 agents=204 avg_r=2.4500 sum_r=627.21 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 133/401 | loss=0.5434 ev=0.325 agents=526 avg_r=0.8884 sum_r=227.42 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 134/401 | loss=0.5892 ev=0.354 agents=34 avg_r=-0.7723 sum_r=-197.70 x<0=0.21 elig=0.60 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 135/401 | loss=0.5742 ev=0.352 agents=190 avg_r=0.4945 sum_r=126.58 x<0=0.22 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 136/401 | loss=0.5433 ev=0.369 agents=82 avg_r=1.3959 sum_r=357.34 x<0=0.22 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 137/401 | loss=0.6962 ev=0.361 agents=419 avg_r=1.1219 sum_r=287.20 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 138/401 | loss=0.5333 ev=0.347 agents=320 avg_r=-0.8777 sum_r=-224.69 x<0=0.20 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 139/401 | loss=0.6291 ev=0.393 agents=89 avg_r=-2.0054 sum_r=-513.38 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 140/401 | loss=0.5229 ev=0.277 agents=556 avg_r=1.0066 sum_r=257.69 x<0=0.20 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.1s
+ 141/401 | loss=0.7257 ev=0.369 agents=301 avg_r=1.0365 sum_r=265.35 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 142/401 | loss=0.5885 ev=0.356 agents=344 avg_r=0.2587 sum_r=66.23 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 143/401 | loss=0.6219 ev=0.407 agents=66 avg_r=-0.0013 sum_r=-0.34 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.2s
+ 144/401 | loss=0.6111 ev=0.349 agents=429 avg_r=0.7761 sum_r=198.68 x<0=0.23 elig=0.61 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.6s
+ 145/401 | loss=0.4913 ev=0.237 agents=34 avg_r=-1.9325 sum_r=-494.72 x<0=0.20 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 n_ref=0 r_loc=0.000 6.9s
+ 146/401 | loss=0.6959 ev=0.388 agents=151 avg_r=0.5241 sum_r=134.16 x<0=0.23 elig=0.61 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.4s
+ 147/401 | loss=0.5916 ev=0.367 agents=226 avg_r=1.0964 sum_r=280.67 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.7s
+ 148/401 | loss=0.6063 ev=0.321 agents=549 avg_r=-1.3176 sum_r=-337.29 x<0=0.22 elig=0.60 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.4s
+ 149/401 | loss=0.5880 ev=0.369 agents=144 avg_r=-0.5012 sum_r=-128.32 x<0=0.23 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 150/401 | loss=0.7330 ev=0.336 agents=93 avg_r=-0.9342 sum_r=-239.16 x<0=0.20 elig=0.62 dorfler_tail=0.06 floor=0 sel=28 n_ref=0 r_loc=0.000 7.1s
+[Checkpoint] saved → checkpoints/model_iter0150.pt
+ 151/401 | loss=0.5344 ev=0.326 agents=232 avg_r=0.5301 sum_r=135.71 x<0=0.23 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.5s
+ 152/401 | loss=0.4994 ev=0.361 agents=76 avg_r=1.3224 sum_r=338.52 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 153/401 | loss=0.7887 ev=0.381 agents=165 avg_r=-1.4365 sum_r=-367.74 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 154/401 | loss=0.5708 ev=0.353 agents=227 avg_r=0.6867 sum_r=175.79 x<0=0.22 elig=0.61 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.5s
+ 155/401 | loss=0.5476 ev=0.372 agents=184 avg_r=-0.1764 sum_r=-45.17 x<0=0.20 elig=0.60 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 156/401 | loss=0.5947 ev=0.350 agents=296 avg_r=-0.1529 sum_r=-39.15 x<0=0.21 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 157/401 | loss=0.5219 ev=0.399 agents=66 avg_r=0.6051 sum_r=154.90 x<0=0.21 elig=0.60 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 158/401 | loss=0.6396 ev=0.393 agents=34 avg_r=0.4283 sum_r=109.63 x<0=0.19 elig=0.61 dorfler_tail=0.06 floor=0 sel=29 n_ref=0 r_loc=0.000 7.1s
+ 159/401 | loss=0.5693 ev=0.382 agents=805 avg_r=1.2933 sum_r=331.08 x<0=0.21 elig=0.60 dorfler_tail=0.06 floor=0 sel=34 n_ref=0 r_loc=0.000 7.4s
+ 160/401 | loss=0.5833 ev=0.338 agents=84 avg_r=-1.8923 sum_r=-484.43 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 161/401 | loss=0.5746 ev=0.340 agents=549 avg_r=-0.2881 sum_r=-73.75 x<0=0.23 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.4s
+ 162/401 | loss=0.6617 ev=0.402 agents=144 avg_r=-0.0799 sum_r=-20.45 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 163/401 | loss=0.5360 ev=0.314 agents=87 avg_r=0.4493 sum_r=115.02 x<0=0.24 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 164/401 | loss=0.5845 ev=0.329 agents=1107 avg_r=-1.3259 sum_r=-339.43 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 165/401 | loss=0.5861 ev=0.369 agents=340 avg_r=-1.7656 sum_r=-452.00 x<0=0.24 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 166/401 | loss=0.5568 ev=0.429 agents=142 avg_r=2.4693 sum_r=632.13 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 167/401 | loss=0.6408 ev=0.325 agents=235 avg_r=-1.4679 sum_r=-375.77 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 168/401 | loss=0.5684 ev=0.360 agents=81 avg_r=-0.1609 sum_r=-41.19 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 169/401 | loss=0.6655 ev=0.398 agents=1068 avg_r=-0.0692 sum_r=-17.71 x<0=0.25 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.6s
+ 170/401 | loss=0.5322 ev=0.278 agents=219 avg_r=-0.4841 sum_r=-123.92 x<0=0.25 elig=0.62 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.8s
+ 171/401 | loss=0.5651 ev=0.348 agents=175 avg_r=-0.9866 sum_r=-252.57 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.3s
+ 172/401 | loss=0.6972 ev=0.365 agents=200 avg_r=-1.4787 sum_r=-378.56 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 173/401 | loss=0.5219 ev=0.333 agents=75 avg_r=0.9503 sum_r=243.28 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.2s
+ 174/401 | loss=0.7200 ev=0.356 agents=198 avg_r=-1.1237 sum_r=-287.66 x<0=0.27 elig=0.61 dorfler_tail=0.06 floor=0 sel=34 n_ref=0 r_loc=0.000 7.7s
+ 175/401 | loss=0.5611 ev=0.380 agents=518 avg_r=0.1212 sum_r=31.02 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 176/401 | loss=0.6726 ev=0.400 agents=100 avg_r=0.6386 sum_r=163.47 x<0=0.25 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 177/401 | loss=0.4632 ev=0.317 agents=526 avg_r=0.1369 sum_r=35.05 x<0=0.25 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 178/401 | loss=0.6494 ev=0.344 agents=220 avg_r=-2.4843 sum_r=-635.98 x<0=0.24 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 179/401 | loss=0.5324 ev=0.361 agents=726 avg_r=-0.2240 sum_r=-57.34 x<0=0.25 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 180/401 | loss=0.6761 ev=0.413 agents=34 avg_r=-0.8163 sum_r=-208.97 x<0=0.23 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 181/401 | loss=0.5574 ev=0.348 agents=60 avg_r=-0.3088 sum_r=-79.05 x<0=0.23 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 182/401 | loss=0.5345 ev=0.374 agents=972 avg_r=-0.4068 sum_r=-104.14 x<0=0.24 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 183/401 | loss=0.5651 ev=0.371 agents=100 avg_r=0.0724 sum_r=18.54 x<0=0.22 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.2s
+ 184/401 | loss=0.7592 ev=0.345 agents=72 avg_r=-1.9106 sum_r=-489.12 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 185/401 | loss=0.5137 ev=0.370 agents=436 avg_r=1.2368 sum_r=316.62 x<0=0.22 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 186/401 | loss=0.5665 ev=0.383 agents=133 avg_r=-1.6560 sum_r=-423.93 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 187/401 | loss=0.5679 ev=0.411 agents=34 avg_r=-0.2303 sum_r=-58.95 x<0=0.21 elig=0.60 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.1s
+ 188/401 | loss=0.5255 ev=0.342 agents=140 avg_r=0.6738 sum_r=172.49 x<0=0.22 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 189/401 | loss=0.5645 ev=0.376 agents=898 avg_r=0.3043 sum_r=77.89 x<0=0.21 elig=0.60 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 190/401 | loss=0.5262 ev=0.374 agents=434 avg_r=0.1856 sum_r=47.52 x<0=0.22 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 191/401 | loss=0.5633 ev=0.367 agents=429 avg_r=0.6451 sum_r=165.14 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 192/401 | loss=0.7072 ev=0.389 agents=406 avg_r=-2.2003 sum_r=-563.27 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.8s
+ 193/401 | loss=0.5323 ev=0.409 agents=337 avg_r=1.1695 sum_r=299.39 x<0=0.21 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.6s
+ 194/401 | loss=0.6203 ev=0.342 agents=156 avg_r=-1.8071 sum_r=-462.63 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.3s
+ 195/401 | loss=0.5161 ev=0.402 agents=85 avg_r=-0.4427 sum_r=-113.34 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+ 196/401 | loss=0.6093 ev=0.379 agents=379 avg_r=-0.8613 sum_r=-220.49 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 197/401 | loss=0.6390 ev=0.417 agents=176 avg_r=-0.0713 sum_r=-18.26 x<0=0.22 elig=0.61 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 198/401 | loss=0.5660 ev=0.373 agents=387 avg_r=-1.3506 sum_r=-345.76 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 199/401 | loss=0.4968 ev=0.332 agents=139 avg_r=-0.6881 sum_r=-176.16 x<0=0.23 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 200/401 | loss=0.5646 ev=0.403 agents=539 avg_r=1.6537 sum_r=423.34 x<0=0.24 elig=0.60 dorfler_tail=0.07 floor=0 sel=35 n_ref=0 r_loc=0.000 7.5s
+[Checkpoint] saved → checkpoints/model_iter0200.pt
+ 201/401 | loss=0.5881 ev=0.359 agents=158 avg_r=-0.6809 sum_r=-174.32 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 202/401 | loss=0.5527 ev=0.373 agents=86 avg_r=0.5753 sum_r=147.28 x<0=0.23 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 203/401 | loss=0.6413 ev=0.392 agents=824 avg_r=0.1860 sum_r=47.62 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 204/401 | loss=0.5117 ev=0.341 agents=198 avg_r=-0.4617 sum_r=-118.20 x<0=0.22 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 205/401 | loss=0.6845 ev=0.402 agents=53 avg_r=-2.0145 sum_r=-515.71 x<0=0.23 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 206/401 | loss=0.4670 ev=0.339 agents=133 avg_r=0.5982 sum_r=153.13 x<0=0.21 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 n_ref=0 r_loc=0.000 7.0s
+ 207/401 | loss=0.5664 ev=0.369 agents=1222 avg_r=0.9834 sum_r=251.75 x<0=0.23 elig=0.60 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.4s
+ 208/401 | loss=0.6963 ev=0.385 agents=80 avg_r=-2.0704 sum_r=-530.03 x<0=0.19 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 209/401 | loss=0.5655 ev=0.367 agents=563 avg_r=1.0998 sum_r=281.55 x<0=0.21 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 210/401 | loss=0.5638 ev=0.385 agents=736 avg_r=-0.6709 sum_r=-171.76 x<0=0.19 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 211/401 | loss=0.4561 ev=0.421 agents=1554 avg_r=0.3749 sum_r=95.98 x<0=0.19 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 212/401 | loss=0.7065 ev=0.398 agents=34 avg_r=0.3088 sum_r=79.06 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 213/401 | loss=0.5221 ev=0.311 agents=34 avg_r=-3.9111 sum_r=-1001.24 x<0=0.21 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.1s
+ 214/401 | loss=0.6268 ev=0.406 agents=207 avg_r=0.6081 sum_r=155.67 x<0=0.20 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.1s
+ 215/401 | loss=0.6910 ev=0.417 agents=161 avg_r=-0.4418 sum_r=-113.09 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.6s
+ 216/401 | loss=0.5559 ev=0.355 agents=300 avg_r=-0.1959 sum_r=-50.14 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 217/401 | loss=0.5544 ev=0.384 agents=133 avg_r=-2.2292 sum_r=-570.67 x<0=0.20 elig=0.60 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 218/401 | loss=0.5503 ev=0.386 agents=1380 avg_r=0.2610 sum_r=66.83 x<0=0.22 elig=0.61 dorfler_tail=0.07 floor=0 sel=36 n_ref=0 r_loc=0.000 7.7s
+ 219/401 | loss=0.5591 ev=0.380 agents=441 avg_r=-1.7828 sum_r=-456.41 x<0=0.19 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 n_ref=0 r_loc=0.000 7.0s
+ 220/401 | loss=0.6269 ev=0.447 agents=337 avg_r=0.6625 sum_r=169.59 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 221/401 | loss=0.5442 ev=0.337 agents=48 avg_r=0.6702 sum_r=171.58 x<0=0.22 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 222/401 | loss=0.5796 ev=0.373 agents=209 avg_r=-0.7158 sum_r=-183.25 x<0=0.22 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 223/401 | loss=0.5371 ev=0.400 agents=328 avg_r=-0.1674 sum_r=-42.86 x<0=0.21 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.0s
+ 224/401 | loss=0.6295 ev=0.416 agents=121 avg_r=-0.6457 sum_r=-165.30 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 225/401 | loss=0.4862 ev=0.367 agents=244 avg_r=1.1177 sum_r=286.12 x<0=0.23 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 226/401 | loss=0.5710 ev=0.360 agents=175 avg_r=-0.2754 sum_r=-70.49 x<0=0.23 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 227/401 | loss=0.5945 ev=0.353 agents=34 avg_r=-3.3050 sum_r=-846.07 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 228/401 | loss=0.6549 ev=0.416 agents=159 avg_r=-0.3421 sum_r=-87.59 x<0=0.21 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 229/401 | loss=0.5569 ev=0.402 agents=142 avg_r=0.4867 sum_r=124.59 x<0=0.20 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 230/401 | loss=0.6834 ev=0.416 agents=432 avg_r=-1.3377 sum_r=-342.44 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 231/401 | loss=0.5048 ev=0.346 agents=299 avg_r=-0.3187 sum_r=-81.60 x<0=0.22 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 232/401 | loss=0.7049 ev=0.413 agents=78 avg_r=-0.6128 sum_r=-156.89 x<0=0.22 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 233/401 | loss=0.4813 ev=0.343 agents=36 avg_r=0.3085 sum_r=78.97 x<0=0.21 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 n_ref=0 r_loc=0.000 6.9s
+ 234/401 | loss=0.5862 ev=0.354 agents=333 avg_r=1.7158 sum_r=439.25 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.5s
+ 235/401 | loss=0.6787 ev=0.397 agents=34 avg_r=-1.9337 sum_r=-495.01 x<0=0.24 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 236/401 | loss=0.5569 ev=0.399 agents=193 avg_r=-0.9097 sum_r=-232.89 x<0=0.23 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 237/401 | loss=0.5414 ev=0.393 agents=103 avg_r=-1.4208 sum_r=-363.73 x<0=0.25 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.1s
+ 238/401 | loss=0.5549 ev=0.372 agents=48 avg_r=-1.0300 sum_r=-263.67 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+ 239/401 | loss=0.6030 ev=0.435 agents=896 avg_r=-0.1038 sum_r=-26.56 x<0=0.24 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.5s
+ 240/401 | loss=0.5383 ev=0.320 agents=48 avg_r=0.5485 sum_r=140.41 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 241/401 | loss=0.6044 ev=0.427 agents=370 avg_r=-0.7533 sum_r=-192.84 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.7s
+ 242/401 | loss=0.5599 ev=0.372 agents=236 avg_r=-1.5351 sum_r=-392.98 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 243/401 | loss=0.5583 ev=0.395 agents=153 avg_r=-1.1731 sum_r=-300.30 x<0=0.28 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+ 244/401 | loss=0.5860 ev=0.384 agents=1091 avg_r=-1.3456 sum_r=-344.48 x<0=0.27 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 245/401 | loss=0.5337 ev=0.377 agents=1349 avg_r=2.2382 sum_r=572.98 x<0=0.28 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 246/401 | loss=0.6395 ev=0.356 agents=851 avg_r=-3.1663 sum_r=-810.58 x<0=0.27 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 247/401 | loss=0.5909 ev=0.428 agents=671 avg_r=3.1579 sum_r=808.42 x<0=0.27 elig=0.61 dorfler_tail=0.06 floor=0 sel=34 n_ref=0 r_loc=0.000 7.5s
+ 248/401 | loss=0.5679 ev=0.362 agents=219 avg_r=-4.4722 sum_r=-1144.88 x<0=0.27 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.0s
+ 249/401 | loss=0.4965 ev=0.384 agents=112 avg_r=-1.7098 sum_r=-437.70 x<0=0.28 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 250/401 | loss=0.5453 ev=0.411 agents=185 avg_r=0.6639 sum_r=169.96 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+[Checkpoint] saved → checkpoints/model_iter0250.pt
+ 251/401 | loss=0.6922 ev=0.377 agents=488 avg_r=-1.7138 sum_r=-438.73 x<0=0.27 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 252/401 | loss=0.5444 ev=0.395 agents=193 avg_r=0.3247 sum_r=83.11 x<0=0.28 elig=0.61 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.4s
+ 253/401 | loss=0.5359 ev=0.388 agents=159 avg_r=-1.5650 sum_r=-400.65 x<0=0.27 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 254/401 | loss=0.5134 ev=0.401 agents=217 avg_r=-0.0328 sum_r=-8.39 x<0=0.27 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 255/401 | loss=0.5651 ev=0.395 agents=428 avg_r=0.4327 sum_r=110.77 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 256/401 | loss=0.5563 ev=0.385 agents=497 avg_r=-0.7435 sum_r=-190.33 x<0=0.27 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 257/401 | loss=0.6860 ev=0.371 agents=34 avg_r=-0.7764 sum_r=-198.75 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 258/401 | loss=0.5434 ev=0.422 agents=1102 avg_r=-0.7016 sum_r=-179.60 x<0=0.27 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.1s
+ 259/401 | loss=0.5401 ev=0.403 agents=526 avg_r=-0.7190 sum_r=-184.06 x<0=0.28 elig=0.61 dorfler_tail=0.06 floor=0 sel=35 n_ref=0 r_loc=0.000 7.5s
+ 260/401 | loss=0.5250 ev=0.369 agents=128 avg_r=-0.4536 sum_r=-116.13 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.0s
+ 261/401 | loss=0.5151 ev=0.353 agents=293 avg_r=-0.9870 sum_r=-252.66 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.5s
+ 262/401 | loss=0.6481 ev=0.430 agents=305 avg_r=-0.2456 sum_r=-62.88 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.6s
+ 263/401 | loss=0.5681 ev=0.403 agents=224 avg_r=0.3445 sum_r=88.20 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 264/401 | loss=0.5175 ev=0.407 agents=112 avg_r=-0.2865 sum_r=-73.34 x<0=0.26 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 265/401 | loss=0.6772 ev=0.411 agents=379 avg_r=-2.6835 sum_r=-686.99 x<0=0.25 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 266/401 | loss=0.5117 ev=0.337 agents=529 avg_r=1.9509 sum_r=499.44 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 267/401 | loss=0.6832 ev=0.418 agents=34 avg_r=-2.7091 sum_r=-693.54 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.2s
+ 268/401 | loss=0.5119 ev=0.416 agents=381 avg_r=-0.6775 sum_r=-173.45 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 269/401 | loss=0.6067 ev=0.360 agents=331 avg_r=-0.4300 sum_r=-110.08 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+ 270/401 | loss=0.5958 ev=0.361 agents=431 avg_r=-2.7872 sum_r=-713.53 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.0s
+ 271/401 | loss=0.5430 ev=0.468 agents=250 avg_r=2.4127 sum_r=617.66 x<0=0.27 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 272/401 | loss=0.5570 ev=0.396 agents=195 avg_r=-3.9342 sum_r=-1007.15 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 273/401 | loss=0.5044 ev=0.347 agents=689 avg_r=-1.4386 sum_r=-368.28 x<0=0.27 elig=0.60 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 274/401 | loss=0.6166 ev=0.441 agents=235 avg_r=0.2971 sum_r=76.05 x<0=0.27 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 275/401 | loss=0.5763 ev=0.349 agents=245 avg_r=-1.4691 sum_r=-376.08 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 276/401 | loss=0.5384 ev=0.407 agents=275 avg_r=-1.0088 sum_r=-258.25 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 277/401 | loss=0.6362 ev=0.424 agents=244 avg_r=0.3209 sum_r=82.14 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 278/401 | loss=0.5336 ev=0.314 agents=100 avg_r=-2.8569 sum_r=-731.36 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 n_ref=0 r_loc=0.000 7.1s
+ 279/401 | loss=0.6352 ev=0.424 agents=280 avg_r=0.4295 sum_r=109.95 x<0=0.27 elig=0.61 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.5s
+ 280/401 | loss=0.5223 ev=0.365 agents=280 avg_r=1.8529 sum_r=474.35 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 281/401 | loss=0.6468 ev=0.442 agents=84 avg_r=-2.3205 sum_r=-594.05 x<0=0.28 elig=0.61 dorfler_tail=0.06 floor=0 sel=34 n_ref=0 r_loc=0.000 7.3s
+ 282/401 | loss=0.6596 ev=0.413 agents=472 avg_r=-0.4806 sum_r=-123.04 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 283/401 | loss=0.4776 ev=0.352 agents=72 avg_r=-1.7717 sum_r=-453.56 x<0=0.27 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 284/401 | loss=0.6458 ev=0.423 agents=159 avg_r=0.2598 sum_r=66.52 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.7s
+ 285/401 | loss=0.6260 ev=0.352 agents=215 avg_r=-0.5077 sum_r=-129.98 x<0=0.27 elig=0.61 dorfler_tail=0.06 floor=0 sel=34 n_ref=0 r_loc=0.000 7.8s
+ 286/401 | loss=0.4547 ev=0.354 agents=259 avg_r=0.6267 sum_r=160.43 x<0=0.26 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 n_ref=0 r_loc=0.000 7.1s
+ 287/401 | loss=0.5419 ev=0.376 agents=452 avg_r=-2.1155 sum_r=-541.58 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 288/401 | loss=0.6451 ev=0.428 agents=1442 avg_r=-0.0228 sum_r=-5.83 x<0=0.27 elig=0.61 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.5s
+ 289/401 | loss=0.5450 ev=0.397 agents=137 avg_r=1.1484 sum_r=293.99 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 290/401 | loss=0.5728 ev=0.385 agents=686 avg_r=-3.4156 sum_r=-874.40 x<0=0.25 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 291/401 | loss=0.5499 ev=0.405 agents=514 avg_r=1.9201 sum_r=491.55 x<0=0.25 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 292/401 | loss=0.5678 ev=0.381 agents=244 avg_r=-1.8899 sum_r=-483.81 x<0=0.27 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 293/401 | loss=0.6316 ev=0.441 agents=224 avg_r=-2.8545 sum_r=-730.75 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 294/401 | loss=0.5186 ev=0.350 agents=100 avg_r=1.1642 sum_r=298.03 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.4s
+ 295/401 | loss=0.6109 ev=0.428 agents=78 avg_r=-1.6792 sum_r=-429.87 x<0=0.25 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 296/401 | loss=0.5862 ev=0.366 agents=76 avg_r=-1.0895 sum_r=-278.91 x<0=0.25 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.2s
+ 297/401 | loss=0.6333 ev=0.441 agents=139 avg_r=-2.3314 sum_r=-596.85 x<0=0.27 elig=0.61 dorfler_tail=0.06 floor=0 sel=34 n_ref=0 r_loc=0.000 7.4s
+ 298/401 | loss=0.5617 ev=0.398 agents=240 avg_r=-1.6337 sum_r=-418.24 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 299/401 | loss=0.4948 ev=0.320 agents=34 avg_r=0.1841 sum_r=47.12 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 300/401 | loss=0.6482 ev=0.447 agents=413 avg_r=-1.1234 sum_r=-287.59 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+[Checkpoint] saved → checkpoints/model_iter0300.pt
+ 301/401 | loss=0.6045 ev=0.323 agents=556 avg_r=-0.8391 sum_r=-214.80 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 302/401 | loss=0.5194 ev=0.405 agents=207 avg_r=-1.0090 sum_r=-258.30 x<0=0.25 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.2s
+ 303/401 | loss=0.5433 ev=0.412 agents=135 avg_r=-1.4167 sum_r=-362.67 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 304/401 | loss=0.5904 ev=0.305 agents=372 avg_r=-4.1354 sum_r=-1058.66 x<0=0.24 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.0s
+ 305/401 | loss=0.6260 ev=0.441 agents=34 avg_r=-0.5323 sum_r=-136.27 x<0=0.24 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.1s
+ 306/401 | loss=0.4904 ev=0.349 agents=165 avg_r=0.4701 sum_r=120.35 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.3s
+ 307/401 | loss=0.6882 ev=0.399 agents=1312 avg_r=0.4548 sum_r=116.43 x<0=0.24 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 308/401 | loss=0.5244 ev=0.424 agents=887 avg_r=-1.4608 sum_r=-373.98 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.8s
+ 309/401 | loss=0.5516 ev=0.405 agents=34 avg_r=-0.1411 sum_r=-36.12 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 310/401 | loss=0.4932 ev=0.373 agents=141 avg_r=-2.8948 sum_r=-741.06 x<0=0.25 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.2s
+ 311/401 | loss=0.5420 ev=0.388 agents=1335 avg_r=0.3463 sum_r=88.64 x<0=0.24 elig=0.61 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 312/401 | loss=0.6290 ev=0.472 agents=36 avg_r=-1.9370 sum_r=-495.88 x<0=0.25 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 313/401 | loss=0.5851 ev=0.350 agents=810 avg_r=-1.9614 sum_r=-502.11 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 314/401 | loss=0.5564 ev=0.400 agents=79 avg_r=-1.1821 sum_r=-302.61 x<0=0.24 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+ 315/401 | loss=0.5560 ev=0.395 agents=195 avg_r=-1.6661 sum_r=-426.52 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 316/401 | loss=0.5173 ev=0.373 agents=223 avg_r=-1.4246 sum_r=-364.69 x<0=0.23 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.0s
+ 317/401 | loss=0.5820 ev=0.378 agents=90 avg_r=-1.8654 sum_r=-477.54 x<0=0.24 elig=0.61 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 318/401 | loss=0.5921 ev=0.454 agents=470 avg_r=1.8024 sum_r=461.43 x<0=0.26 elig=0.61 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+ 319/401 | loss=0.5236 ev=0.425 agents=123 avg_r=-2.1968 sum_r=-562.39 x<0=0.24 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 320/401 | loss=0.5607 ev=0.371 agents=312 avg_r=-1.6211 sum_r=-415.01 x<0=0.24 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+ 321/401 | loss=0.5437 ev=0.416 agents=1566 avg_r=-0.8026 sum_r=-205.46 x<0=0.24 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+ 322/401 | loss=0.5501 ev=0.391 agents=209 avg_r=-0.7605 sum_r=-194.70 x<0=0.25 elig=0.62 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.3s
+ 323/401 | loss=0.6514 ev=0.438 agents=188 avg_r=-1.3562 sum_r=-347.19 x<0=0.25 elig=0.62 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+ 324/401 | loss=0.5607 ev=0.362 agents=156 avg_r=-2.3552 sum_r=-602.93 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 325/401 | loss=0.4888 ev=0.377 agents=319 avg_r=-1.3467 sum_r=-344.77 x<0=0.23 elig=0.62 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.2s
+ 326/401 | loss=0.6876 ev=0.394 agents=349 avg_r=-1.9759 sum_r=-505.83 x<0=0.26 elig=0.62 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.2s
+ 327/401 | loss=0.6569 ev=0.451 agents=34 avg_r=-1.8179 sum_r=-465.39 x<0=0.24 elig=0.62 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.3s
+ 328/401 | loss=0.5126 ev=0.281 agents=152 avg_r=-0.5285 sum_r=-135.29 x<0=0.24 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 n_ref=0 r_loc=0.000 7.1s
+ 329/401 | loss=0.5931 ev=0.450 agents=981 avg_r=-0.2140 sum_r=-54.78 x<0=0.25 elig=0.62 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 330/401 | loss=0.5123 ev=0.339 agents=155 avg_r=-1.5693 sum_r=-401.74 x<0=0.24 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 n_ref=0 r_loc=0.000 7.1s
+ 331/401 | loss=0.6416 ev=0.403 agents=34 avg_r=-1.7765 sum_r=-454.79 x<0=0.25 elig=0.62 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.7s
+ 332/401 | loss=0.5404 ev=0.403 agents=156 avg_r=-1.6670 sum_r=-426.76 x<0=0.24 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.8s
+ 333/401 | loss=0.6274 ev=0.441 agents=89 avg_r=-1.2332 sum_r=-315.70 x<0=0.25 elig=0.62 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.7s
+ 334/401 | loss=0.5735 ev=0.352 agents=62 avg_r=-1.9856 sum_r=-508.33 x<0=0.22 elig=0.62 dorfler_tail=0.06 floor=0 sel=29 n_ref=0 r_loc=0.000 7.3s
+ 335/401 | loss=0.4917 ev=0.352 agents=526 avg_r=0.7029 sum_r=179.95 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.6s
+ 336/401 | loss=0.5990 ev=0.340 agents=132 avg_r=-3.0811 sum_r=-788.76 x<0=0.23 elig=0.62 dorfler_tail=0.06 floor=0 sel=29 n_ref=0 r_loc=0.000 7.1s
+ 337/401 | loss=0.5901 ev=0.462 agents=84 avg_r=-1.6743 sum_r=-428.62 x<0=0.25 elig=0.62 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 338/401 | loss=0.5888 ev=0.395 agents=72 avg_r=-1.8019 sum_r=-461.30 x<0=0.24 elig=0.62 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.5s
+ 339/401 | loss=0.5367 ev=0.414 agents=144 avg_r=-0.9111 sum_r=-233.24 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.4s
+ 340/401 | loss=0.5691 ev=0.331 agents=175 avg_r=-4.5466 sum_r=-1163.92 x<0=0.26 elig=0.62 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 341/401 | loss=0.6337 ev=0.447 agents=91 avg_r=-0.5287 sum_r=-135.34 x<0=0.25 elig=0.62 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.6s
+ 342/401 | loss=0.5585 ev=0.361 agents=139 avg_r=1.2346 sum_r=316.07 x<0=0.25 elig=0.62 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.4s
+ 343/401 | loss=0.5099 ev=0.408 agents=60 avg_r=-2.0503 sum_r=-524.87 x<0=0.25 elig=0.62 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+ 344/401 | loss=0.5666 ev=0.390 agents=36 avg_r=-1.7931 sum_r=-459.04 x<0=0.24 elig=0.62 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 345/401 | loss=0.5461 ev=0.404 agents=383 avg_r=-3.6997 sum_r=-947.13 x<0=0.24 elig=0.62 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.3s
+ 346/401 | loss=0.7290 ev=0.376 agents=142 avg_r=0.2659 sum_r=68.08 x<0=0.26 elig=0.62 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 347/401 | loss=0.4937 ev=0.428 agents=217 avg_r=-1.5564 sum_r=-398.43 x<0=0.24 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+ 348/401 | loss=0.5818 ev=0.337 agents=72 avg_r=-1.5159 sum_r=-388.07 x<0=0.26 elig=0.62 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.2s
+ 349/401 | loss=0.5557 ev=0.396 agents=238 avg_r=-1.6126 sum_r=-412.83 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 350/401 | loss=0.5531 ev=0.390 agents=34 avg_r=-0.3411 sum_r=-87.32 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+[Checkpoint] saved → checkpoints/model_iter0350.pt
+ 351/401 | loss=0.5428 ev=0.398 agents=682 avg_r=-0.0545 sum_r=-13.96 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.2s
+ 352/401 | loss=0.5971 ev=0.375 agents=1161 avg_r=-4.0630 sum_r=-1040.14 x<0=0.24 elig=0.62 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.4s
+ 353/401 | loss=0.6607 ev=0.414 agents=212 avg_r=-1.9949 sum_r=-510.68 x<0=0.24 elig=0.62 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.1s
+ 354/401 | loss=0.5486 ev=0.378 agents=83 avg_r=-0.9611 sum_r=-246.04 x<0=0.24 elig=0.62 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.3s
+ 355/401 | loss=0.5905 ev=0.379 agents=1077 avg_r=-2.1700 sum_r=-555.53 x<0=0.26 elig=0.62 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 8.0s
+ 356/401 | loss=0.5469 ev=0.389 agents=140 avg_r=-1.3158 sum_r=-336.85 x<0=0.26 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.6s
+ 357/401 | loss=0.5095 ev=0.397 agents=764 avg_r=-0.0966 sum_r=-24.72 x<0=0.24 elig=0.61 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.7s
+ 358/401 | loss=0.5770 ev=0.395 agents=125 avg_r=-2.5987 sum_r=-665.27 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.4s
+ 359/401 | loss=0.6685 ev=0.406 agents=103 avg_r=-3.2896 sum_r=-842.13 x<0=0.23 elig=0.63 dorfler_tail=0.06 floor=0 sel=29 n_ref=0 r_loc=0.000 7.2s
+ 360/401 | loss=0.5382 ev=0.408 agents=537 avg_r=0.4558 sum_r=116.70 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=34 n_ref=0 r_loc=0.000 7.7s
+ 361/401 | loss=0.5846 ev=0.384 agents=245 avg_r=-1.1329 sum_r=-290.03 x<0=0.24 elig=0.62 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.3s
+ 362/401 | loss=0.5318 ev=0.404 agents=194 avg_r=-1.1031 sum_r=-282.39 x<0=0.25 elig=0.61 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+ 363/401 | loss=0.6778 ev=0.410 agents=155 avg_r=-3.5161 sum_r=-900.13 x<0=0.25 elig=0.63 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.8s
+ 364/401 | loss=0.5592 ev=0.387 agents=720 avg_r=-3.1739 sum_r=-812.52 x<0=0.25 elig=0.61 dorfler_tail=0.06 floor=0 sel=29 n_ref=0 r_loc=0.000 7.2s
+ 365/401 | loss=0.5257 ev=0.340 agents=195 avg_r=1.4110 sum_r=361.21 x<0=0.24 elig=0.61 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+ 366/401 | loss=0.7202 ev=0.381 agents=64 avg_r=-3.0263 sum_r=-774.72 x<0=0.24 elig=0.62 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.2s
+ 367/401 | loss=0.5865 ev=0.393 agents=584 avg_r=-2.2033 sum_r=-564.05 x<0=0.24 elig=0.62 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.4s
+ 368/401 | loss=0.5074 ev=0.411 agents=78 avg_r=-2.5681 sum_r=-657.44 x<0=0.25 elig=0.62 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 369/401 | loss=0.5519 ev=0.377 agents=183 avg_r=0.4932 sum_r=126.27 x<0=0.25 elig=0.62 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.4s
+ 370/401 | loss=0.5265 ev=0.397 agents=183 avg_r=-1.9064 sum_r=-488.03 x<0=0.24 elig=0.62 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.4s
+ 371/401 | loss=0.6248 ev=0.468 agents=325 avg_r=-1.4349 sum_r=-367.34 x<0=0.23 elig=0.62 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 372/401 | loss=0.6210 ev=0.368 agents=195 avg_r=-2.1573 sum_r=-552.26 x<0=0.24 elig=0.62 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+ 373/401 | loss=0.5398 ev=0.381 agents=1257 avg_r=0.1999 sum_r=51.16 x<0=0.24 elig=0.61 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.5s
+ 374/401 | loss=0.7041 ev=0.437 agents=140 avg_r=-2.6638 sum_r=-681.93 x<0=0.24 elig=0.63 dorfler_tail=0.06 floor=0 sel=28 n_ref=0 r_loc=0.000 7.0s
+ 375/401 | loss=0.5560 ev=0.344 agents=1153 avg_r=-4.6746 sum_r=-1196.70 x<0=0.26 elig=0.62 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 7.6s
+ 376/401 | loss=0.5135 ev=0.402 agents=145 avg_r=0.4112 sum_r=105.26 x<0=0.24 elig=0.62 dorfler_tail=0.06 floor=0 sel=29 n_ref=0 r_loc=0.000 7.1s
+ 377/401 | loss=0.5797 ev=0.389 agents=476 avg_r=-1.3227 sum_r=-338.62 x<0=0.26 elig=0.62 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.6s
+ 378/401 | loss=0.5229 ev=0.401 agents=80 avg_r=-1.8801 sum_r=-481.30 x<0=0.25 elig=0.62 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.3s
+ 379/401 | loss=0.5683 ev=0.371 agents=94 avg_r=-2.1285 sum_r=-544.89 x<0=0.25 elig=0.62 dorfler_tail=0.06 floor=0 sel=33 n_ref=0 r_loc=0.000 8.0s
+ 380/401 | loss=0.5654 ev=0.402 agents=196 avg_r=-2.9217 sum_r=-747.96 x<0=0.25 elig=0.62 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.6s
+ 381/401 | loss=0.6029 ev=0.422 agents=76 avg_r=0.8416 sum_r=215.45 x<0=0.25 elig=0.63 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.6s
+ 382/401 | loss=0.5868 ev=0.403 agents=202 avg_r=-3.3551 sum_r=-858.92 x<0=0.24 elig=0.62 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.8s
+ 383/401 | loss=0.5493 ev=0.371 agents=759 avg_r=-1.1757 sum_r=-300.97 x<0=0.25 elig=0.62 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.4s
+ 384/401 | loss=0.5628 ev=0.398 agents=286 avg_r=-2.6977 sum_r=-690.62 x<0=0.25 elig=0.62 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.5s
+ 385/401 | loss=0.5984 ev=0.329 agents=79 avg_r=-0.9978 sum_r=-255.44 x<0=0.25 elig=0.62 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.4s
+ 386/401 | loss=0.6295 ev=0.474 agents=112 avg_r=-2.3561 sum_r=-603.16 x<0=0.25 elig=0.63 dorfler_tail=0.06 floor=0 sel=32 n_ref=0 r_loc=0.000 7.6s
+ 387/401 | loss=0.5699 ev=0.372 agents=747 avg_r=-2.0223 sum_r=-517.72 x<0=0.25 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.4s
+ 388/401 | loss=0.5713 ev=0.367 agents=74 avg_r=-2.6122 sum_r=-668.71 x<0=0.23 elig=0.63 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.4s
+ 389/401 | loss=0.5408 ev=0.380 agents=34 avg_r=-0.7515 sum_r=-192.39 x<0=0.24 elig=0.62 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 390/401 | loss=0.5509 ev=0.404 agents=185 avg_r=-1.0922 sum_r=-279.60 x<0=0.24 elig=0.62 dorfler_tail=0.07 floor=0 sel=31 n_ref=0 r_loc=0.000 7.5s
+ 391/401 | loss=0.7629 ev=0.392 agents=1114 avg_r=-2.8317 sum_r=-724.91 x<0=0.24 elig=0.62 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.2s
+ 392/401 | loss=0.5248 ev=0.384 agents=204 avg_r=0.4260 sum_r=109.06 x<0=0.24 elig=0.62 dorfler_tail=0.07 floor=0 sel=33 n_ref=0 r_loc=0.000 7.7s
+ 393/401 | loss=0.5672 ev=0.383 agents=84 avg_r=-1.4752 sum_r=-377.66 x<0=0.25 elig=0.62 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.3s
+ 394/401 | loss=0.5358 ev=0.420 agents=136 avg_r=-2.7112 sum_r=-694.07 x<0=0.24 elig=0.62 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 395/401 | loss=0.5721 ev=0.385 agents=123 avg_r=-0.5855 sum_r=-149.88 x<0=0.25 elig=0.62 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.5s
+ 396/401 | loss=0.6814 ev=0.430 agents=769 avg_r=-2.4388 sum_r=-624.33 x<0=0.25 elig=0.62 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.3s
+ 397/401 | loss=0.4945 ev=0.420 agents=196 avg_r=-1.5640 sum_r=-400.38 x<0=0.24 elig=0.62 dorfler_tail=0.07 floor=0 sel=32 n_ref=0 r_loc=0.000 7.6s
+ 398/401 | loss=0.5281 ev=0.308 agents=179 avg_r=-1.0618 sum_r=-271.83 x<0=0.24 elig=0.62 dorfler_tail=0.07 floor=0 sel=30 n_ref=0 r_loc=0.000 7.2s
+ 399/401 | loss=0.7013 ev=0.408 agents=177 avg_r=-3.2987 sum_r=-844.47 x<0=0.24 elig=0.62 dorfler_tail=0.06 floor=0 sel=30 n_ref=0 r_loc=0.000 7.4s
+ 400/401 | loss=0.5656 ev=0.374 agents=1732 avg_r=-1.8509 sum_r=-473.83 x<0=0.24 elig=0.62 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.3s
+[Checkpoint] saved → checkpoints/model_iter0400.pt
+ 401/401 | loss=0.5597 ev=0.432 agents=220 avg_r=-2.2646 sum_r=-579.72 x<0=0.24 elig=0.62 dorfler_tail=0.06 floor=0 sel=31 n_ref=0 r_loc=0.000 7.4s
+[Checkpoint] saved → checkpoints/model_iter0401.pt
+[Checkpoint] saved → checkpoints/model_final.pt
+[Train] done, total time 2975.5s
+Training finished at Thu 28 May 14:15:44 CST 2026
diff --git a/logs/stop150.out b/logs/stop150.out
new file mode 100644
index 0000000..8595bbc
--- /dev/null
+++ b/logs/stop150.out
@@ -0,0 +1,178 @@
+Starting training at Fri 29 May 14:36:05 CST 2026
+Running on node: node06
+[Device] cuda
+[Env] node_feats=14 edge_feats=1 act_dim=1
+[Model] params=92,804
+ 1/401 | loss=1.2593 ev=-0.005 agents=109 avg_r=-0.4716 sum_r=-120.74 x<0=0.69 elig=0.58 dorfler_tail=0.09 floor=0 sel=35 8.7s
+ 2/401 | loss=1.1660 ev=0.023 agents=193 avg_r=1.8712 sum_r=479.03 x<0=0.62 elig=0.58 dorfler_tail=0.08 floor=0 sel=32 7.8s
+ 3/401 | loss=1.1102 ev=0.044 agents=39 avg_r=-1.2724 sum_r=-325.74 x<0=0.60 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.8s
+ 4/401 | loss=1.1780 ev=0.065 agents=34 avg_r=2.1552 sum_r=551.73 x<0=0.61 elig=0.58 dorfler_tail=0.09 floor=0 sel=35 8.3s
+ 5/401 | loss=1.1065 ev=0.091 agents=88 avg_r=-1.4642 sum_r=-374.83 x<0=0.52 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 8.0s
+ 6/401 | loss=1.2564 ev=0.098 agents=36 avg_r=1.5516 sum_r=397.20 x<0=0.49 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.8s
+ 7/401 | loss=1.0063 ev=0.172 agents=34 avg_r=0.8841 sum_r=226.33 x<0=0.47 elig=0.58 dorfler_tail=0.09 floor=0 sel=35 8.1s
+ 8/401 | loss=1.3696 ev=0.168 agents=133 avg_r=0.6858 sum_r=175.58 x<0=0.44 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.9s
+ 9/401 | loss=1.1844 ev=0.215 agents=79 avg_r=0.2644 sum_r=67.68 x<0=0.45 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.7s
+ 10/401 | loss=1.0413 ev=0.216 agents=82 avg_r=-1.0025 sum_r=-256.64 x<0=0.42 elig=0.59 dorfler_tail=0.08 floor=0 sel=34 8.0s
+ 11/401 | loss=1.2795 ev=0.256 agents=60 avg_r=2.6849 sum_r=687.34 x<0=0.39 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.8s
+ 12/401 | loss=0.8503 ev=0.306 agents=48 avg_r=0.5254 sum_r=134.49 x<0=0.40 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.9s
+ 13/401 | loss=0.8283 ev=0.322 agents=88 avg_r=0.9044 sum_r=231.52 x<0=0.42 elig=0.58 dorfler_tail=0.08 floor=0 sel=33 7.9s
+ 14/401 | loss=0.8950 ev=0.298 agents=40 avg_r=0.4961 sum_r=127.00 x<0=0.39 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.9s
+ 15/401 | loss=0.8561 ev=0.342 agents=101 avg_r=0.5456 sum_r=139.67 x<0=0.41 elig=0.58 dorfler_tail=0.08 floor=0 sel=34 8.0s
+ 16/401 | loss=1.1581 ev=0.283 agents=34 avg_r=-1.9177 sum_r=-490.92 x<0=0.33 elig=0.59 dorfler_tail=0.08 floor=0 sel=29 7.5s
+ 17/401 | loss=0.8868 ev=0.364 agents=132 avg_r=3.2843 sum_r=840.77 x<0=0.33 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 8.0s
+ 18/401 | loss=0.8571 ev=0.349 agents=34 avg_r=1.1258 sum_r=288.21 x<0=0.30 elig=0.58 dorfler_tail=0.08 floor=0 sel=32 7.9s
+ 19/401 | loss=0.7991 ev=0.374 agents=201 avg_r=-0.2317 sum_r=-59.32 x<0=0.28 elig=0.59 dorfler_tail=0.08 floor=0 sel=35 8.1s
+ 20/401 | loss=0.8149 ev=0.386 agents=120 avg_r=1.5704 sum_r=402.02 x<0=0.21 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.7s
+ 21/401 | loss=0.8764 ev=0.357 agents=78 avg_r=0.5421 sum_r=138.78 x<0=0.22 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.7s
+ 22/401 | loss=0.7788 ev=0.367 agents=44 avg_r=0.6768 sum_r=173.27 x<0=0.17 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.7s
+ 23/401 | loss=0.7429 ev=0.382 agents=36 avg_r=0.6276 sum_r=160.68 x<0=0.16 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.8s
+ 24/401 | loss=0.8267 ev=0.404 agents=175 avg_r=3.4114 sum_r=873.33 x<0=0.13 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.9s
+ 25/401 | loss=0.7211 ev=0.390 agents=34 avg_r=0.2581 sum_r=66.07 x<0=0.12 elig=0.59 dorfler_tail=0.08 floor=0 sel=29 7.4s
+ 26/401 | loss=0.9829 ev=0.350 agents=34 avg_r=-0.0098 sum_r=-2.50 x<0=0.13 elig=0.59 dorfler_tail=0.08 floor=0 sel=34 8.0s
+ 27/401 | loss=0.7973 ev=0.356 agents=176 avg_r=0.8028 sum_r=205.51 x<0=0.12 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 8.1s
+ 28/401 | loss=0.7603 ev=0.414 agents=219 avg_r=0.7955 sum_r=203.65 x<0=0.10 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 8.1s
+ 29/401 | loss=0.7585 ev=0.375 agents=44 avg_r=1.5867 sum_r=406.19 x<0=0.09 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 8.0s
+ 30/401 | loss=0.6940 ev=0.425 agents=133 avg_r=2.4328 sum_r=622.81 x<0=0.09 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.6s
+ 31/401 | loss=0.9083 ev=0.370 agents=44 avg_r=2.5351 sum_r=648.99 x<0=0.13 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.8s
+ 32/401 | loss=1.0825 ev=0.356 agents=34 avg_r=0.0954 sum_r=24.43 x<0=0.16 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 8.0s
+ 33/401 | loss=0.6799 ev=0.430 agents=752 avg_r=2.1090 sum_r=539.90 x<0=0.15 elig=0.59 dorfler_tail=0.07 floor=0 sel=31 7.7s
+ 34/401 | loss=1.0309 ev=0.325 agents=132 avg_r=-0.3870 sum_r=-99.07 x<0=0.14 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.6s
+ 35/401 | loss=0.7810 ev=0.385 agents=60 avg_r=2.1370 sum_r=547.06 x<0=0.10 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 36/401 | loss=0.7733 ev=0.381 agents=139 avg_r=0.5555 sum_r=142.22 x<0=0.09 elig=0.59 dorfler_tail=0.08 floor=0 sel=29 7.4s
+ 37/401 | loss=0.7242 ev=0.386 agents=752 avg_r=1.7036 sum_r=436.12 x<0=0.10 elig=0.59 dorfler_tail=0.07 floor=0 sel=31 7.5s
+ 38/401 | loss=0.7454 ev=0.402 agents=34 avg_r=1.7798 sum_r=455.64 x<0=0.09 elig=0.59 dorfler_tail=0.07 floor=0 sel=31 7.5s
+ 39/401 | loss=0.6106 ev=0.445 agents=87 avg_r=2.2153 sum_r=567.13 x<0=0.06 elig=0.60 dorfler_tail=0.08 floor=0 sel=30 7.5s
+ 40/401 | loss=0.8085 ev=0.381 agents=88 avg_r=2.2893 sum_r=586.06 x<0=0.06 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.7s
+ 41/401 | loss=0.6706 ev=0.419 agents=301 avg_r=1.4149 sum_r=362.21 x<0=0.05 elig=0.59 dorfler_tail=0.07 floor=0 sel=29 7.2s
+ 42/401 | loss=0.6504 ev=0.440 agents=1563 avg_r=2.3614 sum_r=604.52 x<0=0.06 elig=0.59 dorfler_tail=0.07 floor=0 sel=31 7.5s
+ 43/401 | loss=0.6548 ev=0.389 agents=905 avg_r=2.1166 sum_r=541.85 x<0=0.05 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.5s
+ 44/401 | loss=0.6763 ev=0.392 agents=603 avg_r=2.1965 sum_r=562.30 x<0=0.05 elig=0.60 dorfler_tail=0.08 floor=0 sel=31 7.6s
+ 45/401 | loss=0.6371 ev=0.417 agents=321 avg_r=1.2079 sum_r=309.23 x<0=0.04 elig=0.59 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 46/401 | loss=0.7580 ev=0.419 agents=64 avg_r=2.3964 sum_r=613.47 x<0=0.05 elig=0.59 dorfler_tail=0.07 floor=0 sel=31 7.6s
+ 47/401 | loss=0.8826 ev=0.357 agents=648 avg_r=1.9237 sum_r=492.46 x<0=0.07 elig=0.60 dorfler_tail=0.08 floor=0 sel=30 7.4s
+ 48/401 | loss=0.7618 ev=0.374 agents=72 avg_r=1.9302 sum_r=494.14 x<0=0.04 elig=0.59 dorfler_tail=0.07 floor=0 sel=31 7.4s
+ 49/401 | loss=1.0496 ev=0.349 agents=1113 avg_r=1.6100 sum_r=412.15 x<0=0.05 elig=0.59 dorfler_tail=0.07 floor=0 sel=31 8.0s
+ 50/401 | loss=1.0966 ev=0.355 agents=207 avg_r=0.2694 sum_r=68.96 x<0=0.04 elig=0.59 dorfler_tail=0.07 floor=0 sel=30 7.7s
+[Checkpoint] saved → checkpoints/model_iter0050.pt
+ 51/401 | loss=0.7497 ev=0.362 agents=88 avg_r=2.4859 sum_r=636.39 x<0=0.04 elig=0.59 dorfler_tail=0.07 floor=0 sel=30 7.6s
+ 52/401 | loss=0.7117 ev=0.376 agents=34 avg_r=1.3932 sum_r=356.65 x<0=0.04 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.5s
+ 53/401 | loss=0.8732 ev=0.428 agents=482 avg_r=2.5241 sum_r=646.16 x<0=0.05 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.5s
+ 54/401 | loss=0.7275 ev=0.414 agents=797 avg_r=2.5614 sum_r=655.71 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.6s
+ 55/401 | loss=1.0015 ev=0.267 agents=238 avg_r=1.7553 sum_r=449.35 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.7s
+ 56/401 | loss=0.9532 ev=0.328 agents=78 avg_r=1.6596 sum_r=424.86 x<0=0.04 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.3s
+ 57/401 | loss=0.9659 ev=0.392 agents=180 avg_r=0.1315 sum_r=33.67 x<0=0.04 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.6s
+ 58/401 | loss=0.5575 ev=0.479 agents=1467 avg_r=3.9607 sum_r=1013.94 x<0=0.04 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.6s
+ 59/401 | loss=0.6323 ev=0.412 agents=257 avg_r=1.1701 sum_r=299.54 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.6s
+ 60/401 | loss=0.7717 ev=0.429 agents=278 avg_r=1.1557 sum_r=295.85 x<0=0.04 elig=0.60 dorfler_tail=0.08 floor=0 sel=28 7.3s
+ 61/401 | loss=0.6149 ev=0.436 agents=162 avg_r=2.4661 sum_r=631.33 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.5s
+ 62/401 | loss=0.5705 ev=0.410 agents=269 avg_r=3.6565 sum_r=936.06 x<0=0.03 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.6s
+ 63/401 | loss=0.7479 ev=0.391 agents=34 avg_r=1.1095 sum_r=284.04 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 64/401 | loss=0.9662 ev=0.418 agents=149 avg_r=1.0548 sum_r=270.02 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 65/401 | loss=0.8020 ev=0.379 agents=139 avg_r=2.3568 sum_r=603.34 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 66/401 | loss=0.9130 ev=0.401 agents=140 avg_r=0.8920 sum_r=228.35 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.5s
+ 67/401 | loss=0.6314 ev=0.411 agents=82 avg_r=2.2832 sum_r=584.50 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 68/401 | loss=0.8747 ev=0.437 agents=258 avg_r=0.8502 sum_r=217.65 x<0=0.01 elig=0.60 dorfler_tail=0.08 floor=0 sel=30 7.6s
+ 69/401 | loss=0.7156 ev=0.397 agents=649 avg_r=2.6260 sum_r=672.26 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 70/401 | loss=0.7031 ev=0.427 agents=520 avg_r=2.5518 sum_r=653.26 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 71/401 | loss=0.6538 ev=0.393 agents=412 avg_r=2.4192 sum_r=619.32 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.6s
+ 72/401 | loss=0.6831 ev=0.418 agents=84 avg_r=2.0187 sum_r=516.80 x<0=0.01 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.8s
+ 73/401 | loss=0.7298 ev=0.426 agents=438 avg_r=2.5987 sum_r=665.26 x<0=0.00 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.7s
+ 74/401 | loss=0.6047 ev=0.470 agents=301 avg_r=3.4593 sum_r=885.58 x<0=0.00 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 75/401 | loss=0.6847 ev=0.412 agents=515 avg_r=0.6582 sum_r=168.49 x<0=0.00 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 76/401 | loss=0.9368 ev=0.393 agents=503 avg_r=2.7642 sum_r=707.63 x<0=0.00 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.7s
+ 77/401 | loss=0.9459 ev=0.432 agents=261 avg_r=1.2000 sum_r=307.20 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.3s
+ 78/401 | loss=0.7438 ev=0.411 agents=221 avg_r=2.1195 sum_r=542.58 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 7.6s
+ 79/401 | loss=0.7466 ev=0.450 agents=232 avg_r=4.4824 sum_r=1147.50 x<0=0.01 elig=0.60 dorfler_tail=0.08 floor=0 sel=32 7.7s
+ 80/401 | loss=1.1380 ev=0.460 agents=814 avg_r=0.3357 sum_r=85.95 x<0=0.01 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.2s
+ 81/401 | loss=0.8259 ev=0.394 agents=568 avg_r=1.8428 sum_r=471.75 x<0=0.00 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 82/401 | loss=0.5936 ev=0.436 agents=237 avg_r=3.5513 sum_r=909.14 x<0=0.00 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.5s
+ 83/401 | loss=0.6978 ev=0.432 agents=389 avg_r=2.7072 sum_r=693.05 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 84/401 | loss=0.8955 ev=0.404 agents=80 avg_r=3.3064 sum_r=846.43 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=31 7.8s
+ 85/401 | loss=0.8506 ev=0.432 agents=34 avg_r=0.2730 sum_r=69.89 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=24 6.9s
+ 86/401 | loss=0.7781 ev=0.412 agents=391 avg_r=3.9846 sum_r=1020.05 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=30 7.9s
+ 87/401 | loss=0.8894 ev=0.397 agents=418 avg_r=2.6888 sum_r=688.32 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 88/401 | loss=1.0689 ev=0.411 agents=80 avg_r=3.0347 sum_r=776.89 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 89/401 | loss=0.8925 ev=0.358 agents=862 avg_r=2.9356 sum_r=751.50 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 90/401 | loss=0.7441 ev=0.464 agents=549 avg_r=4.5978 sum_r=1177.04 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 91/401 | loss=1.1180 ev=0.386 agents=101 avg_r=2.1914 sum_r=560.99 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 92/401 | loss=0.9271 ev=0.439 agents=60 avg_r=3.2678 sum_r=836.57 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 93/401 | loss=0.9531 ev=0.437 agents=291 avg_r=3.1621 sum_r=809.49 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 94/401 | loss=0.8870 ev=0.439 agents=101 avg_r=3.1353 sum_r=802.65 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 8.0s
+ 95/401 | loss=0.9440 ev=0.434 agents=34 avg_r=5.3761 sum_r=1376.27 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 8.4s
+ 96/401 | loss=1.1221 ev=0.381 agents=62 avg_r=2.8338 sum_r=725.45 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.9s
+ 97/401 | loss=0.9903 ev=0.452 agents=180 avg_r=4.0017 sum_r=1024.43 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.9s
+ 98/401 | loss=1.0881 ev=0.436 agents=419 avg_r=4.6007 sum_r=1177.77 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 99/401 | loss=0.8982 ev=0.432 agents=85 avg_r=2.9775 sum_r=762.24 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.8s
+ 100/401 | loss=1.0656 ev=0.359 agents=691 avg_r=3.0152 sum_r=771.89 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.7s
+[Checkpoint] saved → checkpoints/model_iter0100.pt
+ 101/401 | loss=0.8757 ev=0.449 agents=147 avg_r=4.0589 sum_r=1039.07 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.7s
+ 102/401 | loss=0.9537 ev=0.441 agents=802 avg_r=4.1671 sum_r=1066.79 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 103/401 | loss=1.1348 ev=0.457 agents=120 avg_r=4.9407 sum_r=1264.81 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 104/401 | loss=1.0887 ev=0.415 agents=48 avg_r=3.7664 sum_r=964.21 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 105/401 | loss=0.7257 ev=0.441 agents=245 avg_r=1.1230 sum_r=287.49 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=26 7.5s
+ 106/401 | loss=0.9558 ev=0.429 agents=193 avg_r=3.9291 sum_r=1005.86 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 107/401 | loss=1.1960 ev=0.461 agents=140 avg_r=3.8453 sum_r=984.40 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 8.0s
+ 108/401 | loss=1.0023 ev=0.425 agents=34 avg_r=3.5098 sum_r=898.50 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=26 7.5s
+ 109/401 | loss=1.0553 ev=0.437 agents=155 avg_r=4.4515 sum_r=1139.58 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 110/401 | loss=0.8946 ev=0.458 agents=317 avg_r=2.2184 sum_r=567.91 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 111/401 | loss=0.8399 ev=0.475 agents=322 avg_r=3.8648 sum_r=989.39 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 112/401 | loss=0.8203 ev=0.450 agents=661 avg_r=4.3269 sum_r=1107.69 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 113/401 | loss=1.2963 ev=0.414 agents=88 avg_r=4.9068 sum_r=1256.15 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 8.0s
+ 114/401 | loss=0.8770 ev=0.434 agents=96 avg_r=2.3554 sum_r=602.99 x<0=0.00 elig=0.64 dorfler_tail=0.06 floor=0 sel=25 7.3s
+ 115/401 | loss=1.0023 ev=0.462 agents=1043 avg_r=4.6932 sum_r=1201.45 x<0=0.01 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 116/401 | loss=0.9185 ev=0.471 agents=574 avg_r=4.3713 sum_r=1119.05 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 117/401 | loss=0.9487 ev=0.445 agents=461 avg_r=3.4812 sum_r=891.18 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 118/401 | loss=1.1328 ev=0.459 agents=186 avg_r=4.4079 sum_r=1128.43 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 8.2s
+ 119/401 | loss=0.8739 ev=0.454 agents=659 avg_r=3.6846 sum_r=943.26 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 8.0s
+ 120/401 | loss=0.8952 ev=0.490 agents=78 avg_r=4.0254 sum_r=1030.50 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 8.0s
+ 121/401 | loss=1.1642 ev=0.444 agents=180 avg_r=5.1341 sum_r=1314.33 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 8.0s
+ 122/401 | loss=1.0194 ev=0.449 agents=1241 avg_r=3.6450 sum_r=933.12 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.7s
+ 123/401 | loss=0.9362 ev=0.425 agents=227 avg_r=3.2675 sum_r=836.47 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.8s
+ 124/401 | loss=1.0467 ev=0.420 agents=34 avg_r=4.8397 sum_r=1238.97 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 125/401 | loss=0.9613 ev=0.467 agents=592 avg_r=5.1937 sum_r=1329.58 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=30 8.0s
+ 126/401 | loss=0.9090 ev=0.439 agents=44 avg_r=4.2965 sum_r=1099.89 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 127/401 | loss=1.0189 ev=0.451 agents=184 avg_r=4.2159 sum_r=1079.27 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=31 8.0s
+ 128/401 | loss=1.1045 ev=0.459 agents=808 avg_r=2.0674 sum_r=529.25 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=26 7.3s
+ 129/401 | loss=1.0547 ev=0.487 agents=705 avg_r=2.0413 sum_r=522.57 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 130/401 | loss=0.8997 ev=0.489 agents=119 avg_r=5.8658 sum_r=1501.65 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=30 7.9s
+ 131/401 | loss=1.1464 ev=0.463 agents=514 avg_r=5.3146 sum_r=1360.55 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=30 8.0s
+ 132/401 | loss=0.9049 ev=0.468 agents=176 avg_r=3.2288 sum_r=826.57 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=25 7.3s
+ 133/401 | loss=0.9787 ev=0.465 agents=1140 avg_r=3.8684 sum_r=990.30 x<0=0.00 elig=0.65 dorfler_tail=0.07 floor=0 sel=28 7.8s
+ 134/401 | loss=0.9619 ev=0.454 agents=44 avg_r=3.6363 sum_r=930.90 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 135/401 | loss=1.1247 ev=0.476 agents=71 avg_r=6.3209 sum_r=1618.16 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 136/401 | loss=0.9569 ev=0.428 agents=637 avg_r=2.3333 sum_r=597.34 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=26 7.4s
+ 137/401 | loss=1.3365 ev=0.372 agents=132 avg_r=3.3031 sum_r=845.59 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 7.8s
+ 138/401 | loss=1.0446 ev=0.487 agents=197 avg_r=4.3467 sum_r=1112.75 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 139/401 | loss=0.9965 ev=0.493 agents=1239 avg_r=3.0278 sum_r=775.11 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 140/401 | loss=0.8756 ev=0.491 agents=34 avg_r=4.0575 sum_r=1038.73 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=26 7.8s
+ 141/401 | loss=1.0863 ev=0.455 agents=202 avg_r=4.4626 sum_r=1142.43 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 8.2s
+ 142/401 | loss=0.8633 ev=0.492 agents=599 avg_r=3.6977 sum_r=946.60 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.7s
+ 143/401 | loss=1.2714 ev=0.450 agents=83 avg_r=3.4606 sum_r=885.91 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.8s
+ 144/401 | loss=0.8689 ev=0.480 agents=212 avg_r=5.9020 sum_r=1510.92 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=31 8.2s
+ 145/401 | loss=0.8527 ev=0.457 agents=466 avg_r=3.3779 sum_r=864.73 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 146/401 | loss=1.0791 ev=0.436 agents=41 avg_r=3.9742 sum_r=1017.40 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 147/401 | loss=1.0243 ev=0.483 agents=201 avg_r=4.0608 sum_r=1039.56 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.7s
+ 148/401 | loss=0.8642 ev=0.439 agents=169 avg_r=5.0525 sum_r=1293.44 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 149/401 | loss=1.2060 ev=0.492 agents=1118 avg_r=3.4406 sum_r=880.81 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.8s
+ 150/401 | loss=0.8956 ev=0.491 agents=139 avg_r=4.4020 sum_r=1126.90 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.7s
+[Checkpoint] saved → checkpoints/model_iter0150.pt
+ 151/401 | loss=0.8862 ev=0.439 agents=36 avg_r=3.6186 sum_r=926.35 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=26 7.4s
+ 152/401 | loss=1.1976 ev=0.436 agents=374 avg_r=5.2749 sum_r=1350.39 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=30 8.0s
+ 153/401 | loss=0.7750 ev=0.453 agents=203 avg_r=3.3719 sum_r=863.21 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=26 7.5s
+ 154/401 | loss=1.1222 ev=0.448 agents=498 avg_r=5.2013 sum_r=1331.52 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 155/401 | loss=0.8401 ev=0.498 agents=174 avg_r=4.3179 sum_r=1105.39 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 156/401 | loss=1.1951 ev=0.475 agents=144 avg_r=4.7607 sum_r=1218.73 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 157/401 | loss=1.0364 ev=0.488 agents=233 avg_r=4.6508 sum_r=1190.61 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 158/401 | loss=1.1938 ev=0.437 agents=40 avg_r=4.8137 sum_r=1232.31 x<0=0.00 elig=0.65 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 159/401 | loss=0.7339 ev=0.442 agents=401 avg_r=2.6907 sum_r=688.82 x<0=0.00 elig=0.64 dorfler_tail=0.06 floor=0 sel=27 7.5s
+ 160/401 | loss=0.9124 ev=0.494 agents=377 avg_r=5.1447 sum_r=1317.04 x<0=0.00 elig=0.65 dorfler_tail=0.07 floor=0 sel=27 7.7s
+ 161/401 | loss=1.1279 ev=0.482 agents=34 avg_r=5.6036 sum_r=1434.53 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=30 8.0s
+ 162/401 | loss=0.9648 ev=0.472 agents=725 avg_r=4.8624 sum_r=1244.77 x<0=0.00 elig=0.65 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 163/401 | loss=0.8031 ev=0.507 agents=276 avg_r=2.6097 sum_r=668.09 x<0=0.00 elig=0.64 dorfler_tail=0.06 floor=0 sel=23 7.6s
+ 164/401 | loss=1.3767 ev=0.402 agents=177 avg_r=5.0539 sum_r=1293.81 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=31 8.4s
+ 165/401 | loss=0.9780 ev=0.513 agents=158 avg_r=4.9213 sum_r=1259.84 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 8.0s
+ 166/401 | loss=0.9135 ev=0.480 agents=397 avg_r=3.7623 sum_r=963.14 x<0=0.00 elig=0.65 dorfler_tail=0.07 floor=0 sel=27 7.8s
+ 167/401 | loss=1.1074 ev=0.503 agents=193 avg_r=5.2436 sum_r=1342.35 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=30 8.0s
+ 168/401 | loss=1.1870 ev=0.476 agents=1235 avg_r=3.8139 sum_r=976.35 x<0=0.00 elig=0.65 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 169/401 | loss=1.2314 ev=0.459 agents=476 avg_r=2.9524 sum_r=755.82 x<0=0.00 elig=0.65 dorfler_tail=0.07 floor=0 sel=29 7.9s
+slurmstepd: error: *** JOB 4533 ON node06 CANCELLED AT 2026-05-29T14:58:13 ***
diff --git a/logs/train_4534.out b/logs/train_4534.out
new file mode 100644
index 0000000..cf2e4b7
--- /dev/null
+++ b/logs/train_4534.out
@@ -0,0 +1,418 @@
+Starting training at Fri 29 May 14:58:18 CST 2026
+Running on node: node06
+[Device] cuda
+[Env] node_feats=14 edge_feats=1 act_dim=1
+[Model] params=92,804
+ 1/401 | loss=1.4128 ev=-0.004 agents=109 avg_r=-2.9617 sum_r=-758.20 x<0=0.69 elig=0.58 dorfler_tail=0.09 floor=0 sel=35 8.6s
+ 2/401 | loss=1.3206 ev=0.021 agents=193 avg_r=-0.3258 sum_r=-83.41 x<0=0.62 elig=0.58 dorfler_tail=0.08 floor=0 sel=32 7.8s
+ 3/401 | loss=1.2607 ev=0.053 agents=39 avg_r=-3.3286 sum_r=-852.13 x<0=0.56 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.7s
+ 4/401 | loss=1.3325 ev=0.075 agents=34 avg_r=0.7804 sum_r=199.78 x<0=0.52 elig=0.58 dorfler_tail=0.09 floor=0 sel=35 8.2s
+ 5/401 | loss=1.2579 ev=0.094 agents=88 avg_r=-3.0086 sum_r=-770.19 x<0=0.43 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 8.0s
+ 6/401 | loss=1.2490 ev=0.117 agents=36 avg_r=-0.7408 sum_r=-189.63 x<0=0.40 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.7s
+ 7/401 | loss=1.1303 ev=0.172 agents=34 avg_r=-0.5650 sum_r=-144.65 x<0=0.35 elig=0.58 dorfler_tail=0.08 floor=0 sel=35 8.0s
+ 8/401 | loss=1.1519 ev=0.223 agents=133 avg_r=-0.3562 sum_r=-91.18 x<0=0.29 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.8s
+ 9/401 | loss=1.0561 ev=0.265 agents=79 avg_r=0.0758 sum_r=19.41 x<0=0.28 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.6s
+ 10/401 | loss=1.0494 ev=0.258 agents=82 avg_r=-2.5148 sum_r=-643.78 x<0=0.34 elig=0.59 dorfler_tail=0.08 floor=0 sel=34 7.8s
+ 11/401 | loss=1.0812 ev=0.302 agents=60 avg_r=2.1651 sum_r=554.27 x<0=0.30 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.6s
+ 12/401 | loss=0.9418 ev=0.317 agents=48 avg_r=1.0822 sum_r=277.04 x<0=0.28 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.7s
+ 13/401 | loss=0.9202 ev=0.317 agents=88 avg_r=0.3357 sum_r=85.94 x<0=0.33 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.8s
+ 14/401 | loss=0.9721 ev=0.318 agents=40 avg_r=0.2343 sum_r=59.99 x<0=0.28 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.7s
+ 15/401 | loss=0.9063 ev=0.352 agents=101 avg_r=0.5217 sum_r=133.55 x<0=0.25 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.8s
+ 16/401 | loss=1.0478 ev=0.353 agents=34 avg_r=-1.6244 sum_r=-415.85 x<0=0.21 elig=0.59 dorfler_tail=0.08 floor=0 sel=29 7.4s
+ 17/401 | loss=0.9633 ev=0.345 agents=132 avg_r=2.7550 sum_r=705.27 x<0=0.24 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.8s
+ 18/401 | loss=0.9338 ev=0.365 agents=34 avg_r=0.5794 sum_r=148.32 x<0=0.30 elig=0.58 dorfler_tail=0.08 floor=0 sel=32 7.7s
+ 19/401 | loss=0.8862 ev=0.393 agents=201 avg_r=0.2777 sum_r=71.08 x<0=0.27 elig=0.59 dorfler_tail=0.08 floor=0 sel=34 7.9s
+ 20/401 | loss=0.8669 ev=0.394 agents=120 avg_r=0.4671 sum_r=119.58 x<0=0.19 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.6s
+ 21/401 | loss=0.9409 ev=0.369 agents=78 avg_r=0.5001 sum_r=128.03 x<0=0.17 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.6s
+ 22/401 | loss=0.8863 ev=0.373 agents=44 avg_r=-0.1458 sum_r=-37.33 x<0=0.19 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.6s
+ 23/401 | loss=0.8574 ev=0.378 agents=36 avg_r=0.1385 sum_r=35.46 x<0=0.18 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.6s
+ 24/401 | loss=0.8286 ev=0.432 agents=175 avg_r=3.1860 sum_r=815.61 x<0=0.16 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.7s
+ 25/401 | loss=0.9002 ev=0.363 agents=34 avg_r=-0.0388 sum_r=-9.93 x<0=0.14 elig=0.59 dorfler_tail=0.08 floor=0 sel=28 7.2s
+ 26/401 | loss=0.8252 ev=0.385 agents=34 avg_r=-0.2623 sum_r=-67.15 x<0=0.12 elig=0.58 dorfler_tail=0.08 floor=0 sel=34 7.8s
+ 27/401 | loss=0.8039 ev=0.408 agents=176 avg_r=0.3361 sum_r=86.04 x<0=0.11 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.9s
+ 28/401 | loss=0.8841 ev=0.404 agents=219 avg_r=-0.2521 sum_r=-64.55 x<0=0.10 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 8.1s
+ 29/401 | loss=0.8608 ev=0.345 agents=44 avg_r=1.4892 sum_r=381.24 x<0=0.10 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.9s
+ 30/401 | loss=0.7754 ev=0.444 agents=133 avg_r=1.3507 sum_r=345.79 x<0=0.09 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.5s
+ 31/401 | loss=0.8501 ev=0.406 agents=44 avg_r=1.3255 sum_r=339.33 x<0=0.09 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.7s
+ 32/401 | loss=0.8750 ev=0.418 agents=34 avg_r=0.3083 sum_r=78.94 x<0=0.06 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.7s
+ 33/401 | loss=0.7966 ev=0.438 agents=745 avg_r=2.5903 sum_r=663.13 x<0=0.06 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 34/401 | loss=0.8724 ev=0.418 agents=132 avg_r=0.1713 sum_r=43.85 x<0=0.06 elig=0.59 dorfler_tail=0.07 floor=0 sel=31 7.5s
+ 35/401 | loss=0.7984 ev=0.436 agents=60 avg_r=1.5414 sum_r=394.60 x<0=0.05 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.6s
+ 36/401 | loss=0.8868 ev=0.401 agents=139 avg_r=0.2042 sum_r=52.28 x<0=0.04 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.4s
+ 37/401 | loss=0.9037 ev=0.426 agents=228 avg_r=0.5137 sum_r=131.52 x<0=0.04 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 38/401 | loss=0.9280 ev=0.353 agents=34 avg_r=1.7908 sum_r=458.45 x<0=0.05 elig=0.59 dorfler_tail=0.07 floor=0 sel=31 7.5s
+ 39/401 | loss=0.7340 ev=0.438 agents=194 avg_r=1.8975 sum_r=485.76 x<0=0.05 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.4s
+ 40/401 | loss=0.8670 ev=0.364 agents=228 avg_r=2.4297 sum_r=621.99 x<0=0.07 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.7s
+ 41/401 | loss=0.8306 ev=0.403 agents=199 avg_r=1.3996 sum_r=358.30 x<0=0.06 elig=0.59 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 42/401 | loss=0.7935 ev=0.456 agents=40 avg_r=2.2913 sum_r=586.59 x<0=0.06 elig=0.59 dorfler_tail=0.07 floor=0 sel=31 7.5s
+ 43/401 | loss=0.7569 ev=0.425 agents=34 avg_r=1.5674 sum_r=401.25 x<0=0.05 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 44/401 | loss=0.8324 ev=0.425 agents=193 avg_r=1.5056 sum_r=385.44 x<0=0.07 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.5s
+ 45/401 | loss=0.8032 ev=0.458 agents=230 avg_r=1.1388 sum_r=291.54 x<0=0.06 elig=0.59 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 46/401 | loss=0.8043 ev=0.436 agents=34 avg_r=2.3922 sum_r=612.39 x<0=0.07 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 47/401 | loss=0.7410 ev=0.443 agents=120 avg_r=3.2861 sum_r=841.24 x<0=0.08 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.4s
+ 48/401 | loss=0.8324 ev=0.403 agents=34 avg_r=0.2820 sum_r=72.19 x<0=0.05 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 49/401 | loss=0.7722 ev=0.461 agents=118 avg_r=3.1596 sum_r=808.87 x<0=0.06 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 8.0s
+ 50/401 | loss=0.7615 ev=0.445 agents=203 avg_r=1.2732 sum_r=325.95 x<0=0.03 elig=0.59 dorfler_tail=0.07 floor=0 sel=30 7.7s
+[Checkpoint] saved → checkpoints/model_iter0050.pt
+ 51/401 | loss=0.7829 ev=0.428 agents=1574 avg_r=1.8165 sum_r=465.03 x<0=0.02 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.7s
+ 52/401 | loss=0.7954 ev=0.432 agents=278 avg_r=2.1507 sum_r=550.57 x<0=0.02 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 53/401 | loss=0.6962 ev=0.449 agents=133 avg_r=2.0534 sum_r=525.66 x<0=0.02 elig=0.59 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 54/401 | loss=0.7625 ev=0.454 agents=231 avg_r=1.5343 sum_r=392.79 x<0=0.02 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 55/401 | loss=0.7736 ev=0.414 agents=97 avg_r=1.6580 sum_r=424.46 x<0=0.02 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.6s
+ 56/401 | loss=0.8158 ev=0.454 agents=108 avg_r=1.4593 sum_r=373.59 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.3s
+ 57/401 | loss=0.8160 ev=0.384 agents=140 avg_r=1.2522 sum_r=320.57 x<0=0.04 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 58/401 | loss=0.7392 ev=0.444 agents=534 avg_r=3.1169 sum_r=797.93 x<0=0.04 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.6s
+ 59/401 | loss=0.7812 ev=0.401 agents=112 avg_r=1.2579 sum_r=322.03 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 60/401 | loss=0.7958 ev=0.444 agents=64 avg_r=0.6857 sum_r=175.55 x<0=0.02 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 61/401 | loss=0.7650 ev=0.447 agents=303 avg_r=2.2103 sum_r=565.84 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 62/401 | loss=0.7742 ev=0.476 agents=82 avg_r=1.9037 sum_r=487.34 x<0=0.02 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.7s
+ 63/401 | loss=0.8447 ev=0.351 agents=66 avg_r=1.7917 sum_r=458.68 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 64/401 | loss=0.7786 ev=0.394 agents=93 avg_r=1.5619 sum_r=399.83 x<0=0.02 elig=0.60 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 65/401 | loss=0.7889 ev=0.429 agents=93 avg_r=3.1505 sum_r=806.54 x<0=0.03 elig=0.60 dorfler_tail=0.08 floor=0 sel=30 7.3s
+ 66/401 | loss=0.7486 ev=0.411 agents=82 avg_r=3.4632 sum_r=886.58 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.5s
+ 67/401 | loss=0.8361 ev=0.387 agents=89 avg_r=2.5091 sum_r=642.33 x<0=0.04 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 68/401 | loss=0.8049 ev=0.455 agents=1246 avg_r=1.6280 sum_r=416.76 x<0=0.02 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.6s
+ 69/401 | loss=0.7406 ev=0.469 agents=169 avg_r=3.0316 sum_r=776.10 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 70/401 | loss=0.7916 ev=0.431 agents=666 avg_r=1.2786 sum_r=327.33 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 71/401 | loss=0.7455 ev=0.448 agents=219 avg_r=1.7504 sum_r=448.09 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.4s
+ 72/401 | loss=0.7722 ev=0.408 agents=255 avg_r=3.3442 sum_r=856.10 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 8.0s
+ 73/401 | loss=0.7531 ev=0.422 agents=334 avg_r=2.3709 sum_r=606.95 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.5s
+ 74/401 | loss=0.7534 ev=0.445 agents=34 avg_r=4.3503 sum_r=1113.68 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 75/401 | loss=0.8434 ev=0.401 agents=144 avg_r=0.4869 sum_r=124.64 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.5s
+ 76/401 | loss=0.8142 ev=0.417 agents=728 avg_r=3.7060 sum_r=948.74 x<0=0.04 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.6s
+ 77/401 | loss=0.8339 ev=0.382 agents=607 avg_r=3.4045 sum_r=871.55 x<0=0.04 elig=0.61 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 78/401 | loss=0.9084 ev=0.413 agents=483 avg_r=1.5291 sum_r=391.46 x<0=0.05 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 7.5s
+ 79/401 | loss=0.8091 ev=0.434 agents=241 avg_r=5.4058 sum_r=1383.89 x<0=0.07 elig=0.61 dorfler_tail=0.08 floor=0 sel=33 8.1s
+ 80/401 | loss=0.8532 ev=0.444 agents=299 avg_r=3.2896 sum_r=842.13 x<0=0.06 elig=0.63 dorfler_tail=0.07 floor=0 sel=26 7.3s
+ 81/401 | loss=0.9505 ev=0.414 agents=812 avg_r=2.3540 sum_r=602.61 x<0=0.06 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 7.6s
+ 82/401 | loss=0.8656 ev=0.370 agents=557 avg_r=1.9931 sum_r=510.22 x<0=0.06 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.4s
+ 83/401 | loss=0.8751 ev=0.454 agents=34 avg_r=4.0672 sum_r=1041.20 x<0=0.07 elig=0.61 dorfler_tail=0.08 floor=0 sel=30 7.7s
+ 84/401 | loss=1.0631 ev=0.385 agents=527 avg_r=2.2599 sum_r=578.52 x<0=0.06 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 85/401 | loss=0.8861 ev=0.371 agents=110 avg_r=2.5793 sum_r=660.29 x<0=0.06 elig=0.61 dorfler_tail=0.07 floor=0 sel=26 7.2s
+ 86/401 | loss=1.0104 ev=0.399 agents=692 avg_r=3.1834 sum_r=814.94 x<0=0.07 elig=0.61 dorfler_tail=0.08 floor=0 sel=31 7.9s
+ 87/401 | loss=1.0484 ev=0.337 agents=265 avg_r=3.8907 sum_r=996.02 x<0=0.11 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 88/401 | loss=0.9365 ev=0.374 agents=1076 avg_r=3.6280 sum_r=928.78 x<0=0.10 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 89/401 | loss=1.0322 ev=0.379 agents=738 avg_r=3.2173 sum_r=823.64 x<0=0.09 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 90/401 | loss=1.0024 ev=0.440 agents=814 avg_r=4.1741 sum_r=1068.56 x<0=0.14 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 91/401 | loss=1.0702 ev=0.415 agents=103 avg_r=2.9575 sum_r=757.12 x<0=0.11 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.8s
+ 92/401 | loss=1.0768 ev=0.393 agents=222 avg_r=2.3631 sum_r=604.95 x<0=0.09 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 93/401 | loss=0.8536 ev=0.446 agents=817 avg_r=2.8966 sum_r=741.53 x<0=0.10 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 94/401 | loss=1.0326 ev=0.381 agents=263 avg_r=3.2866 sum_r=841.36 x<0=0.11 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.9s
+ 95/401 | loss=0.9661 ev=0.438 agents=457 avg_r=4.7830 sum_r=1224.46 x<0=0.14 elig=0.62 dorfler_tail=0.08 floor=0 sel=32 8.7s
+ 96/401 | loss=1.0307 ev=0.410 agents=146 avg_r=1.6996 sum_r=435.09 x<0=0.12 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 97/401 | loss=1.0506 ev=0.374 agents=1822 avg_r=4.6356 sum_r=1186.73 x<0=0.13 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 8.0s
+ 98/401 | loss=1.0002 ev=0.431 agents=247 avg_r=3.5428 sum_r=906.95 x<0=0.13 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 99/401 | loss=0.9919 ev=0.429 agents=438 avg_r=2.5796 sum_r=660.39 x<0=0.15 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 100/401 | loss=1.1839 ev=0.424 agents=80 avg_r=2.8253 sum_r=723.27 x<0=0.12 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.7s
+[Checkpoint] saved → checkpoints/model_iter0100.pt
+ 101/401 | loss=1.0950 ev=0.459 agents=897 avg_r=3.8530 sum_r=986.37 x<0=0.18 elig=0.63 dorfler_tail=0.08 floor=0 sel=28 7.8s
+ 102/401 | loss=1.0915 ev=0.416 agents=82 avg_r=4.4633 sum_r=1142.59 x<0=0.13 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 103/401 | loss=0.9961 ev=0.445 agents=228 avg_r=5.0288 sum_r=1287.37 x<0=0.16 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 104/401 | loss=1.0334 ev=0.390 agents=42 avg_r=4.6071 sum_r=1179.43 x<0=0.17 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 105/401 | loss=1.0714 ev=0.429 agents=375 avg_r=2.9595 sum_r=757.64 x<0=0.14 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 106/401 | loss=1.0984 ev=0.407 agents=34 avg_r=4.7091 sum_r=1205.54 x<0=0.16 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 107/401 | loss=1.0159 ev=0.444 agents=66 avg_r=5.0649 sum_r=1296.62 x<0=0.16 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 7.9s
+ 108/401 | loss=1.0474 ev=0.424 agents=92 avg_r=3.6964 sum_r=946.27 x<0=0.14 elig=0.63 dorfler_tail=0.07 floor=0 sel=26 7.4s
+ 109/401 | loss=1.0957 ev=0.424 agents=225 avg_r=4.3635 sum_r=1117.06 x<0=0.15 elig=0.62 dorfler_tail=0.07 floor=0 sel=30 7.9s
+ 110/401 | loss=1.0859 ev=0.396 agents=182 avg_r=2.8480 sum_r=729.08 x<0=0.15 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 111/401 | loss=0.9448 ev=0.422 agents=171 avg_r=4.1148 sum_r=1053.38 x<0=0.13 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 112/401 | loss=1.0549 ev=0.444 agents=175 avg_r=4.9807 sum_r=1275.05 x<0=0.15 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 7.8s
+ 113/401 | loss=1.0457 ev=0.431 agents=132 avg_r=4.3526 sum_r=1114.27 x<0=0.13 elig=0.63 dorfler_tail=0.07 floor=0 sel=31 8.0s
+ 114/401 | loss=0.9811 ev=0.431 agents=219 avg_r=1.9930 sum_r=510.21 x<0=0.11 elig=0.63 dorfler_tail=0.07 floor=0 sel=26 7.2s
+ 115/401 | loss=1.0557 ev=0.400 agents=39 avg_r=4.7748 sum_r=1222.35 x<0=0.17 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 116/401 | loss=1.1500 ev=0.432 agents=504 avg_r=4.6241 sum_r=1183.76 x<0=0.17 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 117/401 | loss=1.0410 ev=0.412 agents=39 avg_r=3.2529 sum_r=832.73 x<0=0.15 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 118/401 | loss=1.0850 ev=0.452 agents=333 avg_r=4.1276 sum_r=1056.66 x<0=0.16 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 8.3s
+ 119/401 | loss=1.0983 ev=0.418 agents=261 avg_r=4.2111 sum_r=1078.04 x<0=0.16 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.9s
+ 120/401 | loss=1.1755 ev=0.452 agents=201 avg_r=5.2366 sum_r=1340.57 x<0=0.17 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 121/401 | loss=1.2066 ev=0.441 agents=101 avg_r=4.9395 sum_r=1264.51 x<0=0.17 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 8.0s
+ 122/401 | loss=1.1325 ev=0.462 agents=411 avg_r=3.0792 sum_r=788.29 x<0=0.21 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 123/401 | loss=1.0326 ev=0.444 agents=625 avg_r=4.2090 sum_r=1077.51 x<0=0.17 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 124/401 | loss=1.1518 ev=0.423 agents=157 avg_r=4.9204 sum_r=1259.61 x<0=0.19 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 125/401 | loss=1.1643 ev=0.456 agents=77 avg_r=5.4202 sum_r=1387.57 x<0=0.17 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 126/401 | loss=1.1922 ev=0.445 agents=112 avg_r=4.2411 sum_r=1085.71 x<0=0.17 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 127/401 | loss=1.3675 ev=0.408 agents=118 avg_r=5.1671 sum_r=1322.77 x<0=0.17 elig=0.64 dorfler_tail=0.08 floor=0 sel=31 7.9s
+ 128/401 | loss=1.0731 ev=0.426 agents=341 avg_r=4.4974 sum_r=1151.33 x<0=0.15 elig=0.64 dorfler_tail=0.07 floor=0 sel=25 7.3s
+ 129/401 | loss=1.2627 ev=0.413 agents=143 avg_r=2.6131 sum_r=668.96 x<0=0.14 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 130/401 | loss=1.2541 ev=0.396 agents=919 avg_r=5.7318 sum_r=1467.35 x<0=0.18 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 131/401 | loss=1.1595 ev=0.459 agents=568 avg_r=5.8106 sum_r=1487.51 x<0=0.14 elig=0.64 dorfler_tail=0.07 floor=0 sel=31 7.9s
+ 132/401 | loss=1.0261 ev=0.464 agents=159 avg_r=3.7017 sum_r=947.63 x<0=0.15 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.4s
+ 133/401 | loss=1.1509 ev=0.457 agents=180 avg_r=4.5674 sum_r=1169.27 x<0=0.13 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 134/401 | loss=1.2367 ev=0.399 agents=34 avg_r=3.3756 sum_r=864.15 x<0=0.12 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 135/401 | loss=1.2713 ev=0.472 agents=42 avg_r=6.9697 sum_r=1784.24 x<0=0.11 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 136/401 | loss=1.1949 ev=0.393 agents=252 avg_r=2.6102 sum_r=668.20 x<0=0.11 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.3s
+ 137/401 | loss=1.1157 ev=0.439 agents=1066 avg_r=5.3136 sum_r=1360.29 x<0=0.09 elig=0.63 dorfler_tail=0.07 floor=0 sel=31 7.9s
+ 138/401 | loss=1.0746 ev=0.449 agents=214 avg_r=4.6555 sum_r=1191.80 x<0=0.12 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 139/401 | loss=1.1177 ev=0.460 agents=1208 avg_r=3.3845 sum_r=866.43 x<0=0.08 elig=0.63 dorfler_tail=0.07 floor=0 sel=31 7.9s
+ 140/401 | loss=1.1579 ev=0.498 agents=74 avg_r=3.9158 sum_r=1002.45 x<0=0.10 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 141/401 | loss=1.1397 ev=0.452 agents=227 avg_r=4.6873 sum_r=1199.94 x<0=0.11 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 8.1s
+ 142/401 | loss=1.0311 ev=0.451 agents=272 avg_r=4.3273 sum_r=1107.79 x<0=0.09 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 143/401 | loss=1.2372 ev=0.429 agents=586 avg_r=3.5519 sum_r=909.28 x<0=0.07 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.8s
+ 144/401 | loss=1.1732 ev=0.431 agents=137 avg_r=5.6718 sum_r=1451.99 x<0=0.10 elig=0.64 dorfler_tail=0.07 floor=0 sel=31 8.1s
+ 145/401 | loss=1.1318 ev=0.423 agents=1531 avg_r=3.6947 sum_r=945.84 x<0=0.07 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 7.8s
+ 146/401 | loss=1.2082 ev=0.371 agents=468 avg_r=2.9619 sum_r=758.24 x<0=0.08 elig=0.63 dorfler_tail=0.07 floor=0 sel=26 7.3s
+ 147/401 | loss=1.0488 ev=0.490 agents=34 avg_r=4.6683 sum_r=1195.08 x<0=0.09 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 148/401 | loss=1.0228 ev=0.425 agents=199 avg_r=3.9396 sum_r=1008.54 x<0=0.10 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 7.6s
+ 149/401 | loss=1.1164 ev=0.460 agents=34 avg_r=5.2988 sum_r=1356.48 x<0=0.11 elig=0.63 dorfler_tail=0.08 floor=0 sel=29 7.8s
+ 150/401 | loss=1.2006 ev=0.420 agents=224 avg_r=4.6276 sum_r=1184.65 x<0=0.14 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.6s
+[Checkpoint] saved → checkpoints/model_iter0150.pt
+ 151/401 | loss=1.1592 ev=0.461 agents=219 avg_r=3.2275 sum_r=826.23 x<0=0.14 elig=0.64 dorfler_tail=0.07 floor=0 sel=26 7.3s
+ 152/401 | loss=1.1567 ev=0.491 agents=66 avg_r=5.4326 sum_r=1390.76 x<0=0.13 elig=0.64 dorfler_tail=0.07 floor=0 sel=32 8.1s
+ 153/401 | loss=1.0849 ev=0.410 agents=44 avg_r=3.2665 sum_r=836.23 x<0=0.13 elig=0.63 dorfler_tail=0.07 floor=0 sel=25 7.2s
+ 154/401 | loss=1.2139 ev=0.451 agents=144 avg_r=5.5749 sum_r=1427.18 x<0=0.13 elig=0.64 dorfler_tail=0.07 floor=0 sel=30 7.8s
+ 155/401 | loss=1.2641 ev=0.374 agents=72 avg_r=3.8995 sum_r=998.28 x<0=0.08 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 156/401 | loss=1.1181 ev=0.448 agents=305 avg_r=4.0441 sum_r=1035.29 x<0=0.08 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.4s
+ 157/401 | loss=1.1287 ev=0.426 agents=193 avg_r=5.2623 sum_r=1347.16 x<0=0.09 elig=0.63 dorfler_tail=0.08 floor=0 sel=31 7.9s
+ 158/401 | loss=1.0094 ev=0.439 agents=112 avg_r=3.9313 sum_r=1006.42 x<0=0.10 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 159/401 | loss=1.2058 ev=0.424 agents=208 avg_r=4.5753 sum_r=1171.28 x<0=0.10 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 160/401 | loss=1.0749 ev=0.436 agents=272 avg_r=4.3559 sum_r=1115.11 x<0=0.10 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 161/401 | loss=1.2113 ev=0.476 agents=157 avg_r=5.9866 sum_r=1532.58 x<0=0.09 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 7.9s
+ 162/401 | loss=1.2021 ev=0.410 agents=178 avg_r=2.3998 sum_r=614.36 x<0=0.07 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 163/401 | loss=1.2304 ev=0.489 agents=1031 avg_r=4.5909 sum_r=1175.26 x<0=0.08 elig=0.63 dorfler_tail=0.07 floor=0 sel=31 8.3s
+ 164/401 | loss=1.1285 ev=0.477 agents=932 avg_r=4.0162 sum_r=1028.14 x<0=0.07 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 165/401 | loss=1.2368 ev=0.421 agents=222 avg_r=5.6582 sum_r=1448.51 x<0=0.08 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 166/401 | loss=1.1362 ev=0.451 agents=41 avg_r=4.6464 sum_r=1189.47 x<0=0.05 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 167/401 | loss=1.1229 ev=0.462 agents=562 avg_r=4.0773 sum_r=1043.78 x<0=0.06 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 7.8s
+ 168/401 | loss=1.1106 ev=0.454 agents=92 avg_r=3.3590 sum_r=859.91 x<0=0.06 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 169/401 | loss=1.1281 ev=0.476 agents=280 avg_r=4.4418 sum_r=1137.09 x<0=0.06 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 7.8s
+ 170/401 | loss=1.1614 ev=0.480 agents=89 avg_r=5.0368 sum_r=1289.41 x<0=0.07 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 171/401 | loss=1.1519 ev=0.472 agents=798 avg_r=4.8366 sum_r=1238.17 x<0=0.07 elig=0.65 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 172/401 | loss=1.1491 ev=0.486 agents=1228 avg_r=3.9325 sum_r=1006.73 x<0=0.06 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 173/401 | loss=1.1892 ev=0.433 agents=34 avg_r=5.7898 sum_r=1482.19 x<0=0.07 elig=0.64 dorfler_tail=0.07 floor=0 sel=31 7.9s
+ 174/401 | loss=1.2609 ev=0.441 agents=34 avg_r=4.9001 sum_r=1254.42 x<0=0.09 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 175/401 | loss=1.0890 ev=0.490 agents=302 avg_r=4.3919 sum_r=1124.32 x<0=0.09 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.4s
+ 176/401 | loss=1.2669 ev=0.509 agents=413 avg_r=5.4385 sum_r=1392.26 x<0=0.08 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 177/401 | loss=1.1942 ev=0.431 agents=34 avg_r=5.7676 sum_r=1476.51 x<0=0.05 elig=0.63 dorfler_tail=0.07 floor=0 sel=31 7.9s
+ 178/401 | loss=1.2717 ev=0.397 agents=708 avg_r=3.3482 sum_r=857.14 x<0=0.05 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.3s
+ 179/401 | loss=1.2435 ev=0.422 agents=132 avg_r=4.4943 sum_r=1150.54 x<0=0.05 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 180/401 | loss=1.2206 ev=0.416 agents=1685 avg_r=6.0635 sum_r=1552.26 x<0=0.05 elig=0.63 dorfler_tail=0.07 floor=0 sel=31 7.8s
+ 181/401 | loss=1.2401 ev=0.426 agents=74 avg_r=4.4630 sum_r=1142.54 x<0=0.03 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 182/401 | loss=1.1143 ev=0.503 agents=101 avg_r=5.8115 sum_r=1487.76 x<0=0.05 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 183/401 | loss=1.1343 ev=0.482 agents=1198 avg_r=4.8445 sum_r=1240.20 x<0=0.05 elig=0.64 dorfler_tail=0.07 floor=0 sel=31 7.9s
+ 184/401 | loss=1.1171 ev=0.467 agents=146 avg_r=3.7889 sum_r=969.97 x<0=0.05 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.4s
+ 185/401 | loss=1.1019 ev=0.453 agents=55 avg_r=3.1546 sum_r=807.57 x<0=0.04 elig=0.64 dorfler_tail=0.07 floor=0 sel=26 7.3s
+ 186/401 | loss=1.2893 ev=0.487 agents=241 avg_r=7.1095 sum_r=1820.03 x<0=0.05 elig=0.64 dorfler_tail=0.07 floor=0 sel=30 7.8s
+ 187/401 | loss=1.2431 ev=0.484 agents=1392 avg_r=4.2931 sum_r=1099.02 x<0=0.03 elig=0.64 dorfler_tail=0.07 floor=0 sel=30 8.2s
+ 188/401 | loss=1.2041 ev=0.489 agents=371 avg_r=4.5463 sum_r=1163.85 x<0=0.03 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 8.0s
+ 189/401 | loss=1.1026 ev=0.500 agents=84 avg_r=5.3215 sum_r=1362.30 x<0=0.04 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 190/401 | loss=1.1617 ev=0.490 agents=1313 avg_r=3.7937 sum_r=971.19 x<0=0.04 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 191/401 | loss=1.2295 ev=0.445 agents=92 avg_r=5.4176 sum_r=1386.91 x<0=0.04 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 192/401 | loss=1.1866 ev=0.459 agents=101 avg_r=4.6249 sum_r=1183.98 x<0=0.03 elig=0.64 dorfler_tail=0.07 floor=0 sel=30 7.8s
+ 193/401 | loss=1.1729 ev=0.450 agents=85 avg_r=4.5923 sum_r=1175.63 x<0=0.03 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 194/401 | loss=1.1481 ev=0.475 agents=144 avg_r=3.5323 sum_r=904.26 x<0=0.03 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 195/401 | loss=1.0329 ev=0.503 agents=452 avg_r=5.7863 sum_r=1481.30 x<0=0.02 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 196/401 | loss=1.1833 ev=0.481 agents=80 avg_r=5.2709 sum_r=1349.34 x<0=0.04 elig=0.64 dorfler_tail=0.07 floor=0 sel=30 7.7s
+ 197/401 | loss=1.0276 ev=0.526 agents=345 avg_r=4.4862 sum_r=1148.48 x<0=0.04 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.4s
+ 198/401 | loss=1.1872 ev=0.502 agents=112 avg_r=4.0325 sum_r=1032.33 x<0=0.04 elig=0.64 dorfler_tail=0.07 floor=0 sel=31 7.8s
+ 199/401 | loss=1.1178 ev=0.506 agents=55 avg_r=5.9643 sum_r=1526.87 x<0=0.04 elig=0.64 dorfler_tail=0.07 floor=0 sel=30 7.8s
+ 200/401 | loss=1.1306 ev=0.477 agents=383 avg_r=3.5642 sum_r=912.45 x<0=0.03 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.5s
+[Checkpoint] saved → checkpoints/model_iter0200.pt
+ 201/401 | loss=1.2014 ev=0.489 agents=358 avg_r=4.1907 sum_r=1072.82 x<0=0.04 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 202/401 | loss=1.0706 ev=0.486 agents=1012 avg_r=6.4612 sum_r=1654.08 x<0=0.03 elig=0.64 dorfler_tail=0.07 floor=0 sel=31 7.9s
+ 203/401 | loss=1.1745 ev=0.434 agents=112 avg_r=4.4139 sum_r=1129.95 x<0=0.03 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 204/401 | loss=1.1475 ev=0.441 agents=66 avg_r=2.0276 sum_r=519.07 x<0=0.03 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.3s
+ 205/401 | loss=1.2463 ev=0.448 agents=608 avg_r=4.3842 sum_r=1122.34 x<0=0.02 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 206/401 | loss=1.0930 ev=0.507 agents=199 avg_r=3.6852 sum_r=943.42 x<0=0.04 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.4s
+ 207/401 | loss=1.0337 ev=0.492 agents=78 avg_r=5.9192 sum_r=1515.31 x<0=0.04 elig=0.63 dorfler_tail=0.08 floor=0 sel=31 7.9s
+ 208/401 | loss=1.0812 ev=0.511 agents=239 avg_r=2.7268 sum_r=698.05 x<0=0.03 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 209/401 | loss=1.1193 ev=0.488 agents=290 avg_r=4.8390 sum_r=1238.78 x<0=0.03 elig=0.63 dorfler_tail=0.08 floor=0 sel=31 8.3s
+ 210/401 | loss=1.0216 ev=0.512 agents=560 avg_r=4.4400 sum_r=1136.65 x<0=0.04 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.8s
+ 211/401 | loss=1.1425 ev=0.489 agents=82 avg_r=4.0555 sum_r=1038.20 x<0=0.04 elig=0.63 dorfler_tail=0.08 floor=0 sel=30 8.0s
+ 212/401 | loss=1.0860 ev=0.510 agents=159 avg_r=3.0865 sum_r=790.16 x<0=0.02 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 7.9s
+ 213/401 | loss=1.1143 ev=0.461 agents=466 avg_r=4.2296 sum_r=1082.79 x<0=0.04 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 214/401 | loss=1.1696 ev=0.455 agents=594 avg_r=3.4831 sum_r=891.68 x<0=0.03 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 7.9s
+ 215/401 | loss=0.9946 ev=0.541 agents=34 avg_r=4.5702 sum_r=1169.98 x<0=0.05 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.7s
+ 216/401 | loss=0.9747 ev=0.476 agents=118 avg_r=1.9068 sum_r=488.14 x<0=0.03 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.4s
+ 217/401 | loss=1.0586 ev=0.485 agents=463 avg_r=4.5953 sum_r=1176.40 x<0=0.03 elig=0.63 dorfler_tail=0.08 floor=0 sel=32 8.0s
+ 218/401 | loss=0.9961 ev=0.517 agents=782 avg_r=4.2842 sum_r=1096.75 x<0=0.02 elig=0.62 dorfler_tail=0.08 floor=0 sel=31 7.8s
+ 219/401 | loss=0.9959 ev=0.509 agents=455 avg_r=3.9179 sum_r=1002.98 x<0=0.03 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.4s
+ 220/401 | loss=1.0537 ev=0.484 agents=104 avg_r=3.2154 sum_r=823.14 x<0=0.02 elig=0.63 dorfler_tail=0.07 floor=0 sel=32 8.0s
+ 221/401 | loss=1.0243 ev=0.528 agents=367 avg_r=3.3715 sum_r=863.11 x<0=0.03 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.4s
+ 222/401 | loss=1.0120 ev=0.533 agents=244 avg_r=3.1987 sum_r=818.87 x<0=0.02 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 7.8s
+ 223/401 | loss=1.0247 ev=0.525 agents=544 avg_r=4.3206 sum_r=1106.08 x<0=0.02 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.5s
+ 224/401 | loss=1.1590 ev=0.478 agents=86 avg_r=4.5344 sum_r=1160.79 x<0=0.04 elig=0.64 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 225/401 | loss=1.2170 ev=0.509 agents=154 avg_r=2.9427 sum_r=753.34 x<0=0.02 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 226/401 | loss=1.0551 ev=0.507 agents=688 avg_r=4.8525 sum_r=1242.24 x<0=0.02 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 227/401 | loss=1.0929 ev=0.495 agents=1389 avg_r=3.4812 sum_r=891.19 x<0=0.03 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 228/401 | loss=1.0829 ev=0.484 agents=552 avg_r=4.0013 sum_r=1024.33 x<0=0.02 elig=0.62 dorfler_tail=0.08 floor=0 sel=32 7.8s
+ 229/401 | loss=1.0821 ev=0.543 agents=537 avg_r=4.6780 sum_r=1197.58 x<0=0.03 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.4s
+ 230/401 | loss=1.0237 ev=0.517 agents=245 avg_r=4.9465 sum_r=1266.29 x<0=0.02 elig=0.63 dorfler_tail=0.08 floor=0 sel=30 7.8s
+ 231/401 | loss=0.9584 ev=0.520 agents=80 avg_r=3.6329 sum_r=930.02 x<0=0.03 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 232/401 | loss=1.0787 ev=0.525 agents=34 avg_r=3.9045 sum_r=999.56 x<0=0.02 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 7.9s
+ 233/401 | loss=0.9447 ev=0.450 agents=78 avg_r=1.3955 sum_r=357.24 x<0=0.02 elig=0.62 dorfler_tail=0.07 floor=0 sel=26 7.9s
+ 234/401 | loss=0.9411 ev=0.544 agents=1678 avg_r=4.2359 sum_r=1084.38 x<0=0.02 elig=0.62 dorfler_tail=0.08 floor=0 sel=33 8.5s
+ 235/401 | loss=1.0497 ev=0.498 agents=1671 avg_r=2.7100 sum_r=693.76 x<0=0.02 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 236/401 | loss=1.0309 ev=0.519 agents=34 avg_r=5.2648 sum_r=1347.78 x<0=0.02 elig=0.63 dorfler_tail=0.08 floor=0 sel=32 8.2s
+ 237/401 | loss=1.0213 ev=0.455 agents=89 avg_r=2.4790 sum_r=634.62 x<0=0.03 elig=0.63 dorfler_tail=0.07 floor=0 sel=26 7.2s
+ 238/401 | loss=0.9939 ev=0.543 agents=197 avg_r=4.4294 sum_r=1133.92 x<0=0.03 elig=0.62 dorfler_tail=0.08 floor=0 sel=31 8.0s
+ 239/401 | loss=0.9712 ev=0.480 agents=764 avg_r=1.1436 sum_r=292.76 x<0=0.02 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 7.6s
+ 240/401 | loss=1.0520 ev=0.520 agents=98 avg_r=3.5913 sum_r=919.36 x<0=0.02 elig=0.63 dorfler_tail=0.08 floor=0 sel=29 7.7s
+ 241/401 | loss=1.0733 ev=0.529 agents=242 avg_r=3.8688 sum_r=990.40 x<0=0.03 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 7.9s
+ 242/401 | loss=0.9550 ev=0.471 agents=334 avg_r=1.7380 sum_r=444.92 x<0=0.03 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.4s
+ 243/401 | loss=1.0333 ev=0.485 agents=219 avg_r=2.4626 sum_r=630.44 x<0=0.04 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 7.7s
+ 244/401 | loss=0.9276 ev=0.522 agents=34 avg_r=3.0563 sum_r=782.41 x<0=0.04 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 245/401 | loss=0.9300 ev=0.556 agents=707 avg_r=3.2084 sum_r=821.35 x<0=0.04 elig=0.62 dorfler_tail=0.08 floor=0 sel=31 7.8s
+ 246/401 | loss=0.9332 ev=0.523 agents=90 avg_r=2.4516 sum_r=627.62 x<0=0.03 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 247/401 | loss=0.8789 ev=0.527 agents=34 avg_r=2.0551 sum_r=526.11 x<0=0.04 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.7s
+ 248/401 | loss=0.9587 ev=0.532 agents=81 avg_r=3.7530 sum_r=960.77 x<0=0.04 elig=0.61 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 249/401 | loss=0.9774 ev=0.505 agents=431 avg_r=2.2023 sum_r=563.78 x<0=0.03 elig=0.61 dorfler_tail=0.08 floor=0 sel=31 7.8s
+ 250/401 | loss=0.9413 ev=0.535 agents=299 avg_r=3.2959 sum_r=843.75 x<0=0.04 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 7.9s
+[Checkpoint] saved → checkpoints/model_iter0250.pt
+ 251/401 | loss=0.8520 ev=0.529 agents=179 avg_r=1.5290 sum_r=391.43 x<0=0.03 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 7.4s
+ 252/401 | loss=0.9216 ev=0.545 agents=1237 avg_r=3.0161 sum_r=772.13 x<0=0.04 elig=0.62 dorfler_tail=0.07 floor=0 sel=30 7.7s
+ 253/401 | loss=0.9574 ev=0.523 agents=34 avg_r=2.6567 sum_r=680.11 x<0=0.05 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 254/401 | loss=0.8550 ev=0.545 agents=438 avg_r=3.3394 sum_r=854.87 x<0=0.04 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 7.7s
+ 255/401 | loss=0.9844 ev=0.498 agents=1420 avg_r=2.4418 sum_r=625.11 x<0=0.06 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 256/401 | loss=0.9256 ev=0.573 agents=571 avg_r=5.8027 sum_r=1485.49 x<0=0.05 elig=0.62 dorfler_tail=0.08 floor=0 sel=31 8.5s
+ 257/401 | loss=0.9898 ev=0.483 agents=95 avg_r=1.5702 sum_r=401.96 x<0=0.04 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.7s
+ 258/401 | loss=0.9519 ev=0.534 agents=199 avg_r=2.4135 sum_r=617.85 x<0=0.05 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.7s
+ 259/401 | loss=0.8724 ev=0.542 agents=235 avg_r=4.1436 sum_r=1060.77 x<0=0.04 elig=0.62 dorfler_tail=0.08 floor=0 sel=31 8.0s
+ 260/401 | loss=0.9030 ev=0.547 agents=306 avg_r=3.4969 sum_r=895.20 x<0=0.03 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 8.0s
+ 261/401 | loss=0.8940 ev=0.553 agents=278 avg_r=1.2701 sum_r=325.14 x<0=0.03 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.7s
+ 262/401 | loss=0.9520 ev=0.522 agents=247 avg_r=2.2571 sum_r=577.81 x<0=0.05 elig=0.62 dorfler_tail=0.07 floor=0 sel=26 7.2s
+ 263/401 | loss=0.9901 ev=0.538 agents=34 avg_r=3.7187 sum_r=952.00 x<0=0.05 elig=0.62 dorfler_tail=0.08 floor=0 sel=31 7.9s
+ 264/401 | loss=0.8780 ev=0.551 agents=210 avg_r=2.6562 sum_r=680.00 x<0=0.03 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 7.8s
+ 265/401 | loss=0.9646 ev=0.551 agents=1333 avg_r=2.6470 sum_r=677.63 x<0=0.07 elig=0.63 dorfler_tail=0.08 floor=0 sel=26 7.3s
+ 266/401 | loss=0.8954 ev=0.553 agents=1474 avg_r=4.4314 sum_r=1134.44 x<0=0.05 elig=0.62 dorfler_tail=0.08 floor=0 sel=34 8.4s
+ 267/401 | loss=0.9252 ev=0.547 agents=219 avg_r=1.3921 sum_r=356.39 x<0=0.07 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.5s
+ 268/401 | loss=0.9428 ev=0.529 agents=448 avg_r=2.0273 sum_r=518.98 x<0=0.08 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.5s
+ 269/401 | loss=1.0055 ev=0.512 agents=119 avg_r=3.3292 sum_r=852.28 x<0=0.06 elig=0.61 dorfler_tail=0.08 floor=0 sel=30 7.7s
+ 270/401 | loss=0.8147 ev=0.546 agents=713 avg_r=2.1123 sum_r=540.76 x<0=0.08 elig=0.62 dorfler_tail=0.08 floor=0 sel=27 7.5s
+ 271/401 | loss=0.8906 ev=0.516 agents=283 avg_r=1.6996 sum_r=435.11 x<0=0.10 elig=0.61 dorfler_tail=0.08 floor=0 sel=30 7.6s
+ 272/401 | loss=0.8740 ev=0.539 agents=615 avg_r=2.0937 sum_r=536.00 x<0=0.09 elig=0.61 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 273/401 | loss=0.8926 ev=0.534 agents=148 avg_r=3.3738 sum_r=863.69 x<0=0.06 elig=0.62 dorfler_tail=0.08 floor=0 sel=31 8.0s
+ 274/401 | loss=0.9262 ev=0.517 agents=1373 avg_r=1.4594 sum_r=373.60 x<0=0.10 elig=0.61 dorfler_tail=0.08 floor=0 sel=27 7.4s
+ 275/401 | loss=0.8819 ev=0.544 agents=534 avg_r=3.1571 sum_r=808.21 x<0=0.06 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 7.7s
+ 276/401 | loss=0.9410 ev=0.555 agents=197 avg_r=1.4638 sum_r=374.73 x<0=0.06 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 277/401 | loss=0.9281 ev=0.544 agents=461 avg_r=3.8103 sum_r=975.44 x<0=0.06 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 8.2s
+ 278/401 | loss=0.9413 ev=0.482 agents=132 avg_r=0.8562 sum_r=219.19 x<0=0.07 elig=0.61 dorfler_tail=0.08 floor=0 sel=27 7.6s
+ 279/401 | loss=1.0616 ev=0.511 agents=387 avg_r=2.8525 sum_r=730.25 x<0=0.04 elig=0.62 dorfler_tail=0.08 floor=0 sel=32 8.2s
+ 280/401 | loss=0.8064 ev=0.565 agents=34 avg_r=2.3635 sum_r=605.05 x<0=0.08 elig=0.61 dorfler_tail=0.08 floor=0 sel=30 8.0s
+ 281/401 | loss=0.9595 ev=0.516 agents=42 avg_r=1.2882 sum_r=329.77 x<0=0.08 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 7.7s
+ 282/401 | loss=0.8745 ev=0.544 agents=212 avg_r=2.6701 sum_r=683.56 x<0=0.08 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 7.8s
+ 283/401 | loss=0.8034 ev=0.556 agents=700 avg_r=1.2154 sum_r=311.15 x<0=0.09 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 7.6s
+ 284/401 | loss=0.9041 ev=0.526 agents=165 avg_r=3.3568 sum_r=859.33 x<0=0.09 elig=0.61 dorfler_tail=0.08 floor=0 sel=31 7.9s
+ 285/401 | loss=0.8815 ev=0.556 agents=92 avg_r=3.1372 sum_r=803.13 x<0=0.10 elig=0.61 dorfler_tail=0.08 floor=0 sel=29 7.7s
+ 286/401 | loss=0.8307 ev=0.536 agents=118 avg_r=1.5978 sum_r=409.03 x<0=0.06 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 7.6s
+ 287/401 | loss=0.8403 ev=0.562 agents=423 avg_r=2.7292 sum_r=698.68 x<0=0.10 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.8s
+ 288/401 | loss=0.9074 ev=0.520 agents=169 avg_r=3.6068 sum_r=923.33 x<0=0.07 elig=0.62 dorfler_tail=0.08 floor=0 sel=32 7.9s
+ 289/401 | loss=0.9122 ev=0.561 agents=206 avg_r=2.3035 sum_r=589.70 x<0=0.07 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 290/401 | loss=0.9271 ev=0.523 agents=472 avg_r=1.9889 sum_r=509.16 x<0=0.12 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 7.5s
+ 291/401 | loss=0.8706 ev=0.563 agents=811 avg_r=2.7751 sum_r=710.43 x<0=0.10 elig=0.61 dorfler_tail=0.08 floor=0 sel=30 7.8s
+ 292/401 | loss=0.9530 ev=0.524 agents=80 avg_r=2.5786 sum_r=660.13 x<0=0.11 elig=0.62 dorfler_tail=0.08 floor=0 sel=27 7.4s
+ 293/401 | loss=0.8116 ev=0.540 agents=154 avg_r=0.2428 sum_r=62.17 x<0=0.11 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.3s
+ 294/401 | loss=0.9140 ev=0.518 agents=175 avg_r=2.3269 sum_r=595.68 x<0=0.09 elig=0.61 dorfler_tail=0.08 floor=0 sel=30 7.8s
+ 295/401 | loss=0.8169 ev=0.527 agents=220 avg_r=3.0412 sum_r=778.55 x<0=0.10 elig=0.60 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 296/401 | loss=0.8810 ev=0.542 agents=1189 avg_r=2.2746 sum_r=582.29 x<0=0.14 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.7s
+ 297/401 | loss=0.8664 ev=0.514 agents=120 avg_r=2.9741 sum_r=761.37 x<0=0.11 elig=0.61 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 298/401 | loss=0.7806 ev=0.525 agents=399 avg_r=1.6251 sum_r=416.02 x<0=0.11 elig=0.60 dorfler_tail=0.09 floor=0 sel=32 7.6s
+ 299/401 | loss=0.7862 ev=0.541 agents=253 avg_r=0.9686 sum_r=247.97 x<0=0.16 elig=0.61 dorfler_tail=0.08 floor=0 sel=27 7.2s
+ 300/401 | loss=0.8033 ev=0.530 agents=400 avg_r=1.6370 sum_r=419.07 x<0=0.10 elig=0.60 dorfler_tail=0.09 floor=0 sel=34 8.1s
+[Checkpoint] saved → checkpoints/model_iter0300.pt
+ 301/401 | loss=0.6913 ev=0.558 agents=86 avg_r=2.2967 sum_r=587.97 x<0=0.17 elig=0.61 dorfler_tail=0.08 floor=0 sel=27 7.8s
+ 302/401 | loss=0.8170 ev=0.548 agents=581 avg_r=0.8235 sum_r=210.82 x<0=0.15 elig=0.60 dorfler_tail=0.08 floor=0 sel=30 7.8s
+ 303/401 | loss=0.6984 ev=0.563 agents=1661 avg_r=-0.4295 sum_r=-109.96 x<0=0.16 elig=0.60 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 304/401 | loss=0.7311 ev=0.548 agents=224 avg_r=0.8700 sum_r=222.71 x<0=0.14 elig=0.60 dorfler_tail=0.08 floor=0 sel=30 7.7s
+ 305/401 | loss=0.7374 ev=0.523 agents=36 avg_r=1.8769 sum_r=480.49 x<0=0.18 elig=0.60 dorfler_tail=0.08 floor=0 sel=28 7.4s
+ 306/401 | loss=0.7575 ev=0.528 agents=34 avg_r=0.2656 sum_r=67.99 x<0=0.12 elig=0.60 dorfler_tail=0.09 floor=0 sel=32 7.8s
+ 307/401 | loss=0.7143 ev=0.558 agents=383 avg_r=1.9704 sum_r=504.43 x<0=0.15 elig=0.60 dorfler_tail=0.08 floor=0 sel=33 7.7s
+ 308/401 | loss=0.6706 ev=0.578 agents=354 avg_r=1.0502 sum_r=268.85 x<0=0.16 elig=0.60 dorfler_tail=0.08 floor=0 sel=28 7.3s
+ 309/401 | loss=0.7886 ev=0.535 agents=658 avg_r=0.7953 sum_r=203.59 x<0=0.16 elig=0.60 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 310/401 | loss=0.7315 ev=0.544 agents=101 avg_r=2.9009 sum_r=742.62 x<0=0.15 elig=0.60 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 311/401 | loss=0.8253 ev=0.511 agents=133 avg_r=-0.0058 sum_r=-1.49 x<0=0.14 elig=0.61 dorfler_tail=0.08 floor=0 sel=30 7.6s
+ 312/401 | loss=0.7325 ev=0.559 agents=710 avg_r=1.4958 sum_r=382.94 x<0=0.17 elig=0.60 dorfler_tail=0.08 floor=0 sel=28 7.3s
+ 313/401 | loss=0.7200 ev=0.561 agents=815 avg_r=2.1457 sum_r=549.29 x<0=0.14 elig=0.60 dorfler_tail=0.08 floor=0 sel=31 7.8s
+ 314/401 | loss=0.7983 ev=0.533 agents=112 avg_r=2.3176 sum_r=593.31 x<0=0.19 elig=0.60 dorfler_tail=0.08 floor=0 sel=31 7.6s
+ 315/401 | loss=0.7438 ev=0.549 agents=1189 avg_r=0.7720 sum_r=197.64 x<0=0.14 elig=0.60 dorfler_tail=0.08 floor=0 sel=29 7.4s
+ 316/401 | loss=0.7035 ev=0.572 agents=255 avg_r=1.6356 sum_r=418.72 x<0=0.14 elig=0.60 dorfler_tail=0.08 floor=0 sel=29 7.4s
+ 317/401 | loss=0.7101 ev=0.532 agents=34 avg_r=3.0508 sum_r=781.01 x<0=0.14 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 318/401 | loss=0.8912 ev=0.501 agents=355 avg_r=1.0975 sum_r=280.95 x<0=0.19 elig=0.60 dorfler_tail=0.08 floor=0 sel=30 7.5s
+ 319/401 | loss=0.7239 ev=0.544 agents=248 avg_r=1.5235 sum_r=390.01 x<0=0.15 elig=0.60 dorfler_tail=0.08 floor=0 sel=30 7.5s
+ 320/401 | loss=0.7092 ev=0.565 agents=925 avg_r=1.4157 sum_r=362.42 x<0=0.16 elig=0.60 dorfler_tail=0.08 floor=0 sel=29 7.4s
+ 321/401 | loss=0.7461 ev=0.514 agents=311 avg_r=0.2240 sum_r=57.35 x<0=0.14 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 7.2s
+ 322/401 | loss=0.7413 ev=0.558 agents=963 avg_r=2.1983 sum_r=562.76 x<0=0.15 elig=0.60 dorfler_tail=0.08 floor=0 sel=31 7.7s
+ 323/401 | loss=0.7404 ev=0.539 agents=564 avg_r=-0.1535 sum_r=-39.29 x<0=0.14 elig=0.60 dorfler_tail=0.08 floor=0 sel=28 7.6s
+ 324/401 | loss=0.7739 ev=0.520 agents=377 avg_r=2.4348 sum_r=623.30 x<0=0.17 elig=0.60 dorfler_tail=0.08 floor=0 sel=31 7.9s
+ 325/401 | loss=0.7664 ev=0.514 agents=92 avg_r=-0.3153 sum_r=-80.72 x<0=0.16 elig=0.60 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 326/401 | loss=0.6448 ev=0.571 agents=1442 avg_r=2.9909 sum_r=765.66 x<0=0.17 elig=0.60 dorfler_tail=0.08 floor=0 sel=31 7.7s
+ 327/401 | loss=0.7037 ev=0.571 agents=1470 avg_r=1.2222 sum_r=312.89 x<0=0.13 elig=0.59 dorfler_tail=0.09 floor=0 sel=28 7.4s
+ 328/401 | loss=0.6932 ev=0.561 agents=301 avg_r=0.1858 sum_r=47.56 x<0=0.18 elig=0.61 dorfler_tail=0.08 floor=0 sel=27 7.3s
+ 329/401 | loss=0.7244 ev=0.546 agents=72 avg_r=0.3477 sum_r=89.02 x<0=0.17 elig=0.60 dorfler_tail=0.08 floor=0 sel=30 7.5s
+ 330/401 | loss=0.7251 ev=0.550 agents=415 avg_r=1.7594 sum_r=450.41 x<0=0.15 elig=0.60 dorfler_tail=0.08 floor=0 sel=30 7.5s
+ 331/401 | loss=0.6579 ev=0.571 agents=1310 avg_r=0.9986 sum_r=255.65 x<0=0.15 elig=0.60 dorfler_tail=0.08 floor=0 sel=30 7.6s
+ 332/401 | loss=0.6545 ev=0.573 agents=221 avg_r=0.5318 sum_r=136.14 x<0=0.18 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.4s
+ 333/401 | loss=0.6258 ev=0.555 agents=112 avg_r=2.1892 sum_r=560.44 x<0=0.14 elig=0.60 dorfler_tail=0.08 floor=0 sel=30 7.5s
+ 334/401 | loss=0.6942 ev=0.558 agents=97 avg_r=-0.7035 sum_r=-180.09 x<0=0.13 elig=0.59 dorfler_tail=0.08 floor=0 sel=27 7.1s
+ 335/401 | loss=0.7479 ev=0.497 agents=761 avg_r=1.5436 sum_r=395.16 x<0=0.13 elig=0.60 dorfler_tail=0.08 floor=0 sel=29 7.4s
+ 336/401 | loss=0.6501 ev=0.602 agents=34 avg_r=1.0316 sum_r=264.09 x<0=0.14 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.3s
+ 337/401 | loss=0.6053 ev=0.583 agents=428 avg_r=-0.0724 sum_r=-18.53 x<0=0.13 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.4s
+ 338/401 | loss=0.6485 ev=0.555 agents=34 avg_r=1.4593 sum_r=373.58 x<0=0.10 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.4s
+ 339/401 | loss=0.6234 ev=0.577 agents=615 avg_r=2.0301 sum_r=519.70 x<0=0.17 elig=0.60 dorfler_tail=0.08 floor=0 sel=28 7.2s
+ 340/401 | loss=0.6056 ev=0.551 agents=234 avg_r=-0.4751 sum_r=-121.63 x<0=0.19 elig=0.59 dorfler_tail=0.08 floor=0 sel=29 7.2s
+ 341/401 | loss=0.5780 ev=0.592 agents=186 avg_r=1.5097 sum_r=386.49 x<0=0.12 elig=0.60 dorfler_tail=0.08 floor=0 sel=31 7.4s
+ 342/401 | loss=0.6112 ev=0.590 agents=241 avg_r=1.3269 sum_r=339.69 x<0=0.16 elig=0.59 dorfler_tail=0.08 floor=0 sel=29 7.3s
+ 343/401 | loss=0.7043 ev=0.532 agents=44 avg_r=1.0479 sum_r=268.27 x<0=0.14 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.4s
+ 344/401 | loss=0.6269 ev=0.553 agents=308 avg_r=1.5500 sum_r=396.81 x<0=0.15 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.3s
+ 345/401 | loss=0.5842 ev=0.580 agents=704 avg_r=2.1546 sum_r=551.57 x<0=0.12 elig=0.59 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 346/401 | loss=0.6299 ev=0.570 agents=41 avg_r=0.7011 sum_r=179.49 x<0=0.16 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 8.0s
+ 347/401 | loss=0.6316 ev=0.571 agents=278 avg_r=1.6173 sum_r=414.03 x<0=0.15 elig=0.59 dorfler_tail=0.08 floor=0 sel=28 7.3s
+ 348/401 | loss=0.6115 ev=0.573 agents=34 avg_r=0.1809 sum_r=46.32 x<0=0.17 elig=0.59 dorfler_tail=0.08 floor=0 sel=29 7.4s
+ 349/401 | loss=0.6532 ev=0.557 agents=242 avg_r=0.8962 sum_r=229.43 x<0=0.12 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 350/401 | loss=0.6516 ev=0.582 agents=44 avg_r=1.0303 sum_r=263.76 x<0=0.15 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.6s
+[Checkpoint] saved → checkpoints/model_iter0350.pt
+ 351/401 | loss=0.6227 ev=0.554 agents=201 avg_r=0.7558 sum_r=193.50 x<0=0.15 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.3s
+ 352/401 | loss=0.5750 ev=0.605 agents=34 avg_r=0.5050 sum_r=129.29 x<0=0.14 elig=0.58 dorfler_tail=0.08 floor=0 sel=30 7.4s
+ 353/401 | loss=0.6413 ev=0.544 agents=457 avg_r=0.2005 sum_r=51.32 x<0=0.17 elig=0.60 dorfler_tail=0.07 floor=0 sel=26 6.9s
+ 354/401 | loss=0.6211 ev=0.589 agents=120 avg_r=2.0601 sum_r=527.38 x<0=0.12 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.6s
+ 355/401 | loss=0.6174 ev=0.574 agents=34 avg_r=1.1792 sum_r=301.88 x<0=0.15 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.3s
+ 356/401 | loss=0.6271 ev=0.563 agents=267 avg_r=0.9035 sum_r=231.30 x<0=0.15 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.4s
+ 357/401 | loss=0.6969 ev=0.569 agents=34 avg_r=-0.5932 sum_r=-151.87 x<0=0.14 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.4s
+ 358/401 | loss=0.6315 ev=0.543 agents=34 avg_r=0.1535 sum_r=39.30 x<0=0.15 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.4s
+ 359/401 | loss=0.5787 ev=0.598 agents=64 avg_r=-0.8402 sum_r=-215.10 x<0=0.10 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.3s
+ 360/401 | loss=0.6417 ev=0.555 agents=174 avg_r=0.4168 sum_r=106.70 x<0=0.19 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.4s
+ 361/401 | loss=0.6239 ev=0.563 agents=210 avg_r=0.3188 sum_r=81.61 x<0=0.13 elig=0.59 dorfler_tail=0.08 floor=0 sel=29 7.2s
+ 362/401 | loss=0.5985 ev=0.578 agents=1136 avg_r=0.0481 sum_r=12.32 x<0=0.15 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.3s
+ 363/401 | loss=0.5902 ev=0.569 agents=34 avg_r=-0.3036 sum_r=-77.73 x<0=0.15 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.4s
+ 364/401 | loss=0.6606 ev=0.567 agents=147 avg_r=-1.4026 sum_r=-359.07 x<0=0.14 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.3s
+ 365/401 | loss=0.6312 ev=0.553 agents=150 avg_r=0.4739 sum_r=121.33 x<0=0.13 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.6s
+ 366/401 | loss=0.6945 ev=0.551 agents=219 avg_r=-1.1566 sum_r=-296.08 x<0=0.14 elig=0.59 dorfler_tail=0.07 floor=0 sel=27 7.0s
+ 367/401 | loss=0.5808 ev=0.596 agents=85 avg_r=1.6020 sum_r=410.10 x<0=0.13 elig=0.58 dorfler_tail=0.09 floor=0 sel=32 7.7s
+ 368/401 | loss=0.6056 ev=0.568 agents=762 avg_r=-1.3623 sum_r=-348.74 x<0=0.12 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.7s
+ 369/401 | loss=0.6481 ev=0.558 agents=177 avg_r=-0.9408 sum_r=-240.85 x<0=0.17 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.7s
+ 370/401 | loss=0.6171 ev=0.589 agents=1015 avg_r=-0.9711 sum_r=-248.60 x<0=0.14 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.5s
+ 371/401 | loss=0.6382 ev=0.581 agents=97 avg_r=-0.9976 sum_r=-255.40 x<0=0.15 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.5s
+ 372/401 | loss=0.6350 ev=0.563 agents=553 avg_r=-2.2484 sum_r=-575.58 x<0=0.14 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 373/401 | loss=0.6417 ev=0.550 agents=83 avg_r=-1.2092 sum_r=-309.56 x<0=0.17 elig=0.59 dorfler_tail=0.09 floor=0 sel=30 7.4s
+ 374/401 | loss=0.5959 ev=0.596 agents=72 avg_r=-2.0364 sum_r=-521.32 x<0=0.13 elig=0.58 dorfler_tail=0.09 floor=0 sel=34 7.8s
+ 375/401 | loss=0.5694 ev=0.598 agents=154 avg_r=-0.1396 sum_r=-35.75 x<0=0.17 elig=0.59 dorfler_tail=0.08 floor=0 sel=28 7.3s
+ 376/401 | loss=0.6582 ev=0.562 agents=141 avg_r=-3.1031 sum_r=-794.39 x<0=0.17 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.4s
+ 377/401 | loss=0.5972 ev=0.597 agents=1262 avg_r=-1.6131 sum_r=-412.95 x<0=0.15 elig=0.58 dorfler_tail=0.09 floor=0 sel=31 7.5s
+ 378/401 | loss=0.6511 ev=0.595 agents=509 avg_r=-3.4710 sum_r=-888.58 x<0=0.18 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.3s
+ 379/401 | loss=0.6209 ev=0.573 agents=36 avg_r=-2.1022 sum_r=-538.17 x<0=0.14 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.6s
+ 380/401 | loss=0.5629 ev=0.624 agents=600 avg_r=-1.5907 sum_r=-407.23 x<0=0.14 elig=0.58 dorfler_tail=0.09 floor=0 sel=30 7.4s
+ 381/401 | loss=0.6222 ev=0.572 agents=200 avg_r=-1.0094 sum_r=-258.41 x<0=0.13 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.4s
+ 382/401 | loss=0.6545 ev=0.550 agents=388 avg_r=-3.5082 sum_r=-898.10 x<0=0.23 elig=0.60 dorfler_tail=0.08 floor=0 sel=28 7.2s
+ 383/401 | loss=0.5294 ev=0.636 agents=85 avg_r=-0.4136 sum_r=-105.88 x<0=0.12 elig=0.58 dorfler_tail=0.09 floor=0 sel=32 7.5s
+ 384/401 | loss=0.5944 ev=0.579 agents=453 avg_r=-2.0541 sum_r=-525.84 x<0=0.18 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.4s
+ 385/401 | loss=0.6282 ev=0.578 agents=171 avg_r=-1.6239 sum_r=-415.72 x<0=0.17 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.3s
+ 386/401 | loss=0.6290 ev=0.570 agents=561 avg_r=-1.0137 sum_r=-259.51 x<0=0.15 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.4s
+ 387/401 | loss=0.5582 ev=0.611 agents=404 avg_r=-0.5416 sum_r=-138.65 x<0=0.14 elig=0.59 dorfler_tail=0.09 floor=0 sel=31 7.4s
+ 388/401 | loss=0.5969 ev=0.559 agents=154 avg_r=-5.0462 sum_r=-1291.82 x<0=0.17 elig=0.59 dorfler_tail=0.08 floor=0 sel=28 7.2s
+ 389/401 | loss=0.6544 ev=0.548 agents=278 avg_r=-1.2462 sum_r=-319.03 x<0=0.18 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.4s
+ 390/401 | loss=0.6538 ev=0.587 agents=856 avg_r=-1.0032 sum_r=-256.82 x<0=0.17 elig=0.58 dorfler_tail=0.08 floor=0 sel=31 7.9s
+ 391/401 | loss=0.5737 ev=0.593 agents=101 avg_r=-2.4208 sum_r=-619.72 x<0=0.15 elig=0.58 dorfler_tail=0.08 floor=0 sel=31 8.0s
+ 392/401 | loss=0.5898 ev=0.601 agents=101 avg_r=-1.4010 sum_r=-358.67 x<0=0.19 elig=0.59 dorfler_tail=0.08 floor=0 sel=29 7.5s
+ 393/401 | loss=0.5977 ev=0.587 agents=219 avg_r=-2.3206 sum_r=-594.07 x<0=0.11 elig=0.58 dorfler_tail=0.09 floor=0 sel=31 7.7s
+ 394/401 | loss=0.5978 ev=0.583 agents=832 avg_r=-2.7761 sum_r=-710.69 x<0=0.19 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.8s
+ 395/401 | loss=0.5630 ev=0.607 agents=118 avg_r=-2.8482 sum_r=-729.14 x<0=0.15 elig=0.58 dorfler_tail=0.08 floor=0 sel=30 7.5s
+ 396/401 | loss=0.6266 ev=0.557 agents=980 avg_r=-1.5726 sum_r=-402.60 x<0=0.20 elig=0.58 dorfler_tail=0.08 floor=0 sel=30 7.4s
+ 397/401 | loss=0.5852 ev=0.599 agents=55 avg_r=-4.5732 sum_r=-1170.75 x<0=0.18 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 398/401 | loss=0.6173 ev=0.583 agents=604 avg_r=-1.0687 sum_r=-273.59 x<0=0.16 elig=0.58 dorfler_tail=0.09 floor=0 sel=30 7.4s
+ 399/401 | loss=0.5544 ev=0.622 agents=278 avg_r=-2.7659 sum_r=-708.06 x<0=0.18 elig=0.58 dorfler_tail=0.08 floor=0 sel=30 7.4s
+ 400/401 | loss=0.6305 ev=0.572 agents=400 avg_r=-2.0476 sum_r=-524.18 x<0=0.20 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.4s
+[Checkpoint] saved → checkpoints/model_iter0400.pt
+ 401/401 | loss=0.6506 ev=0.589 agents=230 avg_r=0.0894 sum_r=22.90 x<0=0.13 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.4s
+[Checkpoint] saved → checkpoints/model_iter0401.pt
+[Checkpoint] saved → checkpoints/model_final.pt
+[Train] done, total time 3065.4s
+Training finished at Fri 29 May 15:49:40 CST 2026
diff --git a/logs/train_4537.out b/logs/train_4537.out
new file mode 100644
index 0000000..49b1008
--- /dev/null
+++ b/logs/train_4537.out
@@ -0,0 +1,418 @@
+Starting training at Sat 30 May 15:16:09 CST 2026
+Running on node: node06
+[Device] cuda
+[Env] node_feats=13 edge_feats=1 act_dim=1
+[Model] params=92,740
+ 1/401 | loss=1.4016 ev=-0.007 agents=109 avg_r=-3.9659 sum_r=-1015.28 x<0=0.79 elig=0.58 dorfler_tail=0.09 floor=0 sel=35 8.7s
+ 2/401 | loss=1.2826 ev=0.030 agents=193 avg_r=-2.0419 sum_r=-522.72 x<0=0.80 elig=0.58 dorfler_tail=0.08 floor=0 sel=32 7.9s
+ 3/401 | loss=1.2362 ev=0.058 agents=39 avg_r=-4.8186 sum_r=-1233.57 x<0=0.80 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.8s
+ 4/401 | loss=1.2801 ev=0.101 agents=34 avg_r=-0.7326 sum_r=-187.54 x<0=0.77 elig=0.58 dorfler_tail=0.09 floor=0 sel=35 8.3s
+ 5/401 | loss=1.1594 ev=0.132 agents=88 avg_r=-3.2420 sum_r=-829.95 x<0=0.74 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 8.0s
+ 6/401 | loss=1.1517 ev=0.181 agents=36 avg_r=-1.5350 sum_r=-392.96 x<0=0.70 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.9s
+ 7/401 | loss=1.0153 ev=0.253 agents=34 avg_r=-0.7087 sum_r=-181.42 x<0=0.67 elig=0.58 dorfler_tail=0.08 floor=0 sel=35 8.1s
+ 8/401 | loss=1.0623 ev=0.283 agents=133 avg_r=-0.8781 sum_r=-224.79 x<0=0.65 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.9s
+ 9/401 | loss=0.9819 ev=0.304 agents=79 avg_r=-0.5083 sum_r=-130.11 x<0=0.61 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.7s
+ 10/401 | loss=0.9743 ev=0.299 agents=82 avg_r=-2.3678 sum_r=-606.16 x<0=0.59 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.9s
+ 11/401 | loss=1.0183 ev=0.320 agents=60 avg_r=1.3849 sum_r=354.54 x<0=0.53 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.6s
+ 12/401 | loss=0.9395 ev=0.343 agents=48 avg_r=0.4274 sum_r=109.42 x<0=0.50 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.8s
+ 13/401 | loss=0.8380 ev=0.367 agents=88 avg_r=-0.3599 sum_r=-92.14 x<0=0.45 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.8s
+ 14/401 | loss=0.9338 ev=0.341 agents=40 avg_r=0.1794 sum_r=45.93 x<0=0.42 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.7s
+ 15/401 | loss=0.8502 ev=0.381 agents=101 avg_r=0.1944 sum_r=49.77 x<0=0.42 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 8.0s
+ 16/401 | loss=0.9830 ev=0.370 agents=34 avg_r=-1.4113 sum_r=-361.30 x<0=0.40 elig=0.59 dorfler_tail=0.08 floor=0 sel=29 7.4s
+ 17/401 | loss=0.8119 ev=0.428 agents=132 avg_r=1.8346 sum_r=469.66 x<0=0.42 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.8s
+ 18/401 | loss=0.8296 ev=0.394 agents=34 avg_r=-0.0265 sum_r=-6.80 x<0=0.36 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.7s
+ 19/401 | loss=0.8208 ev=0.414 agents=201 avg_r=-0.1825 sum_r=-46.71 x<0=0.34 elig=0.59 dorfler_tail=0.08 floor=0 sel=34 7.9s
+ 20/401 | loss=0.8558 ev=0.396 agents=120 avg_r=0.8307 sum_r=212.65 x<0=0.30 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.7s
+ 21/401 | loss=0.8402 ev=0.410 agents=78 avg_r=-0.2640 sum_r=-67.58 x<0=0.33 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.7s
+ 22/401 | loss=0.8100 ev=0.413 agents=44 avg_r=0.1745 sum_r=44.68 x<0=0.33 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.7s
+ 23/401 | loss=0.7978 ev=0.416 agents=36 avg_r=-0.3726 sum_r=-95.38 x<0=0.27 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.7s
+ 24/401 | loss=0.7886 ev=0.456 agents=175 avg_r=2.2911 sum_r=586.53 x<0=0.23 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.9s
+ 25/401 | loss=0.8188 ev=0.402 agents=34 avg_r=0.0163 sum_r=4.18 x<0=0.24 elig=0.59 dorfler_tail=0.07 floor=0 sel=28 7.4s
+ 26/401 | loss=0.8580 ev=0.417 agents=34 avg_r=-0.2140 sum_r=-54.78 x<0=0.23 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.9s
+ 27/401 | loss=0.7731 ev=0.413 agents=176 avg_r=-0.0139 sum_r=-3.56 x<0=0.22 elig=0.59 dorfler_tail=0.07 floor=0 sel=31 8.0s
+ 28/401 | loss=0.8363 ev=0.407 agents=219 avg_r=-0.2731 sum_r=-69.90 x<0=0.21 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 8.3s
+ 29/401 | loss=0.8037 ev=0.407 agents=44 avg_r=1.4718 sum_r=376.77 x<0=0.22 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 8.0s
+ 30/401 | loss=0.7398 ev=0.460 agents=133 avg_r=1.9308 sum_r=494.30 x<0=0.21 elig=0.59 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 31/401 | loss=0.8308 ev=0.421 agents=44 avg_r=1.0891 sum_r=278.82 x<0=0.19 elig=0.59 dorfler_tail=0.08 floor=0 sel=32 7.8s
+ 32/401 | loss=0.8537 ev=0.451 agents=34 avg_r=0.4553 sum_r=116.57 x<0=0.16 elig=0.59 dorfler_tail=0.07 floor=0 sel=33 7.9s
+ 33/401 | loss=0.7271 ev=0.457 agents=193 avg_r=2.1602 sum_r=553.02 x<0=0.11 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.7s
+ 34/401 | loss=0.8864 ev=0.395 agents=132 avg_r=0.0379 sum_r=9.71 x<0=0.13 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.6s
+ 35/401 | loss=0.7846 ev=0.418 agents=60 avg_r=1.8461 sum_r=472.61 x<0=0.11 elig=0.59 dorfler_tail=0.08 floor=0 sel=30 7.5s
+ 36/401 | loss=0.8040 ev=0.428 agents=139 avg_r=0.1920 sum_r=49.14 x<0=0.08 elig=0.59 dorfler_tail=0.07 floor=0 sel=29 7.5s
+ 37/401 | loss=0.8225 ev=0.432 agents=228 avg_r=0.9105 sum_r=233.08 x<0=0.11 elig=0.59 dorfler_tail=0.07 floor=0 sel=30 7.6s
+ 38/401 | loss=0.7612 ev=0.431 agents=34 avg_r=1.5990 sum_r=409.35 x<0=0.11 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.7s
+ 39/401 | loss=0.7474 ev=0.474 agents=60 avg_r=2.1517 sum_r=550.82 x<0=0.10 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 40/401 | loss=0.7913 ev=0.417 agents=228 avg_r=2.7027 sum_r=691.89 x<0=0.09 elig=0.59 dorfler_tail=0.08 floor=0 sel=33 7.8s
+ 41/401 | loss=0.7976 ev=0.453 agents=199 avg_r=1.2828 sum_r=328.39 x<0=0.10 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.3s
+ 42/401 | loss=0.7862 ev=0.467 agents=40 avg_r=2.1315 sum_r=545.65 x<0=0.07 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.5s
+ 43/401 | loss=0.7528 ev=0.447 agents=34 avg_r=1.6585 sum_r=424.58 x<0=0.09 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.5s
+ 44/401 | loss=0.8170 ev=0.432 agents=193 avg_r=1.4874 sum_r=380.76 x<0=0.09 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.6s
+ 45/401 | loss=0.8174 ev=0.455 agents=230 avg_r=1.1440 sum_r=292.86 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 46/401 | loss=0.7965 ev=0.445 agents=34 avg_r=2.3036 sum_r=589.72 x<0=0.09 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.5s
+ 47/401 | loss=0.7296 ev=0.437 agents=120 avg_r=3.0991 sum_r=793.37 x<0=0.09 elig=0.59 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 48/401 | loss=0.7574 ev=0.426 agents=34 avg_r=1.4336 sum_r=366.99 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 49/401 | loss=0.7115 ev=0.452 agents=314 avg_r=4.5889 sum_r=1174.75 x<0=0.09 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 8.1s
+ 50/401 | loss=0.8021 ev=0.447 agents=309 avg_r=1.0066 sum_r=257.70 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.7s
+[Checkpoint] saved → checkpoints/model_iter0050.pt
+ 51/401 | loss=0.7353 ev=0.461 agents=220 avg_r=2.4559 sum_r=628.70 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.5s
+ 52/401 | loss=0.7844 ev=0.429 agents=75 avg_r=1.7472 sum_r=447.29 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.5s
+ 53/401 | loss=0.7153 ev=0.484 agents=34 avg_r=4.0922 sum_r=1047.60 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 54/401 | loss=0.6924 ev=0.475 agents=325 avg_r=2.5784 sum_r=660.07 x<0=0.07 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.6s
+ 55/401 | loss=0.7292 ev=0.441 agents=1592 avg_r=2.6958 sum_r=690.12 x<0=0.07 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.6s
+ 56/401 | loss=0.7136 ev=0.448 agents=81 avg_r=2.9107 sum_r=745.14 x<0=0.07 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.2s
+ 57/401 | loss=0.7957 ev=0.442 agents=221 avg_r=2.5431 sum_r=651.03 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.5s
+ 58/401 | loss=0.7484 ev=0.477 agents=592 avg_r=3.0523 sum_r=781.38 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.6s
+ 59/401 | loss=0.8223 ev=0.424 agents=260 avg_r=1.2105 sum_r=309.90 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 60/401 | loss=0.7966 ev=0.463 agents=34 avg_r=1.3681 sum_r=350.25 x<0=0.05 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.5s
+ 61/401 | loss=0.6900 ev=0.478 agents=589 avg_r=3.2758 sum_r=838.62 x<0=0.05 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.3s
+ 62/401 | loss=0.7203 ev=0.462 agents=404 avg_r=3.5533 sum_r=909.64 x<0=0.07 elig=0.59 dorfler_tail=0.08 floor=0 sel=31 7.6s
+ 63/401 | loss=0.7498 ev=0.437 agents=88 avg_r=1.3140 sum_r=336.38 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 64/401 | loss=0.6874 ev=0.460 agents=87 avg_r=3.1493 sum_r=806.22 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.6s
+ 65/401 | loss=0.7238 ev=0.479 agents=504 avg_r=2.8049 sum_r=718.04 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.5s
+ 66/401 | loss=0.7026 ev=0.479 agents=612 avg_r=3.3964 sum_r=869.48 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 67/401 | loss=0.7430 ev=0.449 agents=34 avg_r=2.2715 sum_r=581.51 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 68/401 | loss=0.6981 ev=0.444 agents=563 avg_r=2.3441 sum_r=600.10 x<0=0.07 elig=0.59 dorfler_tail=0.07 floor=0 sel=30 7.5s
+ 69/401 | loss=0.7046 ev=0.472 agents=82 avg_r=2.8354 sum_r=725.87 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 70/401 | loss=0.7231 ev=0.466 agents=679 avg_r=2.1406 sum_r=547.99 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 71/401 | loss=0.6765 ev=0.461 agents=177 avg_r=2.7769 sum_r=710.88 x<0=0.07 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.4s
+ 72/401 | loss=0.7200 ev=0.467 agents=417 avg_r=2.5203 sum_r=645.20 x<0=0.07 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 73/401 | loss=0.7056 ev=0.470 agents=406 avg_r=2.4355 sum_r=623.49 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 74/401 | loss=0.7596 ev=0.469 agents=39 avg_r=3.4787 sum_r=890.55 x<0=0.07 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 75/401 | loss=0.8122 ev=0.437 agents=76 avg_r=0.1922 sum_r=49.19 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.5s
+ 76/401 | loss=0.7356 ev=0.480 agents=743 avg_r=3.3444 sum_r=856.16 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 77/401 | loss=0.6961 ev=0.463 agents=868 avg_r=3.1062 sum_r=795.20 x<0=0.05 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 78/401 | loss=0.6751 ev=0.472 agents=239 avg_r=2.1832 sum_r=558.90 x<0=0.07 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 79/401 | loss=0.7819 ev=0.463 agents=92 avg_r=3.4287 sum_r=877.75 x<0=0.07 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.5s
+ 80/401 | loss=0.7031 ev=0.443 agents=100 avg_r=3.0162 sum_r=772.14 x<0=0.09 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 81/401 | loss=0.7328 ev=0.468 agents=216 avg_r=1.5925 sum_r=407.67 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 82/401 | loss=0.6882 ev=0.478 agents=500 avg_r=4.0837 sum_r=1045.44 x<0=0.09 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.5s
+ 83/401 | loss=0.7674 ev=0.439 agents=209 avg_r=2.4277 sum_r=621.49 x<0=0.10 elig=0.60 dorfler_tail=0.07 floor=0 sel=27 7.1s
+ 84/401 | loss=0.6714 ev=0.467 agents=226 avg_r=3.4643 sum_r=886.86 x<0=0.09 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.3s
+ 85/401 | loss=0.6888 ev=0.457 agents=661 avg_r=3.5194 sum_r=900.96 x<0=0.09 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 86/401 | loss=0.7823 ev=0.465 agents=78 avg_r=3.6703 sum_r=939.61 x<0=0.10 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 7.5s
+ 87/401 | loss=0.7369 ev=0.441 agents=426 avg_r=3.0157 sum_r=772.03 x<0=0.08 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 88/401 | loss=0.7635 ev=0.440 agents=445 avg_r=2.9807 sum_r=763.05 x<0=0.07 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.3s
+ 89/401 | loss=0.6536 ev=0.493 agents=42 avg_r=4.4092 sum_r=1128.74 x<0=0.09 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.3s
+ 90/401 | loss=0.7260 ev=0.459 agents=174 avg_r=2.2528 sum_r=576.72 x<0=0.08 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 91/401 | loss=0.8182 ev=0.451 agents=189 avg_r=2.7882 sum_r=713.78 x<0=0.07 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.2s
+ 92/401 | loss=0.7171 ev=0.475 agents=930 avg_r=2.9107 sum_r=745.14 x<0=0.08 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.3s
+ 93/401 | loss=0.7178 ev=0.462 agents=950 avg_r=2.5842 sum_r=661.56 x<0=0.09 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.2s
+ 94/401 | loss=0.6635 ev=0.480 agents=278 avg_r=4.6649 sum_r=1194.22 x<0=0.08 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 8.0s
+ 95/401 | loss=0.8666 ev=0.417 agents=516 avg_r=2.5170 sum_r=644.35 x<0=0.09 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 7.5s
+ 96/401 | loss=0.6856 ev=0.473 agents=225 avg_r=3.6171 sum_r=925.98 x<0=0.09 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 97/401 | loss=0.7293 ev=0.466 agents=139 avg_r=3.4967 sum_r=895.16 x<0=0.09 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 98/401 | loss=0.6989 ev=0.477 agents=386 avg_r=3.2573 sum_r=833.87 x<0=0.08 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.3s
+ 99/401 | loss=0.7278 ev=0.456 agents=607 avg_r=3.5721 sum_r=914.45 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 100/401 | loss=0.6917 ev=0.488 agents=395 avg_r=2.5313 sum_r=648.00 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.4s
+[Checkpoint] saved → checkpoints/model_iter0100.pt
+ 101/401 | loss=0.6450 ev=0.482 agents=118 avg_r=3.6129 sum_r=924.89 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 102/401 | loss=0.6719 ev=0.502 agents=82 avg_r=3.9205 sum_r=1003.65 x<0=0.07 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.2s
+ 103/401 | loss=0.8262 ev=0.444 agents=34 avg_r=0.9714 sum_r=248.68 x<0=0.07 elig=0.61 dorfler_tail=0.06 floor=0 sel=28 7.3s
+ 104/401 | loss=0.6693 ev=0.473 agents=205 avg_r=4.0583 sum_r=1038.93 x<0=0.09 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 105/401 | loss=0.7109 ev=0.493 agents=278 avg_r=3.3932 sum_r=868.66 x<0=0.07 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 7.5s
+ 106/401 | loss=0.7028 ev=0.490 agents=80 avg_r=3.2735 sum_r=838.02 x<0=0.08 elig=0.61 dorfler_tail=0.07 floor=0 sel=26 7.0s
+ 107/401 | loss=0.6651 ev=0.484 agents=72 avg_r=2.5184 sum_r=644.70 x<0=0.07 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 108/401 | loss=0.6931 ev=0.461 agents=157 avg_r=1.9714 sum_r=504.68 x<0=0.07 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.4s
+ 109/401 | loss=0.6012 ev=0.517 agents=169 avg_r=3.9352 sum_r=1007.42 x<0=0.07 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 110/401 | loss=0.7184 ev=0.484 agents=34 avg_r=2.9819 sum_r=763.37 x<0=0.06 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.3s
+ 111/401 | loss=0.6751 ev=0.493 agents=403 avg_r=3.0738 sum_r=786.90 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 112/401 | loss=0.6429 ev=0.488 agents=161 avg_r=2.6077 sum_r=667.57 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.2s
+ 113/401 | loss=0.6752 ev=0.502 agents=55 avg_r=3.7771 sum_r=966.93 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.3s
+ 114/401 | loss=0.7463 ev=0.451 agents=278 avg_r=2.8845 sum_r=738.44 x<0=0.06 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 115/401 | loss=0.7711 ev=0.449 agents=1458 avg_r=1.9170 sum_r=490.75 x<0=0.05 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.1s
+ 116/401 | loss=0.6691 ev=0.478 agents=322 avg_r=2.8004 sum_r=716.90 x<0=0.05 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.2s
+ 117/401 | loss=0.7584 ev=0.482 agents=157 avg_r=1.9519 sum_r=499.68 x<0=0.05 elig=0.61 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 118/401 | loss=0.6645 ev=0.505 agents=34 avg_r=4.1436 sum_r=1060.76 x<0=0.05 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 119/401 | loss=0.7026 ev=0.482 agents=525 avg_r=2.6891 sum_r=688.42 x<0=0.05 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 120/401 | loss=0.6424 ev=0.476 agents=449 avg_r=3.1357 sum_r=802.74 x<0=0.04 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 121/401 | loss=0.6441 ev=0.485 agents=751 avg_r=3.1465 sum_r=805.51 x<0=0.04 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 122/401 | loss=0.7017 ev=0.468 agents=97 avg_r=2.4756 sum_r=633.75 x<0=0.05 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.4s
+ 123/401 | loss=0.8205 ev=0.460 agents=88 avg_r=3.0468 sum_r=779.99 x<0=0.06 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 124/401 | loss=0.7868 ev=0.486 agents=34 avg_r=3.0342 sum_r=776.75 x<0=0.05 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.4s
+ 125/401 | loss=0.7189 ev=0.456 agents=631 avg_r=3.7444 sum_r=958.57 x<0=0.06 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 126/401 | loss=0.7631 ev=0.462 agents=205 avg_r=3.6346 sum_r=930.47 x<0=0.05 elig=0.61 dorfler_tail=0.07 floor=0 sel=26 7.3s
+ 127/401 | loss=0.8456 ev=0.490 agents=276 avg_r=3.9878 sum_r=1020.87 x<0=0.05 elig=0.62 dorfler_tail=0.07 floor=0 sel=31 7.9s
+ 128/401 | loss=0.7728 ev=0.453 agents=216 avg_r=3.3635 sum_r=861.06 x<0=0.05 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.3s
+ 129/401 | loss=0.6854 ev=0.497 agents=171 avg_r=3.1932 sum_r=817.45 x<0=0.05 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 130/401 | loss=0.6694 ev=0.502 agents=773 avg_r=3.1194 sum_r=798.57 x<0=0.05 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 131/401 | loss=0.8146 ev=0.475 agents=417 avg_r=4.4338 sum_r=1135.05 x<0=0.05 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 132/401 | loss=0.6740 ev=0.434 agents=199 avg_r=1.0849 sum_r=277.74 x<0=0.04 elig=0.61 dorfler_tail=0.07 floor=0 sel=25 6.9s
+ 133/401 | loss=0.6344 ev=0.538 agents=199 avg_r=4.8060 sum_r=1230.34 x<0=0.05 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.5s
+ 134/401 | loss=0.7608 ev=0.484 agents=109 avg_r=2.4116 sum_r=617.37 x<0=0.04 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 135/401 | loss=0.6871 ev=0.497 agents=81 avg_r=2.6706 sum_r=683.68 x<0=0.04 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 7.5s
+ 136/401 | loss=0.6854 ev=0.500 agents=349 avg_r=3.1550 sum_r=807.67 x<0=0.04 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.3s
+ 137/401 | loss=0.6222 ev=0.475 agents=309 avg_r=2.9599 sum_r=757.74 x<0=0.04 elig=0.60 dorfler_tail=0.07 floor=0 sel=27 7.2s
+ 138/401 | loss=0.7838 ev=0.473 agents=34 avg_r=3.0775 sum_r=787.84 x<0=0.03 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.3s
+ 139/401 | loss=0.6776 ev=0.469 agents=137 avg_r=4.6078 sum_r=1179.59 x<0=0.04 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.6s
+ 140/401 | loss=0.7131 ev=0.482 agents=34 avg_r=2.7598 sum_r=706.51 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 141/401 | loss=0.6298 ev=0.510 agents=716 avg_r=2.6834 sum_r=686.95 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 142/401 | loss=0.6687 ev=0.482 agents=118 avg_r=2.9901 sum_r=765.46 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.5s
+ 143/401 | loss=0.6278 ev=0.538 agents=684 avg_r=4.2436 sum_r=1086.37 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.7s
+ 144/401 | loss=0.6646 ev=0.496 agents=1317 avg_r=1.9731 sum_r=505.11 x<0=0.03 elig=0.61 dorfler_tail=0.07 floor=0 sel=26 7.2s
+ 145/401 | loss=0.7301 ev=0.477 agents=324 avg_r=2.6170 sum_r=669.96 x<0=0.03 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.5s
+ 146/401 | loss=0.7054 ev=0.474 agents=318 avg_r=3.0373 sum_r=777.55 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=32 7.6s
+ 147/401 | loss=0.6366 ev=0.503 agents=260 avg_r=1.7196 sum_r=440.21 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=26 7.1s
+ 148/401 | loss=0.6500 ev=0.527 agents=64 avg_r=3.5001 sum_r=896.04 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=31 7.5s
+ 149/401 | loss=0.7272 ev=0.504 agents=406 avg_r=1.2588 sum_r=322.26 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.2s
+ 150/401 | loss=0.5931 ev=0.548 agents=494 avg_r=3.0807 sum_r=788.65 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.2s
+[Checkpoint] saved → checkpoints/model_iter0150.pt
+ 151/401 | loss=0.7106 ev=0.473 agents=276 avg_r=2.7628 sum_r=707.27 x<0=0.02 elig=0.60 dorfler_tail=0.08 floor=0 sel=31 7.5s
+ 152/401 | loss=0.7196 ev=0.509 agents=917 avg_r=0.6032 sum_r=154.42 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.2s
+ 153/401 | loss=0.6383 ev=0.494 agents=252 avg_r=4.4047 sum_r=1127.62 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 154/401 | loss=0.6348 ev=0.535 agents=310 avg_r=3.2224 sum_r=824.94 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 155/401 | loss=0.7558 ev=0.478 agents=550 avg_r=2.0697 sum_r=529.83 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=29 7.3s
+ 156/401 | loss=0.7824 ev=0.471 agents=759 avg_r=2.2078 sum_r=565.21 x<0=0.03 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.2s
+ 157/401 | loss=0.6814 ev=0.487 agents=66 avg_r=2.7153 sum_r=695.12 x<0=0.02 elig=0.60 dorfler_tail=0.07 floor=0 sel=30 7.4s
+ 158/401 | loss=0.6918 ev=0.475 agents=157 avg_r=4.0377 sum_r=1033.66 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.3s
+ 159/401 | loss=0.6960 ev=0.497 agents=210 avg_r=4.4194 sum_r=1131.36 x<0=0.02 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.4s
+ 160/401 | loss=0.8230 ev=0.463 agents=72 avg_r=3.2715 sum_r=837.50 x<0=0.01 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 161/401 | loss=0.8833 ev=0.462 agents=101 avg_r=3.1055 sum_r=795.01 x<0=0.01 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 162/401 | loss=0.7523 ev=0.439 agents=1039 avg_r=2.8131 sum_r=720.15 x<0=0.01 elig=0.60 dorfler_tail=0.07 floor=0 sel=28 7.3s
+ 163/401 | loss=0.7434 ev=0.484 agents=857 avg_r=5.0866 sum_r=1302.18 x<0=0.01 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 8.0s
+ 164/401 | loss=0.9129 ev=0.448 agents=208 avg_r=3.0212 sum_r=773.42 x<0=0.02 elig=0.62 dorfler_tail=0.06 floor=0 sel=27 7.7s
+ 165/401 | loss=0.8110 ev=0.503 agents=72 avg_r=5.2848 sum_r=1352.92 x<0=0.02 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 8.1s
+ 166/401 | loss=0.9153 ev=0.417 agents=443 avg_r=2.6762 sum_r=685.11 x<0=0.02 elig=0.62 dorfler_tail=0.07 floor=0 sel=26 7.5s
+ 167/401 | loss=0.8216 ev=0.435 agents=72 avg_r=4.6195 sum_r=1182.58 x<0=0.02 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.8s
+ 168/401 | loss=0.8799 ev=0.468 agents=218 avg_r=5.6227 sum_r=1439.40 x<0=0.02 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.8s
+ 169/401 | loss=0.9677 ev=0.464 agents=64 avg_r=3.2444 sum_r=830.56 x<0=0.02 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 170/401 | loss=0.8684 ev=0.450 agents=1183 avg_r=4.2454 sum_r=1086.82 x<0=0.02 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 171/401 | loss=0.9914 ev=0.457 agents=248 avg_r=5.2504 sum_r=1344.10 x<0=0.02 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 172/401 | loss=0.9352 ev=0.455 agents=66 avg_r=4.8499 sum_r=1241.57 x<0=0.02 elig=0.62 dorfler_tail=0.07 floor=0 sel=30 7.8s
+ 173/401 | loss=0.8915 ev=0.475 agents=195 avg_r=4.3840 sum_r=1122.30 x<0=0.02 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 174/401 | loss=0.9410 ev=0.477 agents=366 avg_r=5.2875 sum_r=1353.60 x<0=0.02 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 175/401 | loss=0.9022 ev=0.454 agents=78 avg_r=4.4750 sum_r=1145.59 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=31 8.0s
+ 176/401 | loss=0.9084 ev=0.455 agents=282 avg_r=3.4913 sum_r=893.77 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=26 7.3s
+ 177/401 | loss=0.8292 ev=0.478 agents=252 avg_r=3.6340 sum_r=930.31 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 178/401 | loss=0.9954 ev=0.469 agents=193 avg_r=5.3305 sum_r=1364.61 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 179/401 | loss=1.0011 ev=0.426 agents=1246 avg_r=4.4377 sum_r=1136.05 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 180/401 | loss=0.9708 ev=0.457 agents=772 avg_r=5.4786 sum_r=1402.53 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 181/401 | loss=0.9704 ev=0.452 agents=132 avg_r=4.8561 sum_r=1243.16 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 182/401 | loss=1.0905 ev=0.437 agents=119 avg_r=4.0510 sum_r=1037.06 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.4s
+ 183/401 | loss=1.0880 ev=0.459 agents=762 avg_r=4.7612 sum_r=1218.87 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 184/401 | loss=1.0019 ev=0.454 agents=212 avg_r=3.7824 sum_r=968.29 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 185/401 | loss=0.9900 ev=0.466 agents=120 avg_r=5.3904 sum_r=1379.95 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 186/401 | loss=1.0037 ev=0.463 agents=70 avg_r=4.2867 sum_r=1097.39 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 187/401 | loss=1.2264 ev=0.454 agents=694 avg_r=6.6090 sum_r=1691.90 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 8.3s
+ 188/401 | loss=1.0584 ev=0.455 agents=761 avg_r=4.4357 sum_r=1135.54 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.7s
+ 189/401 | loss=1.0834 ev=0.435 agents=101 avg_r=3.8870 sum_r=995.07 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.7s
+ 190/401 | loss=0.9906 ev=0.480 agents=82 avg_r=5.7419 sum_r=1469.92 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 191/401 | loss=1.0026 ev=0.489 agents=112 avg_r=4.7027 sum_r=1203.90 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 192/401 | loss=0.9754 ev=0.470 agents=212 avg_r=3.5024 sum_r=896.62 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 193/401 | loss=0.9544 ev=0.504 agents=206 avg_r=6.2049 sum_r=1588.45 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=30 8.0s
+ 194/401 | loss=1.0699 ev=0.470 agents=92 avg_r=3.5192 sum_r=900.92 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 195/401 | loss=1.0682 ev=0.455 agents=1062 avg_r=4.7573 sum_r=1217.87 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 196/401 | loss=1.0261 ev=0.476 agents=73 avg_r=3.4637 sum_r=886.70 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=26 7.4s
+ 197/401 | loss=1.1041 ev=0.477 agents=82 avg_r=5.4997 sum_r=1407.91 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 198/401 | loss=1.0685 ev=0.475 agents=137 avg_r=4.8297 sum_r=1236.40 x<0=0.01 elig=0.63 dorfler_tail=0.08 floor=0 sel=29 7.8s
+ 199/401 | loss=1.0788 ev=0.478 agents=617 avg_r=5.8426 sum_r=1495.71 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.8s
+ 200/401 | loss=1.0358 ev=0.482 agents=346 avg_r=5.6052 sum_r=1434.92 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.8s
+[Checkpoint] saved → checkpoints/model_iter0200.pt
+ 201/401 | loss=0.8902 ev=0.500 agents=366 avg_r=4.7006 sum_r=1203.36 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=26 7.3s
+ 202/401 | loss=1.2783 ev=0.462 agents=438 avg_r=6.6009 sum_r=1689.82 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 203/401 | loss=0.9705 ev=0.479 agents=66 avg_r=4.4767 sum_r=1146.04 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 204/401 | loss=1.0327 ev=0.470 agents=174 avg_r=4.7346 sum_r=1212.06 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.4s
+ 205/401 | loss=1.0545 ev=0.486 agents=454 avg_r=5.4121 sum_r=1385.49 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 206/401 | loss=0.9817 ev=0.477 agents=482 avg_r=5.1323 sum_r=1313.87 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=26 7.4s
+ 207/401 | loss=0.9354 ev=0.464 agents=526 avg_r=2.5360 sum_r=649.22 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=25 7.3s
+ 208/401 | loss=1.0478 ev=0.484 agents=64 avg_r=6.3611 sum_r=1628.44 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=30 8.2s
+ 209/401 | loss=1.0140 ev=0.494 agents=77 avg_r=6.1189 sum_r=1566.43 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=30 8.3s
+ 210/401 | loss=1.0858 ev=0.489 agents=34 avg_r=4.5550 sum_r=1166.07 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=25 7.5s
+ 211/401 | loss=1.0737 ev=0.478 agents=473 avg_r=6.0945 sum_r=1560.20 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=32 8.4s
+ 212/401 | loss=1.1049 ev=0.498 agents=370 avg_r=3.9285 sum_r=1005.70 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=25 7.3s
+ 213/401 | loss=1.0843 ev=0.467 agents=199 avg_r=5.7006 sum_r=1459.35 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.9s
+ 214/401 | loss=0.9703 ev=0.500 agents=1681 avg_r=6.1949 sum_r=1585.90 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 215/401 | loss=1.1585 ev=0.454 agents=95 avg_r=4.3943 sum_r=1124.94 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 216/401 | loss=1.0844 ev=0.490 agents=132 avg_r=3.6609 sum_r=937.19 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=26 7.4s
+ 217/401 | loss=1.0243 ev=0.480 agents=650 avg_r=5.7942 sum_r=1483.30 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=30 7.9s
+ 218/401 | loss=0.9701 ev=0.494 agents=222 avg_r=4.2069 sum_r=1076.96 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=26 7.4s
+ 219/401 | loss=1.1205 ev=0.474 agents=340 avg_r=4.9871 sum_r=1276.71 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.8s
+ 220/401 | loss=1.0831 ev=0.505 agents=199 avg_r=4.2395 sum_r=1085.30 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 221/401 | loss=1.0350 ev=0.478 agents=205 avg_r=7.2874 sum_r=1865.56 x<0=0.00 elig=0.63 dorfler_tail=0.08 floor=0 sel=30 7.9s
+ 222/401 | loss=1.1288 ev=0.485 agents=884 avg_r=3.2765 sum_r=838.78 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=26 7.4s
+ 223/401 | loss=1.0799 ev=0.494 agents=440 avg_r=5.8995 sum_r=1510.28 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 224/401 | loss=0.9680 ev=0.448 agents=41 avg_r=1.7854 sum_r=457.07 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=25 7.3s
+ 225/401 | loss=1.0479 ev=0.507 agents=377 avg_r=8.4851 sum_r=2172.19 x<0=0.00 elig=0.63 dorfler_tail=0.08 floor=0 sel=33 8.2s
+ 226/401 | loss=1.0476 ev=0.484 agents=60 avg_r=4.7891 sum_r=1226.01 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=26 7.4s
+ 227/401 | loss=1.1226 ev=0.506 agents=87 avg_r=6.0974 sum_r=1560.94 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 228/401 | loss=1.0392 ev=0.481 agents=113 avg_r=5.0643 sum_r=1296.45 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 229/401 | loss=1.1729 ev=0.515 agents=220 avg_r=6.9283 sum_r=1773.65 x<0=0.00 elig=0.63 dorfler_tail=0.08 floor=0 sel=30 7.9s
+ 230/401 | loss=1.1397 ev=0.481 agents=153 avg_r=4.7461 sum_r=1215.01 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 231/401 | loss=1.1618 ev=0.486 agents=983 avg_r=4.4464 sum_r=1138.29 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 232/401 | loss=1.0145 ev=0.533 agents=908 avg_r=6.6488 sum_r=1702.09 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=29 8.3s
+ 233/401 | loss=0.9984 ev=0.466 agents=60 avg_r=3.0361 sum_r=777.24 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=26 7.7s
+ 234/401 | loss=1.1600 ev=0.477 agents=34 avg_r=5.4348 sum_r=1391.32 x<0=0.00 elig=0.63 dorfler_tail=0.08 floor=0 sel=28 7.9s
+ 235/401 | loss=1.0123 ev=0.500 agents=1033 avg_r=5.7679 sum_r=1476.59 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.9s
+ 236/401 | loss=0.9871 ev=0.493 agents=267 avg_r=5.4802 sum_r=1402.94 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 237/401 | loss=1.0411 ev=0.493 agents=823 avg_r=4.2589 sum_r=1090.27 x<0=0.00 elig=0.64 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 238/401 | loss=0.9391 ev=0.471 agents=258 avg_r=4.8508 sum_r=1241.81 x<0=0.00 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.7s
+ 239/401 | loss=0.9220 ev=0.526 agents=80 avg_r=5.5145 sum_r=1411.71 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.6s
+ 240/401 | loss=1.0007 ev=0.516 agents=414 avg_r=4.9083 sum_r=1256.51 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.7s
+ 241/401 | loss=1.0398 ev=0.481 agents=387 avg_r=3.9976 sum_r=1023.38 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 242/401 | loss=0.9385 ev=0.508 agents=78 avg_r=4.1453 sum_r=1061.20 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=26 7.3s
+ 243/401 | loss=0.9188 ev=0.506 agents=166 avg_r=4.2940 sum_r=1099.26 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 244/401 | loss=0.8709 ev=0.493 agents=229 avg_r=3.3207 sum_r=850.10 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 245/401 | loss=0.8569 ev=0.526 agents=276 avg_r=4.4382 sum_r=1136.18 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 246/401 | loss=0.7959 ev=0.494 agents=383 avg_r=2.7136 sum_r=694.68 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.4s
+ 247/401 | loss=0.8470 ev=0.525 agents=197 avg_r=6.1670 sum_r=1578.75 x<0=0.00 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 7.7s
+ 248/401 | loss=0.7863 ev=0.449 agents=800 avg_r=2.1261 sum_r=544.28 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.2s
+ 249/401 | loss=0.8609 ev=0.504 agents=423 avg_r=3.3115 sum_r=847.74 x<0=0.00 elig=0.61 dorfler_tail=0.08 floor=0 sel=27 7.4s
+ 250/401 | loss=0.8243 ev=0.524 agents=94 avg_r=4.7484 sum_r=1215.58 x<0=0.01 elig=0.61 dorfler_tail=0.08 floor=0 sel=29 7.7s
+[Checkpoint] saved → checkpoints/model_iter0250.pt
+ 251/401 | loss=0.8358 ev=0.497 agents=221 avg_r=3.1797 sum_r=814.00 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.4s
+ 252/401 | loss=0.7213 ev=0.529 agents=318 avg_r=3.7237 sum_r=953.26 x<0=0.00 elig=0.60 dorfler_tail=0.08 floor=0 sel=28 7.4s
+ 253/401 | loss=0.7174 ev=0.530 agents=1013 avg_r=1.8543 sum_r=474.70 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=25 7.1s
+ 254/401 | loss=0.8496 ev=0.486 agents=101 avg_r=4.5127 sum_r=1155.26 x<0=0.00 elig=0.61 dorfler_tail=0.08 floor=0 sel=29 8.0s
+ 255/401 | loss=0.7620 ev=0.526 agents=39 avg_r=2.8203 sum_r=721.99 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.7s
+ 256/401 | loss=0.7307 ev=0.534 agents=628 avg_r=4.4600 sum_r=1141.76 x<0=0.01 elig=0.61 dorfler_tail=0.08 floor=0 sel=27 7.6s
+ 257/401 | loss=0.7684 ev=0.513 agents=395 avg_r=3.4904 sum_r=893.53 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=27 7.7s
+ 258/401 | loss=0.7384 ev=0.533 agents=244 avg_r=4.2749 sum_r=1094.38 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 259/401 | loss=0.8468 ev=0.500 agents=199 avg_r=2.7803 sum_r=711.75 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=25 7.4s
+ 260/401 | loss=0.8891 ev=0.471 agents=113 avg_r=4.3324 sum_r=1109.10 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 261/401 | loss=0.8631 ev=0.491 agents=573 avg_r=4.3577 sum_r=1115.56 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 262/401 | loss=0.8856 ev=0.504 agents=658 avg_r=4.7877 sum_r=1225.66 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.7s
+ 263/401 | loss=0.7890 ev=0.531 agents=215 avg_r=3.1940 sum_r=817.65 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=26 7.4s
+ 264/401 | loss=0.7539 ev=0.491 agents=44 avg_r=2.2303 sum_r=570.95 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=25 7.2s
+ 265/401 | loss=0.7910 ev=0.521 agents=34 avg_r=4.1604 sum_r=1065.05 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.6s
+ 266/401 | loss=0.7827 ev=0.525 agents=97 avg_r=4.0291 sum_r=1031.44 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.4s
+ 267/401 | loss=0.8642 ev=0.539 agents=64 avg_r=4.4701 sum_r=1144.35 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.6s
+ 268/401 | loss=0.7770 ev=0.503 agents=813 avg_r=3.0955 sum_r=792.44 x<0=0.00 elig=0.62 dorfler_tail=0.07 floor=0 sel=25 7.1s
+ 269/401 | loss=0.6881 ev=0.513 agents=34 avg_r=2.4608 sum_r=629.97 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=29 7.4s
+ 270/401 | loss=0.6843 ev=0.513 agents=523 avg_r=3.8834 sum_r=994.14 x<0=0.00 elig=0.61 dorfler_tail=0.08 floor=0 sel=27 7.4s
+ 271/401 | loss=0.7640 ev=0.497 agents=34 avg_r=3.2820 sum_r=840.20 x<0=0.00 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 7.4s
+ 272/401 | loss=0.8417 ev=0.493 agents=204 avg_r=2.4556 sum_r=628.62 x<0=0.01 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 273/401 | loss=0.7486 ev=0.517 agents=155 avg_r=1.8537 sum_r=474.56 x<0=0.01 elig=0.60 dorfler_tail=0.08 floor=0 sel=27 7.2s
+ 274/401 | loss=0.6343 ev=0.551 agents=245 avg_r=3.7625 sum_r=963.20 x<0=0.00 elig=0.60 dorfler_tail=0.08 floor=0 sel=28 7.4s
+ 275/401 | loss=0.5988 ev=0.554 agents=140 avg_r=2.5426 sum_r=650.91 x<0=0.01 elig=0.60 dorfler_tail=0.08 floor=0 sel=28 7.2s
+ 276/401 | loss=0.7488 ev=0.529 agents=34 avg_r=1.9313 sum_r=494.41 x<0=0.01 elig=0.60 dorfler_tail=0.08 floor=0 sel=28 7.7s
+ 277/401 | loss=0.7258 ev=0.496 agents=104 avg_r=2.8360 sum_r=726.01 x<0=0.01 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.8s
+ 278/401 | loss=0.6367 ev=0.539 agents=86 avg_r=3.5156 sum_r=900.00 x<0=0.00 elig=0.60 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 279/401 | loss=0.6267 ev=0.548 agents=1453 avg_r=3.0546 sum_r=781.97 x<0=0.01 elig=0.60 dorfler_tail=0.08 floor=0 sel=28 7.6s
+ 280/401 | loss=0.6415 ev=0.533 agents=225 avg_r=2.5181 sum_r=644.63 x<0=0.00 elig=0.59 dorfler_tail=0.08 floor=0 sel=28 7.3s
+ 281/401 | loss=0.6360 ev=0.550 agents=211 avg_r=2.4619 sum_r=630.24 x<0=0.01 elig=0.60 dorfler_tail=0.08 floor=0 sel=27 7.4s
+ 282/401 | loss=0.6967 ev=0.496 agents=141 avg_r=1.4766 sum_r=378.01 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=28 7.3s
+ 283/401 | loss=0.7013 ev=0.536 agents=77 avg_r=2.8570 sum_r=731.40 x<0=0.01 elig=0.61 dorfler_tail=0.08 floor=0 sel=27 7.3s
+ 284/401 | loss=0.7681 ev=0.518 agents=34 avg_r=2.8556 sum_r=731.02 x<0=0.01 elig=0.60 dorfler_tail=0.08 floor=0 sel=28 7.4s
+ 285/401 | loss=0.7100 ev=0.530 agents=146 avg_r=3.9244 sum_r=1004.65 x<0=0.01 elig=0.60 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 286/401 | loss=0.6773 ev=0.557 agents=118 avg_r=4.1812 sum_r=1070.38 x<0=0.01 elig=0.60 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 287/401 | loss=0.7370 ev=0.542 agents=79 avg_r=3.1609 sum_r=809.20 x<0=0.00 elig=0.61 dorfler_tail=0.08 floor=0 sel=27 7.4s
+ 288/401 | loss=0.7687 ev=0.522 agents=34 avg_r=2.3589 sum_r=603.88 x<0=0.01 elig=0.61 dorfler_tail=0.07 floor=0 sel=25 7.2s
+ 289/401 | loss=0.7368 ev=0.546 agents=144 avg_r=4.4971 sum_r=1151.27 x<0=0.01 elig=0.61 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 290/401 | loss=0.8127 ev=0.523 agents=112 avg_r=3.2128 sum_r=822.48 x<0=0.00 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 7.6s
+ 291/401 | loss=0.8122 ev=0.544 agents=167 avg_r=5.3077 sum_r=1358.76 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=26 7.4s
+ 292/401 | loss=0.8049 ev=0.548 agents=779 avg_r=4.8604 sum_r=1244.27 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.7s
+ 293/401 | loss=0.8547 ev=0.510 agents=1224 avg_r=5.0976 sum_r=1304.98 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=26 7.5s
+ 294/401 | loss=0.7872 ev=0.549 agents=34 avg_r=4.3640 sum_r=1117.20 x<0=0.01 elig=0.61 dorfler_tail=0.08 floor=0 sel=27 7.5s
+ 295/401 | loss=0.7772 ev=0.535 agents=133 avg_r=3.8117 sum_r=975.79 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.3s
+ 296/401 | loss=0.8143 ev=0.530 agents=171 avg_r=5.1571 sum_r=1320.22 x<0=0.00 elig=0.61 dorfler_tail=0.08 floor=0 sel=29 7.8s
+ 297/401 | loss=0.8086 ev=0.544 agents=198 avg_r=5.4123 sum_r=1385.56 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 8.0s
+ 298/401 | loss=0.7918 ev=0.512 agents=66 avg_r=3.1244 sum_r=799.85 x<0=0.00 elig=0.61 dorfler_tail=0.07 floor=0 sel=24 7.0s
+ 299/401 | loss=0.8891 ev=0.549 agents=200 avg_r=4.3910 sum_r=1124.10 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=27 7.5s
+ 300/401 | loss=0.8565 ev=0.548 agents=349 avg_r=5.9245 sum_r=1516.67 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 8.2s
+[Checkpoint] saved → checkpoints/model_iter0300.pt
+ 301/401 | loss=0.8460 ev=0.520 agents=918 avg_r=3.2190 sum_r=824.07 x<0=0.01 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 8.0s
+ 302/401 | loss=0.8789 ev=0.531 agents=85 avg_r=4.0706 sum_r=1042.08 x<0=0.02 elig=0.62 dorfler_tail=0.08 floor=0 sel=26 7.5s
+ 303/401 | loss=0.7883 ev=0.535 agents=324 avg_r=5.4005 sum_r=1382.52 x<0=0.00 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 7.9s
+ 304/401 | loss=0.7395 ev=0.538 agents=34 avg_r=5.0499 sum_r=1292.78 x<0=0.01 elig=0.61 dorfler_tail=0.08 floor=0 sel=30 8.0s
+ 305/401 | loss=0.7911 ev=0.510 agents=304 avg_r=3.1696 sum_r=811.42 x<0=0.01 elig=0.61 dorfler_tail=0.08 floor=0 sel=26 7.3s
+ 306/401 | loss=0.7920 ev=0.557 agents=383 avg_r=6.0517 sum_r=1549.24 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 8.0s
+ 307/401 | loss=0.8841 ev=0.522 agents=206 avg_r=4.6808 sum_r=1198.28 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=27 7.4s
+ 308/401 | loss=0.8185 ev=0.531 agents=98 avg_r=4.2498 sum_r=1087.96 x<0=0.01 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 7.5s
+ 309/401 | loss=0.7786 ev=0.553 agents=92 avg_r=4.5267 sum_r=1158.84 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.7s
+ 310/401 | loss=0.8129 ev=0.557 agents=232 avg_r=4.8459 sum_r=1240.55 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=26 7.4s
+ 311/401 | loss=0.7548 ev=0.544 agents=85 avg_r=3.9997 sum_r=1023.93 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.6s
+ 312/401 | loss=0.8005 ev=0.574 agents=112 avg_r=5.2808 sum_r=1351.89 x<0=0.00 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 7.6s
+ 313/401 | loss=0.7345 ev=0.581 agents=34 avg_r=4.7019 sum_r=1203.69 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.6s
+ 314/401 | loss=0.9237 ev=0.478 agents=1299 avg_r=1.9343 sum_r=495.18 x<0=0.02 elig=0.62 dorfler_tail=0.08 floor=0 sel=26 7.3s
+ 315/401 | loss=0.7310 ev=0.615 agents=90 avg_r=5.8569 sum_r=1499.36 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.8s
+ 316/401 | loss=0.8623 ev=0.555 agents=125 avg_r=5.8924 sum_r=1508.45 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 7.9s
+ 317/401 | loss=0.9039 ev=0.531 agents=790 avg_r=4.9057 sum_r=1255.87 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.7s
+ 318/401 | loss=0.8584 ev=0.544 agents=667 avg_r=5.5581 sum_r=1422.86 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.8s
+ 319/401 | loss=0.7933 ev=0.559 agents=217 avg_r=3.9606 sum_r=1013.91 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=26 7.4s
+ 320/401 | loss=0.7544 ev=0.577 agents=260 avg_r=4.5550 sum_r=1166.08 x<0=0.00 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 7.5s
+ 321/401 | loss=0.9524 ev=0.525 agents=189 avg_r=5.2861 sum_r=1353.23 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.8s
+ 322/401 | loss=0.7658 ev=0.588 agents=228 avg_r=4.9868 sum_r=1276.62 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 8.0s
+ 323/401 | loss=0.8794 ev=0.551 agents=228 avg_r=5.1649 sum_r=1322.20 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 8.0s
+ 324/401 | loss=0.8258 ev=0.560 agents=926 avg_r=5.6783 sum_r=1453.65 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 8.1s
+ 325/401 | loss=0.8111 ev=0.546 agents=92 avg_r=3.8608 sum_r=988.37 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=26 7.7s
+ 326/401 | loss=0.8054 ev=0.537 agents=44 avg_r=5.0405 sum_r=1290.36 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.8s
+ 327/401 | loss=0.7261 ev=0.572 agents=34 avg_r=4.9393 sum_r=1264.47 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=27 7.6s
+ 328/401 | loss=0.8017 ev=0.541 agents=230 avg_r=4.4739 sum_r=1145.32 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.8s
+ 329/401 | loss=0.7753 ev=0.572 agents=485 avg_r=7.0645 sum_r=1808.50 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 7.9s
+ 330/401 | loss=0.7878 ev=0.545 agents=64 avg_r=4.5437 sum_r=1163.19 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=25 7.4s
+ 331/401 | loss=0.7565 ev=0.557 agents=412 avg_r=4.9920 sum_r=1277.95 x<0=0.01 elig=0.61 dorfler_tail=0.08 floor=0 sel=29 7.8s
+ 332/401 | loss=0.8143 ev=0.552 agents=172 avg_r=3.6211 sum_r=927.01 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=25 7.3s
+ 333/401 | loss=0.9173 ev=0.551 agents=320 avg_r=6.9295 sum_r=1773.94 x<0=0.01 elig=0.62 dorfler_tail=0.09 floor=0 sel=33 8.3s
+ 334/401 | loss=0.8137 ev=0.582 agents=713 avg_r=3.8566 sum_r=987.28 x<0=0.02 elig=0.62 dorfler_tail=0.08 floor=0 sel=26 7.3s
+ 335/401 | loss=0.8842 ev=0.545 agents=60 avg_r=6.7041 sum_r=1716.25 x<0=0.01 elig=0.62 dorfler_tail=0.09 floor=0 sel=28 7.9s
+ 336/401 | loss=0.9756 ev=0.549 agents=1171 avg_r=5.2897 sum_r=1354.17 x<0=0.02 elig=0.62 dorfler_tail=0.09 floor=0 sel=29 7.9s
+ 337/401 | loss=0.9149 ev=0.543 agents=248 avg_r=4.5455 sum_r=1163.64 x<0=0.02 elig=0.62 dorfler_tail=0.08 floor=0 sel=27 7.5s
+ 338/401 | loss=0.8112 ev=0.572 agents=622 avg_r=6.2201 sum_r=1592.33 x<0=0.02 elig=0.62 dorfler_tail=0.08 floor=0 sel=31 7.9s
+ 339/401 | loss=0.8142 ev=0.568 agents=199 avg_r=3.9913 sum_r=1021.77 x<0=0.01 elig=0.61 dorfler_tail=0.08 floor=0 sel=25 7.4s
+ 340/401 | loss=0.8424 ev=0.559 agents=96 avg_r=5.2087 sum_r=1333.43 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.8s
+ 341/401 | loss=0.9293 ev=0.514 agents=81 avg_r=6.3846 sum_r=1634.47 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.9s
+ 342/401 | loss=0.7994 ev=0.581 agents=229 avg_r=4.3458 sum_r=1112.52 x<0=0.01 elig=0.61 dorfler_tail=0.08 floor=0 sel=28 7.5s
+ 343/401 | loss=0.8801 ev=0.527 agents=34 avg_r=4.7860 sum_r=1225.21 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.7s
+ 344/401 | loss=0.7951 ev=0.552 agents=388 avg_r=4.7995 sum_r=1228.67 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=26 7.8s
+ 345/401 | loss=0.9618 ev=0.521 agents=230 avg_r=5.5096 sum_r=1410.46 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 8.1s
+ 346/401 | loss=0.8626 ev=0.531 agents=225 avg_r=3.1414 sum_r=804.19 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=24 7.2s
+ 347/401 | loss=0.9345 ev=0.559 agents=591 avg_r=7.0921 sum_r=1815.57 x<0=0.00 elig=0.62 dorfler_tail=0.09 floor=0 sel=33 8.5s
+ 348/401 | loss=0.9702 ev=0.535 agents=306 avg_r=4.1943 sum_r=1073.73 x<0=0.02 elig=0.62 dorfler_tail=0.08 floor=0 sel=27 7.5s
+ 349/401 | loss=0.9282 ev=0.554 agents=169 avg_r=5.7926 sum_r=1482.90 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 7.9s
+ 350/401 | loss=0.8965 ev=0.529 agents=228 avg_r=4.0997 sum_r=1049.54 x<0=0.01 elig=0.63 dorfler_tail=0.08 floor=0 sel=28 7.6s
+[Checkpoint] saved → checkpoints/model_iter0350.pt
+ 351/401 | loss=0.9006 ev=0.536 agents=86 avg_r=4.7264 sum_r=1209.97 x<0=0.01 elig=0.63 dorfler_tail=0.08 floor=0 sel=27 7.6s
+ 352/401 | loss=0.9423 ev=0.549 agents=400 avg_r=6.4270 sum_r=1645.32 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=31 7.9s
+ 353/401 | loss=0.8666 ev=0.526 agents=430 avg_r=4.5322 sum_r=1160.24 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.5s
+ 354/401 | loss=0.9237 ev=0.542 agents=90 avg_r=4.8545 sum_r=1242.75 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=29 7.6s
+ 355/401 | loss=0.9779 ev=0.510 agents=171 avg_r=4.5744 sum_r=1171.05 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 356/401 | loss=1.0088 ev=0.528 agents=85 avg_r=4.8350 sum_r=1237.76 x<0=0.00 elig=0.63 dorfler_tail=0.08 floor=0 sel=27 7.4s
+ 357/401 | loss=1.0785 ev=0.467 agents=84 avg_r=3.3997 sum_r=870.32 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 358/401 | loss=0.9516 ev=0.541 agents=123 avg_r=6.2179 sum_r=1591.79 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=31 7.8s
+ 359/401 | loss=0.8837 ev=0.540 agents=64 avg_r=5.3393 sum_r=1366.87 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 7.8s
+ 360/401 | loss=1.0886 ev=0.507 agents=829 avg_r=3.6631 sum_r=937.76 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 361/401 | loss=1.0488 ev=0.483 agents=215 avg_r=6.7987 sum_r=1740.47 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 7.7s
+ 362/401 | loss=0.9141 ev=0.505 agents=743 avg_r=3.4182 sum_r=875.05 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 363/401 | loss=0.9284 ev=0.548 agents=94 avg_r=4.6619 sum_r=1193.46 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=27 7.3s
+ 364/401 | loss=0.8426 ev=0.520 agents=157 avg_r=3.2013 sum_r=819.54 x<0=0.01 elig=0.62 dorfler_tail=0.07 floor=0 sel=28 7.4s
+ 365/401 | loss=1.0450 ev=0.499 agents=409 avg_r=5.9785 sum_r=1530.48 x<0=0.00 elig=0.62 dorfler_tail=0.08 floor=0 sel=31 7.8s
+ 366/401 | loss=1.0103 ev=0.517 agents=118 avg_r=4.5559 sum_r=1166.30 x<0=0.01 elig=0.63 dorfler_tail=0.08 floor=0 sel=30 8.0s
+ 367/401 | loss=0.8992 ev=0.548 agents=304 avg_r=5.5253 sum_r=1414.48 x<0=0.01 elig=0.63 dorfler_tail=0.08 floor=0 sel=29 8.1s
+ 368/401 | loss=0.8896 ev=0.542 agents=236 avg_r=4.8329 sum_r=1237.22 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=28 7.8s
+ 369/401 | loss=0.9038 ev=0.547 agents=34 avg_r=4.3783 sum_r=1120.85 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=30 8.0s
+ 370/401 | loss=0.9561 ev=0.534 agents=34 avg_r=4.7629 sum_r=1219.31 x<0=0.02 elig=0.62 dorfler_tail=0.08 floor=0 sel=27 7.5s
+ 371/401 | loss=0.9814 ev=0.522 agents=611 avg_r=4.7171 sum_r=1207.57 x<0=0.01 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.7s
+ 372/401 | loss=0.9877 ev=0.540 agents=119 avg_r=4.1701 sum_r=1067.53 x<0=0.02 elig=0.62 dorfler_tail=0.08 floor=0 sel=29 7.7s
+ 373/401 | loss=0.8940 ev=0.547 agents=39 avg_r=5.0060 sum_r=1281.53 x<0=0.01 elig=0.63 dorfler_tail=0.08 floor=0 sel=30 7.8s
+ 374/401 | loss=1.0368 ev=0.562 agents=197 avg_r=4.9253 sum_r=1260.87 x<0=0.01 elig=0.63 dorfler_tail=0.08 floor=0 sel=27 7.6s
+ 375/401 | loss=0.9746 ev=0.504 agents=200 avg_r=4.9331 sum_r=1262.88 x<0=0.02 elig=0.63 dorfler_tail=0.08 floor=0 sel=27 7.5s
+ 376/401 | loss=0.9767 ev=0.546 agents=276 avg_r=5.4246 sum_r=1388.70 x<0=0.01 elig=0.63 dorfler_tail=0.08 floor=0 sel=30 7.8s
+ 377/401 | loss=0.9836 ev=0.524 agents=198 avg_r=5.0625 sum_r=1296.01 x<0=0.01 elig=0.64 dorfler_tail=0.08 floor=0 sel=27 7.6s
+ 378/401 | loss=1.0488 ev=0.497 agents=745 avg_r=4.0224 sum_r=1029.73 x<0=0.02 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.5s
+ 379/401 | loss=0.9358 ev=0.572 agents=337 avg_r=6.0321 sum_r=1544.22 x<0=0.01 elig=0.63 dorfler_tail=0.08 floor=0 sel=29 7.8s
+ 380/401 | loss=0.9310 ev=0.564 agents=193 avg_r=6.7029 sum_r=1715.94 x<0=0.02 elig=0.63 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 381/401 | loss=0.9425 ev=0.524 agents=1211 avg_r=3.9985 sum_r=1023.62 x<0=0.02 elig=0.63 dorfler_tail=0.09 floor=0 sel=27 7.6s
+ 382/401 | loss=1.0188 ev=0.566 agents=482 avg_r=5.5721 sum_r=1426.45 x<0=0.04 elig=0.63 dorfler_tail=0.08 floor=0 sel=29 7.7s
+ 383/401 | loss=0.9704 ev=0.528 agents=209 avg_r=6.0485 sum_r=1548.41 x<0=0.03 elig=0.64 dorfler_tail=0.08 floor=0 sel=28 7.6s
+ 384/401 | loss=0.9859 ev=0.534 agents=1230 avg_r=5.8093 sum_r=1487.18 x<0=0.02 elig=0.63 dorfler_tail=0.08 floor=0 sel=29 7.8s
+ 385/401 | loss=1.0294 ev=0.542 agents=200 avg_r=4.0988 sum_r=1049.30 x<0=0.02 elig=0.63 dorfler_tail=0.08 floor=0 sel=28 7.6s
+ 386/401 | loss=0.9570 ev=0.537 agents=397 avg_r=5.4463 sum_r=1394.26 x<0=0.02 elig=0.63 dorfler_tail=0.08 floor=0 sel=27 7.5s
+ 387/401 | loss=0.9889 ev=0.533 agents=34 avg_r=6.3465 sum_r=1624.69 x<0=0.01 elig=0.64 dorfler_tail=0.08 floor=0 sel=29 7.6s
+ 388/401 | loss=1.0284 ev=0.518 agents=242 avg_r=6.6849 sum_r=1711.35 x<0=0.01 elig=0.63 dorfler_tail=0.08 floor=0 sel=31 7.9s
+ 389/401 | loss=0.9674 ev=0.506 agents=1219 avg_r=2.7841 sum_r=712.73 x<0=0.01 elig=0.64 dorfler_tail=0.07 floor=0 sel=24 7.3s
+ 390/401 | loss=1.0035 ev=0.524 agents=147 avg_r=7.6948 sum_r=1969.86 x<0=0.00 elig=0.64 dorfler_tail=0.08 floor=0 sel=32 8.5s
+ 391/401 | loss=0.9791 ev=0.521 agents=749 avg_r=4.6773 sum_r=1197.40 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.8s
+ 392/401 | loss=1.0303 ev=0.538 agents=506 avg_r=5.7889 sum_r=1481.96 x<0=0.01 elig=0.63 dorfler_tail=0.08 floor=0 sel=30 7.9s
+ 393/401 | loss=0.9156 ev=0.530 agents=34 avg_r=4.9215 sum_r=1259.91 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=27 7.4s
+ 394/401 | loss=0.9221 ev=0.550 agents=566 avg_r=6.1226 sum_r=1567.39 x<0=0.00 elig=0.63 dorfler_tail=0.08 floor=0 sel=30 7.9s
+ 395/401 | loss=1.0507 ev=0.505 agents=278 avg_r=3.6668 sum_r=938.69 x<0=0.01 elig=0.63 dorfler_tail=0.07 floor=0 sel=28 7.5s
+ 396/401 | loss=1.0621 ev=0.495 agents=535 avg_r=5.1409 sum_r=1316.06 x<0=0.02 elig=0.64 dorfler_tail=0.08 floor=0 sel=27 7.4s
+ 397/401 | loss=0.8922 ev=0.549 agents=145 avg_r=5.6600 sum_r=1448.95 x<0=0.01 elig=0.64 dorfler_tail=0.08 floor=0 sel=29 7.9s
+ 398/401 | loss=1.0484 ev=0.536 agents=62 avg_r=5.7253 sum_r=1465.68 x<0=0.02 elig=0.64 dorfler_tail=0.08 floor=0 sel=26 7.5s
+ 399/401 | loss=1.0258 ev=0.542 agents=146 avg_r=6.1057 sum_r=1563.07 x<0=0.02 elig=0.64 dorfler_tail=0.08 floor=0 sel=29 7.8s
+ 400/401 | loss=0.9834 ev=0.526 agents=697 avg_r=4.9534 sum_r=1268.06 x<0=0.02 elig=0.63 dorfler_tail=0.08 floor=0 sel=28 7.6s
+[Checkpoint] saved → checkpoints/model_iter0400.pt
+ 401/401 | loss=0.9563 ev=0.563 agents=177 avg_r=7.3312 sum_r=1876.79 x<0=0.02 elig=0.64 dorfler_tail=0.08 floor=0 sel=30 7.9s
+[Checkpoint] saved → checkpoints/model_iter0401.pt
+[Checkpoint] saved → checkpoints/model_final.pt
+[Train] done, total time 3050.1s
+Training finished at Sat 30 May 16:07:16 CST 2026
diff --git a/output/__pycache__/build_pptx.cpython-310.pyc b/output/__pycache__/build_pptx.cpython-310.pyc
new file mode 100644
index 0000000..b6ec686
Binary files /dev/null and b/output/__pycache__/build_pptx.cpython-310.pyc differ
diff --git a/output/__pycache__/build_pptx.cpython-313.pyc b/output/__pycache__/build_pptx.cpython-313.pyc
new file mode 100644
index 0000000..f3a1398
Binary files /dev/null and b/output/__pycache__/build_pptx.cpython-313.pyc differ
diff --git a/output/build_pptx.py b/output/build_pptx.py
index 17e3c83..eb8500d 100644
--- a/output/build_pptx.py
+++ b/output/build_pptx.py
@@ -302,8 +302,8 @@ add_textbox(slide, Inches(0.6), Inches(4.2), Inches(12.1), Inches(0.4),
font_color=BLACK, bold=True)
innovations = [
- ("[1] 无量纲化残差误差估计", "k_local 归一化三项残差分量,消除纯几何尺度偏差,跨介质公平可比", ACCENT_BLUE),
- ("[2] Score-based 连续尺寸场", "score = -x_i 纯排序 + 物理预算约束 + Doerfler-P95 动作掩码", ACCENT_TEAL),
+ ("[1] 无量纲化残差误差估计", "真空波数 k 归一化残差+相位/空间特征+GVN,介质内 eta 不被压低", ACCENT_BLUE),
+ ("[2] Score-based 连续尺寸场", "score = -x_i 纯排序 + 物理预算约束 + Reverse Dörfler 动作掩码", ACCENT_TEAL),
("[3] L2 聚合奖励设计", "sqrt(sum eta_child^2) <= eta_parent 保证 r_local >= 0,永不惩罚细化", ACCENT_GREEN),
("[4] 尺度不变性架构", "N_init x domain_area + lambda 无量纲化特征 + ln 压缩 + 前渐近区约束", ACCENT_WARM),
]
@@ -366,9 +366,9 @@ add_textbox(slide, Inches(0.6), Inches(4.1), Inches(6.0), Inches(0.35),
text="RL 问题建模", font_size=SUBHEAD_SIZE, font_color=BLACK, bold=True)
rl_lines = [
("Agent = 每个三角形单元(数量动态变化,约 400 -> 20,000)", False, Pt(11), BODY_GRAY),
- ("State = GNN 节点 12 维特征(几何 + PDE 残差 + 场量 + 物理参数)", False, Pt(11), BODY_GRAY),
+ ("State = GNN 节点 14 维特征(几何 + PDE 残差 + 振幅 + 相位方向 + 物理参数)", False, Pt(11), BODY_GRAY),
("Action = 1 维连续标量 x_i -> score = -x_i 排序 -> top-k 选择细化单元", False, Pt(11), BODY_GRAY),
- ("Reward = L2 聚合局部改善 + 全局势函数塑形 - 动作惩罚", False, Pt(11), BODY_GRAY),
+ ("Reward = 零和预算审查: refined 获 r_local+0.3x(eta/mu-1)-0.06; unrefined r=0", False, Pt(11), BODY_GRAY),
]
add_multiline_textbox(slide, Inches(0.6), Inches(4.5), Inches(6.0), Inches(2.0),
rl_lines, line_spacing=1.6)
@@ -378,7 +378,7 @@ add_textbox(slide, Inches(7.2), Inches(4.1), Inches(5.5), Inches(0.35),
text="PPO 训练配置", font_size=SUBHEAD_SIZE, font_color=BLACK, bold=True)
train_lines = [
("双 GNN 架构:Policy / Value 各自独立 MessagePassingBase", False, Pt(11), BODY_GRAY),
- ("2 层消息传递,inner 残差 + LayerNorm,latent_dim=64", False, Pt(11), BODY_GRAY),
+ ("2 层消息传递 + GVN 全局虚拟节点 (注意力门控广播),inner 残差 + LayerNorm,latent_dim=64", False, Pt(11), BODY_GRAY),
("DiagGaussian 连续动作分布,log_std 可学习,clamp [-4, -1]", False, Pt(11), BODY_GRAY),
("256 步 Rollout,5 Epochs,GAE lambda=0.95,lr=3e-4,梯度裁剪 0.5", False, Pt(11), BODY_GRAY),
]
@@ -399,17 +399,17 @@ add_slide_title(slide, "创新 [1]:无量纲化残差误差估计 -- 消除几
add_textbox(slide, Inches(0.6), Inches(1.25), Inches(5.8), Inches(0.35),
text="前序问题:原始残差包含 h_K、h_e 等几何尺度,不同区域不可直接比较", font_size=Pt(13), font_color=ACCENT_WARM)
add_textbox(slide, Inches(0.6), Inches(1.55), Inches(5.8), Inches(0.35),
- text="解决方案:引入局部波数 k_local 做无量纲归一化,反映相位分辨率残差", font_size=Pt(13), font_color=ACCENT_BLUE)
+ text="解决方案:改用真空波数 k 归一化,介质内残差不再被 sqrt(eps_r) 压低", font_size=Pt(13), font_color=ACCENT_BLUE)
formulas = [
("内部残差 r_int",
- "(h_K/k_local) * sqrt(V) * |k^2*eps_r*u + k^2*(eps_r-1)*u_inc|_K",
- "单元内部 PDE 残差;除以 k_local 使大 eps_r 介质区与真空区可比"),
+ "(h_K/k) * sqrt(V) * |k^2*eps_r*u + k^2*(eps_r-1)*u_inc|_K",
+ "单元内部 PDE 残差;真空波数 k 归一化;SBC 条件保留 k_local"),
("梯度跳变 r_jump",
- "sqrt(1/2 * sum_{e in dK} (h_e/k_local) * |[[grad u * n]]|^2_e)",
- "相邻单元梯度跳变;h_e/k_local 使细化后跳变自然衰减"),
+ "sqrt(1/2 * sum_{e in dK} (h_e/k) * |[[grad u * n]]|^2_e)",
+ "相邻单元梯度跳变;h_e/k 使细化后跳变自然衰减"),
("SBC 边界 r_sbc",
- "(h_bnd/k_local) * |du/dn - i*k_local*u|",
+ "(h_bnd/k) * |du/dn - i*k_local*u|",
"Sommerfeld 吸收边界残差,仅在边界单元非零"),
]
@@ -438,13 +438,13 @@ add_textbox(slide, Inches(7.5), Inches(4.0), Inches(5.0), Inches(0.55),
add_textbox(slide, Inches(0.6), Inches(4.85), Inches(12.1), Inches(0.3),
text="量纲分析验证", font_size=SUBHEAD_SIZE, font_color=BLACK, bold=True)
da_lines = [
- ("k_local ~ [L]^-1, h_e ~ [L], |jump|^2 ~ [L]^-2 => h_e/k_local * |jump|^2 ~ [L]^2 * [L]^-2 = 1 严格无量纲", False, Pt(11), BODY_GRAY),
+ ("k_local ~ [L]^-1, h_e ~ [L], |jump|^2 ~ [L]^-2 => h_e/k * |jump|^2 ~ [L]^2 * [L]^-2 = 1 严格无量纲", False, Pt(11), BODY_GRAY),
("GNN 输入用 log10 压缩的特征;Reward 用原始 eta_K(不经 log 压缩),两者公式一致,物理语义对齐", False, Pt(11), BODY_GRAY),
]
add_multiline_textbox(slide, Inches(0.6), Inches(5.15), Inches(12.1), Inches(0.8),
da_lines, line_spacing=1.5)
-add_takeaway_bar(slide, "k_local 归一化使误差指示子反映相位分辨率残差而非网格粗疏程度,为 RL agent 提供物理一致的误差信号")
+add_takeaway_bar(slide, "真空波数 k 归一化使介质内残差自然放大 ~sqrt(eps_r) 倍,为 RL agent 提供正确的介质内/外优先级信号")
add_slide_number(slide, 5)
@@ -453,7 +453,7 @@ add_slide_number(slide, 5)
# ======================================================================
slide = add_blank_slide()
set_slide_bg(slide, WHITE)
-add_slide_title(slide, "创新 [2]:12 维增强输入特征 -- 赋予 GNN 几何与物理感知")
+add_slide_title(slide, "创新 [2]:14 维增强输入特征 -- 赋予 GNN 振幅与相位方向感知")
add_textbox(slide, Inches(0.6), Inches(1.25), Inches(12.1), Inches(0.35),
text="前序 11 维 -> 现 12 维,新增 dist_to_interface。全部尺度相关特征均以真空波长 lambda=2*pi/k 无量纲化", font_size=Pt(13), font_color=ACCENT_BLUE)
@@ -479,7 +479,7 @@ features = [
("element_penalty", "单元惩罚系数 lambda", "--"),
("timestep", "当前 rollout 步数", "--"),
("wave_number", "Helmholtz 波数 k", "--"),
- ("k_local_sqrt_vol", "k_local x sqrt(volume) 已无量纲", "--"),
+ ("k_local_sqrt_vol", "k x sqrt(eps_r) x sqrt(volume)", "--"),
("is_sbc_boundary", "是否与 SBC 边界相邻 (0/1)", "--"),
("dist_to_interface", "到介质边界的带符号距离 [新增]", "sign(d)*ln(1+|d|/lambda)"),
("epsilon_r", "单元中点介电常数(内=eps_r, 外=1.0)", "--"),
@@ -501,7 +501,7 @@ for i, (name, meaning, norm) in enumerate(features):
# Edge feature note — positioned after table (table bottom = 1.65 + 0.30 + 12*0.30 = 5.55")
add_textbox(slide, Inches(0.6), Inches(5.65), Inches(12.1), Inches(0.25),
- text="边特征 (1 维):euclidean_distance / lambda -- 相邻单元中点无量纲距离 | 合计:12 (节点) + 1 (边) = 13 维图特征",
+ text="边特征 (1 维):euclidean_distance / lambda -- 相邻单元中点无量纲距离 | 合计:14 (节点) + 1 (边) = 15 维图特征",
font_size=Pt(9), font_color=BODY_GRAY)
add_takeaway_bar(slide, "全部与尺度相关的特征均以 lambda 做无量纲归一化;dist_to_interface 用 sign·ln(1+|d|) 对数压缩,近场线性、远场自然压缩,与残差 log10 风格统一")
@@ -534,7 +534,7 @@ algo_steps = [
("Step 2: Score 排序",
"score = -x_i (Actor 输出标量)\nx 越小 -> 优先级越高,纯排序,不设正负门槛"),
("Step 3: 双过滤器",
- "eligible = {i | area_i > 0.25 x A_budget_i AND eta_i >= 0.05 x eta_P95}\narea_floor: 排除已足够细的单元\nDoerfler-P95: 排除低误差单元 (P95 锚定物理误差尺度)"),
+ "eligible = {i | area_i > V_min_safeguard AND i in Reverse_Dorfler_set}\narea_floor: 纯数值底线 (1e-10 x domain_area)\nReverse Dorfler: 能量尾部淘汰 (eps_noise=0.01, >=20% floor)"),
("Step 4: Top-k 选择",
"num = min(|eligible|, N_current//4, remaining//3) (自适应 cap, 增速 N//4)\nselected = top-k by score -> 1-to-4 切分细化"),
]
@@ -549,10 +549,10 @@ for i, (title, content) in enumerate(algo_steps):
add_rect(slide, Inches(0.6), Inches(5.45), Inches(12.1), Inches(0.95), fill_color=None,
line_color=ACCENT_BLUE, line_width=Pt(0.5))
add_textbox(slide, Inches(0.8), Inches(5.5), Inches(11.7), Inches(0.85),
- text="为什么用 Doerfler-P95 而非 median/mean?P95 锚定物理误差尺度,免疫远场噪声稀释。远场低 eta 区即使占 90% 的单元,也不会拉低锚点。确保只有误差真正达标的区域才消耗细化预算。",
+ text="为什么用 Reverse Dörfler 而非 P95 硬阈值?P95 在重尾分布下会被奇异点推至极高,一刀切屏蔽大片中等误差区域。Reverse Dörfler 基于能量累积 (L2 范数平方和),自适应于任意分布形态,剔除确认无价值的底部噪声,保留 >=20% 单元确保 Agent 选择空间。",
font_size=Pt(11), font_color=BODY_GRAY)
-add_takeaway_bar(slide, "Score-based 排序 + 物理预算 + Doerfler-P95 掩码:三层保障确保细化资源只投入到物理上需要的地方")
+add_takeaway_bar(slide, "Score-based 排序 + 物理预算 + Reverse Dörfler 掩码:三层保障确保细化资源只投入到物理上需要的地方")
add_slide_number(slide, 7)
@@ -608,16 +608,17 @@ add_multiline_textbox(slide, Inches(0.6), Inches(4.8), Inches(6.0), Inches(0.7),
pen_lines, line_spacing=1.5)
add_textbox(slide, Inches(7.2), Inches(4.45), Inches(5.5), Inches(0.3),
- text="全局势函数塑形", font_size=SUBHEAD_SIZE, font_color=BLACK, bold=True)
+ text="Actor 奖励设计原则", font_size=SUBHEAD_SIZE, font_color=BLACK, bold=True)
glob_lines = [
- ("E_global = sqrt(sum eta_K^2) / ||u_h||_{L2(Omega)} (无量纲全局误差)", False, Pt(12), BODY_GRAY),
- ("global_bonus = alpha x [log(E_old) - log(E_new)], alpha = 0.2", False, Pt(12), BODY_GRAY),
- ("仅发给被细化的父单元 -- 避免被未细化单元稀释信号", False, Pt(11), CAPTION),
-]
+ ("global_bonus 被 Helmholtz 污染误差污染", False, Pt(12), BODY_GRAY),
+ ("E_new > E_old 可发生在正确细化后", False, Pt(11), BODY_GRAY),
+ ("惩罚 Agent 做对的事 → 策略崩塌 (x<0→0.01)", False, Pt(11), BODY_GRAY),
+ ("修正: global_bonus 仅诊断, 不注入 Actor reward", False, Pt(11), CAPTION),
+ ]
add_multiline_textbox(slide, Inches(7.2), Inches(4.8), Inches(5.5), Inches(0.7),
glob_lines, line_spacing=1.5)
-add_takeaway_bar(slide, "奖励公式 = L2 聚合局部改善 (>=0) + 全局势函数塑形 (仅细化单元) - 轻微动作惩罚 -> 每个被细化父单元净奖励约 +0.387")
+add_takeaway_bar(slide, "零和预算审查: 奖金 0.3*(eta/mu-1) 全场求和为零 (Doerfler 准则 RL 对偶); unrefined r=0; global_bonus 仅诊断")
add_slide_number(slide, 8)
@@ -771,12 +772,14 @@ add_textbox(slide, Inches(0.8), Inches(1.85), Inches(5.4), Inches(0.3),
text="MessagePassingBase (x2, Policy / Value 各自独立基座)", font_size=Pt(13), font_color=ACCENT_BLUE, bold=True)
gnn_items = [
- ("节点嵌入", "Linear(12 -> 64)"),
+ ("节点嵌入", "Linear(14 -> 64)"),
("边嵌入", "Linear(1 -> 64)"),
("MP Step 1", "EdgeModule: MLP([src|dst|edge_attr]) -> 64d"),
("", "NodeModule: MLP([node|scatter_mean(入边)]) -> 64d"),
("", "+ inner 残差 + LayerNorm"),
("MP Step 2", "同 Step 1,堆叠 2 层"),
+ ("GVN 全局虚拟节点", "h_V = Σ(η_v/Ση)·h_v (η_K 加权池化)"),
+ ("", "α = σ(W[h_v||h_V]),h_v += scale·α ⊙ W_V·h_V"),
("输出", "节点隐向量 (num_nodes, 64)"),
]
@@ -896,10 +899,10 @@ add_slide_title(slide, "创新点汇总与可复用价值")
innovations = [
("[1]", "无量纲化\n残差误差估计",
- "k_local 归一化三项残差分量\n消除纯几何尺度偏差\nGNN 输入与 Reward 公式物理一致",
+ "真空波数 k 归一化残差\n介质内 η 不再被压低\nGNN+Reward 统一使用 k 归一化",
ACCENT_BLUE),
("[2]", "Score-based\n连续尺寸场",
- "score = -x_i 纯排序\n物理预算 N_budget 约束\nDoerfler-P95 双过滤器掩码",
+ "score = -x_i 纯排序\n物理预算 N_budget 约束\nReverse Dörfler 双过滤器掩码",
ACCENT_TEAL),
("[3]", "L2 聚合\n奖励设计",
"sqrt(sum eta_child^2) <= eta_parent 天然成立\n永不惩罚细化 (r_local >= 0)\nint 主导区强正奖励约 +0.69",
@@ -927,9 +930,9 @@ add_textbox(slide, Inches(0.6), Inches(4.7), Inches(12.1), Inches(0.3),
reuse_items = [
("L2 聚合 + 父子映射", "适用于任何分裂型变长 agent RL 场景(网格细化、树搜索、层次化决策)"),
- ("k_local 无量纲化方法", "适用于具有特征尺度的任何 PDE 问题:跨介质、跨频率、跨几何的统一误差度量"),
+ ("真空波数 k 归一化方法", "残差归一化用 k₀ 非 k_local,介质内物理信号不再被压低"),
("Score-based + 预算约束选择", "适用于资源受限的排序-选择问题:传感器部署、计算资源分配、实验设计优化"),
- ("Doerfler-P95 动作掩码", "P95 锚定物理尺度的思想可推广到任何需要排除低信号样本的场景"),
+ ("Reverse Dörfler 动作掩码", "能量尾部淘汰的思想可推广到任何需要排除低信号样本的场景"),
]
for i, (tag, desc) in enumerate(reuse_items):
add_textbox(slide, Inches(0.8), Inches(5.05 + i * 0.42), Inches(2.8), Inches(0.35),
@@ -1002,8 +1005,8 @@ add_textbox(slide, Inches(0.85), Inches(2.0), Inches(11.5), Inches(1.0),
summary_points = [
"提出了一套完整的 RL 自适应网格细化框架:从物理建模、误差估计、状态表征、动作空间到奖励设计的全链路创新",
- "无量纲化残差误差估计 (k_local 归一化) 使误差指示子具有跨介质、跨频率的物理一致性",
- "Score-based 尺寸场 + 物理预算约束 + Doerfler-P95 掩码实现了资源感知的细化单元选择",
+ "真空波数 k 归一化残差使介质内 η 自然放大,Agent 获得正确的物理优先级信号",
+ "Score-based 尺寸场 + 物理预算约束 + Reverse Dörfler 掩码实现了资源感知的细化单元选择",
"L2 聚合奖励设计从数学上保证了细化奖励非负,从根本上避免了 L1 sum 的结构性负偏置",
"sign(d)*ln(1+|d|/lambda) 对数压缩 + lambda 归一化全部特征实现了域尺寸的尺度不变泛化",
]
diff --git a/output/final_presentation_cn.pptx b/output/final_presentation_cn.pptx
index 72d43dd..9e1b0d2 100644
Binary files a/output/final_presentation_cn.pptx and b/output/final_presentation_cn.pptx differ
diff --git a/paper_outline.md b/paper_outline.md
new file mode 100644
index 0000000..7d60b95
--- /dev/null
+++ b/paper_outline.md
@@ -0,0 +1,155 @@
+# 论文大纲框架
+
+**暂定标题(中文):** 基于图神经网络与强化学习的亥姆霍兹散射问题自适应网格细化
+
+**暂定标题(英文):** Reinforcement Learning–Driven Adaptive Mesh Refinement for 2D Helmholtz Scattering via Graph Neural Networks
+
+---
+
+## 1. Introduction(引言)
+
+### 1.1 领域背景与重要性
+- 高频亥姆霍兹方程在电磁散射、声学等领域的重要性
+- 有限元方法(FEM)求解亥姆霍兹问题的挑战:污染效应(pollution effect),即标准FEM在高频下误差随波数增长
+
+### 1.2 现有方法与瓶颈
+- 自适应网格细化(AMR)的传统方法:基于残差的误差指示器、Dörfler标记策略
+- 传统AMR的局限性:启发式标记策略难以捕获全局误差分布;高频问题中局部指标与全局误差脱节
+- 已有的机器学习方法尝试(如有相关工作)
+
+### 1.3 本文贡献(Gap → Solution)
+- 提出将AMR建模为马尔可夫决策过程(MDP),使用PPO训练GNN策略网络
+- 三个核心创新点:
+ - (a)空间奖励函数设计,考虑网格细化层级映射
+ - (b)全局虚拟节点(GVN)GNN架构,突破消息传递的直径瓶颈
+ - (c)物理信息特征(相位距离、局部波数)提升泛化能力
+
+### 1.4 论文组织
+- 简述后续各节安排
+
+---
+
+## 2. Problem Formulation(问题形式化)
+
+### 2.1 亥姆霍兹散射问题的数学描述
+- 控制方程:$\nabla^2 u_{scat} + k^2 \epsilon_r u_{scat} = k^2(1-\epsilon_r)u_{inc}$
+- Sommerfeld辐射边界条件
+- P1三角单元的FEM离散
+
+### 2.2 残差误差指示器
+- $\eta_K$ 的定义:内部残差 + 梯度跳跃 + SBC边界项
+- 误差指示器的物理意义
+
+### 2.3 AMR作为序贯决策问题
+- 为什么传统的单步标记策略不够
+- 将多步细化过程建模为MDP的理由
+
+---
+
+## 3. Method(方法)
+
+### 3.1 RL Environment(强化学习环境)
+
+#### 3.1.1 状态空间(State)
+- 图表示:节点 = 网格单元,边 = 邻接关系
+- 节点特征(13维):几何、残差、解信息、时间步
+- 边特征(1维):相位距离
+
+#### 3.1.2 动作空间(Action)
+- 连续评分,基于排序选择top-k细化
+
+#### 3.1.3 奖励函数(Reward)
+- 基于 $\log(\eta_{old}) - \log(\eta_{new})$ 的对数误差缩减
+- 零和奖励项(Dörfler准则的软实现)
+- 元素数惩罚项 $\lambda \cdot (N_{new} - 1)$
+
+#### 3.1.4 预算约束
+- $N_{budget} \propto k^2$
+
+### 3.2 GNN Policy Architecture(GNN策略架构)
+
+#### 3.2.1 消息传递基座
+- 2层边更新 + 节点更新
+- 残差连接 + LayerNorm
+
+#### 3.2.2 全局虚拟节点(GVN)
+- 注意力门控池化
+- 注入全局误差分布上下文,突破消息传递的直径瓶颈
+
+#### 3.2.3 Actor-Critic头
+- 分离的策略头和价值头
+- Actor:对角高斯分布
+- Critic:节点级价值聚合
+
+### 3.3 PPO Training(PPO训练)
+- 自定义RolloutBuffer处理可变智能体数量(网格细化导致节点数变化)
+- GAE计算中使用scatter_add将子节点价值投影回父节点
+- 标准PPO裁剪损失 + 熵正则化
+
+---
+
+## 4. Experiments(实验)
+
+### 4.1 Experimental Setup(实验设置)
+- 数值求解器:scikit-fem,P1三角单元
+- 训练配置:401次迭代,256步rollout
+- 初始网格:基于波数 $k$ 和域面积自动缩放($N \propto k^2$)
+- 预渐近约束:$h \leq \lambda_d / 1.5$
+
+### 4.2 Baselines(基线方法)
+- 均匀细化(Uniform refinement)
+- 基于残差误差指示器的传统AMR(Dörfler标记)
+- 随机策略(Random policy)
+- (如有其他消融实验变体)
+
+### 4.3 Main Results(主要结果)
+- 不同波数 $k$ 下的误差收敛曲线(error vs. DOF)
+- 不同散射体几何(圆形、多圆形、方形)的泛化性能
+- 网格演化可视化(refinement pattern)
+
+### 4.4 Ablation Studies(消融实验)
+- 奖励函数设计的影响(有/无零和奖励、有/无元素数惩罚)
+- GVN模块的贡献(有/无全局上下文)
+- 物理信息特征(相位距离)的影响
+- 消息传递层数的影响
+
+### 4.5 Analysis & Diagnostics(分析与诊断)
+- 学到的细化模式分析(是否集中在散射体边界/高梯度区域)
+- 动作分布统计($x<0$ 比率的变化趋势)
+- 训练曲线(奖励、误差缩减、元素数的收敛过程)
+
+---
+
+## 5. Discussion(讨论)
+
+- **核心优势**:RL策略能够学习超越传统启发式的全局细化模式
+- **与传统方法的关系**:学到的策略隐式地实现了类似Dörfler的标记,但具有更强的上下文感知
+- **GVN的作用**:全局信息对高频问题中跨域误差传播的关键性
+- **局限性**:
+ - 当前仅限2D亥姆霍兹问题
+ - P1单元的固有色散误差未被修正
+ - 训练成本较高
+- **未来方向**:
+ - 双加权残差(DWR):引入伴随误差估计以获得更准确的奖励信号
+ - 相空间方法:使用Wigner分布引导基于动量失配的细化
+ - 算子修正:探索Trefftz方法或GLS稳定化以减少P1单元的固有色散误差
+
+---
+
+## 6. Conclusion(结论)
+
+- 贡献总结:将AMR建模为RL问题,设计了空间奖励函数和GVN-GNN架构
+- 关键证据:在多个波数和几何上展示了误差收敛优势
+- 影响:为高频波传播问题的数据驱动网格优化提供了新范式
+- 边界:当前框架的适用范围与假设
+
+---
+
+## 补充说明
+
+| 项目 | 说明 |
+|---|---|
+| 论文类型 | 方法论文(Method paper) |
+| 核心主张 | RL+GNN可以学习优于传统启发式的AMR策略,尤其在高频亥姆霍兹问题中 |
+| 证据支撑 | 误差收敛曲线、不同几何泛化、消融实验、网格演化可视化 |
+| 待确认 | 是否有与传统AMR的定量对比数据?是否有跨波数泛化的实验?GVN消融结果如何? |
diff --git a/paper_outline.tex b/paper_outline.tex
new file mode 100644
index 0000000..578636b
--- /dev/null
+++ b/paper_outline.tex
@@ -0,0 +1,466 @@
+\documentclass[11pt,a4paper]{article}
+
+% ---- 基础包 ----
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage{amsmath,amssymb,amsfonts}
+\usepackage{graphicx}
+\usepackage{booktabs}
+\usepackage{hyperref}
+\usepackage[margin=2.5cm]{geometry}
+\usepackage{enumitem}
+\usepackage{xcolor}
+
+% ---- 实验标注命令 ----
+\newcommand{\needexp}[1]{\textcolor{red}{[实验待做: #1]}}
+
+% ---- 标题信息 ----
+\title{基于图神经网络与强化学习的亥姆霍兹散射问题自适应网格细化:\\
+跨波数零样本泛化与非局域误差传播}
+\author{[作者姓名] \\ [单位]}
+\date{}
+
+\begin{document}
+
+\maketitle
+
+% ============================================================
+\section{Introduction(引言)}
+% ============================================================
+
+\subsection{领域背景(Field Scale)}
+
+\begin{itemize}
+ \item 高频亥姆霍兹方程 $\nabla^2 u + k^2\varepsilon_r u = f$ 是电磁散射、声学传播、地震成像等领域的核心控制方程
+ \item 有限元方法(FEM)求解亥姆霍兹问题的核心困难:\textbf{污染效应(pollution effect)}——标准 P1 Galerkin FEM 的色散误差随波数 $k$ 增大而累积,导致"即使每波长分辨率足够,远场相位误差仍不可接受"
+ \item 缓解污染效应的主要手段:\textbf{自适应网格细化(AMR)}——在有物理特征(介质界面、高梯度区)的地方局部加密网格,在平缓区保持粗网格
+\end{itemize}
+
+\subsection{现有方法与瓶颈(Prior Attempts \& Bottleneck)}
+
+\begin{itemize}
+ \item \textbf{传统 AMR:}基于后验误差估计子(残差型 $\eta_K$、梯度恢复型)的单步启发式标记策略(D\"{o}rfler 标记、最大策略标记)
+ \item \textbf{传统方法的两个根本局限:}
+ \begin{enumerate}
+ \item \textbf{贪心单步决策}:每步仅根据当前误差分布标记细化区域,无法规划多步预算分配——早期过度细化低价值区域会耗尽后续步的预算
+ \item \textbf{局部信息盲区}:高频亥姆霍兹的误差通过波动物理在长距离上非局域传播(介质界面的误差影响远场散射场),而传统误差指示子仅反映局部残差,无法感知误差的因果来源
+ \end{enumerate}
+ \item \textbf{已有 ML-AMR 方法:}Adaptive Swarm Mesh Refinement (ASMR) 首次将 AMR 形式化为多智能体 MDP 并用 PPO 训练 GNN 策略,但:
+ \begin{itemize}
+ \item 针对泊松/椭圆型方程(自伴、椭圆、误差局部扩散),消息传递机制在椭圆型设置下足够
+ \item 未涉及高频亥姆霍兹方程的非局域性、不定号性和污染效应
+ \end{itemize}
+\end{itemize}
+
+\subsection{未解决的核心 gap(Unresolved Gap)}
+
+\begin{itemize}
+ \item 高频亥姆霍兹散射中的非局域误差传播要求网格细化策略具备\textbf{全局上下文感知能力}——标准 GNN 的局部消息传递受限于图的直径,需 $O(\text{diameter})$ 层数才能传递远距离信息
+ \item 传统 AMR 的误差指示子和标记阈值是\textbf{$k$ 相关的}——针对某个波数调好的参数在更高频段失效,需要重新调参
+ \item 已有方法需依赖真值或超精细网格参考解作为训练信号——在实际工程中通常不可得
+\end{itemize}
+
+\subsection{本文贡献(Present Study)}
+
+提出一种针对高频亥姆霍兹散射的 RL-GNN 自适应网格细化方法。核心贡献:
+
+\begin{enumerate}[label=\textbf{C\arabic*}, leftmargin=*]
+ \item \textbf{首次将 RL-AMR 拓展到高频亥姆霍兹方程。}通过全局虚拟节点(GVN)架构解决非局域误差传播问题,使得 GNN 策略能感知全局误差分布。
+ \item \textbf{跨波数零样本泛化。}通过 $k$ 不变特征归一化(真空波数归一化 + 相位距离边特征),策略在中等波数 $k\in[3,15]$ 训练后可直接泛化到更高波数 $k=30$——无需重新调参或微调。传统 AMR 方法无法做到这一点。
+ \item \textbf{残差型后验误差估计子 $\eta_K$ 作为奖励信号。}无需解析解或超精细参考网格,使方法可应用于任意散射体几何和介质分布。
+ \item \textbf{因果隔离的奖励函数设计。}通过 agent\_mapping 追踪父子元素层级,保证奖励信号的因果正确性:全局误差变化不反馈给 Actor,未细化父元素获得零奖励。
+\end{enumerate}
+
+\subsection{论文组织}
+
+第 2 节建立问题形式化,第 3 节详述方法,第 4 节给出实验与消融分析,第 5 节讨论与展望,第 6 节总结。
+
+% ============================================================
+\section{Problem Formulation(问题形式化)}
+% ============================================================
+
+\subsection{亥姆霍兹散射问题}
+
+\textbf{控制方程(二维):}
+\begin{equation}
+ \nabla^2 u_{\mathrm{scat}} + k^2 \varepsilon_r(\mathbf{x}) u_{\mathrm{scat}}
+ = k^2\big(1-\varepsilon_r(\mathbf{x})\big) u_{\mathrm{inc}}(\mathbf{x})
+ \label{eq:helmholtz}
+\end{equation}
+
+其中 $u_{\mathrm{scat}}$ 为散射场,$u_{\mathrm{inc}}$ 为入射平面波,$k$ 为真空波数,$\varepsilon_r(\mathbf{x})$ 为相对介电常数分布。外边界施加一阶 Sommerfeld 辐射条件:
+\begin{equation}
+ \frac{\partial u_{\mathrm{scat}}}{\partial n} - i k u_{\mathrm{scat}} = 0
+ \label{eq:sbc}
+\end{equation}
+
+\textbf{散射体:}圆形介质柱($\varepsilon_r \in [2.0, 8.0]$),半径和位置可随机化。计算域为 $[0,1] \times [0,1]$ 矩形。
+
+\textbf{FEM 离散:}P1 线性三角单元。Galerkin 弱形式:
+\begin{equation}
+ \int_\Omega \nabla u_h \cdot \nabla v_h \,dx
+ - k^2\int_\Omega \varepsilon_r u_h v_h \,dx
+ - ik\oint_{\partial\Omega} u_h v_h \,ds
+ = -k^2\int_\Omega (1-\varepsilon_r)u_{\mathrm{inc}} v_h \,dx
+\end{equation}
+
+\subsection{残差型后验误差估计子 $\eta_K$}
+
+对每个三角单元 $K$,定义无量纲残差误差指示子(以真空波数 $k$ 归一化,\textbf{非}局部波数 $k\sqrt{\varepsilon_r}$):
+
+\begin{equation}
+ \eta_K^2 =
+ \underbrace{\left(\frac{h_K}{k}\right)^2 \cdot V_K \cdot \big|k^2\varepsilon_r u_h + k^2(\varepsilon_r-1)u_{\mathrm{inc}}\big|^2}_{\text{内部残差}}
+ + \underbrace{\frac{1}{2}\sum_{e\in\partial K} \frac{h_e}{k} \cdot \big\|[\kern-2pt[ \nabla u_h\cdot\mathbf{n} ]\kern-2pt]\big\|^2_e}_{\text{梯度跳跃}}
+ + \underbrace{\frac{h_{\mathrm{bnd}}}{k} \cdot \big|\frac{\partial u_h}{\partial n} - ik u_h\big|^2}_{\text{SBC 边界残差}}
+ \label{eq:eta}
+\end{equation}
+
+\textbf{为什么用真空波数归一化:}使用局部波数 $k_{\mathrm{local}} = k\sqrt{\varepsilon_r}$ 会导致介质内部 $\eta_K$ 被人为压制 $\sqrt{\varepsilon_r}$ 倍,使 GNN 对介质内部区域"视而不见"。用真空波数 $k$ 保证不同介质区域的误差指示子可比。
+
+\textbf{为什么用 $\eta_K$ 作为奖励而非真值:}在实际散射问题中,不存在解析解或超精细参考解。$\eta_K$ 是仅依赖当前 FEM 解的可计算量,且在预渐近条件下($h \leq \lambda_d/N$)与真实误差等价(可靠性 + 有效性)。这使得整个方法不绑定任何特定几何或介质。
+
+\subsection{预渐近约束(Pre-asymptotic Resolution)}
+
+在细化开始前,强制介质内部单元满足 $h_K \leq \lambda_d / N$($N=1.5$,$\lambda_d = 2\pi/(k\sqrt{\varepsilon_r})$ 为介质内波长),确保初始网格已充分解析介质内部波的相位变化。该约束防止 GNN 从"纯数值噪声"中学习。
+
+\subsection{AMR 作为序贯决策问题}
+
+将 $T$ 步网格细化过程形式化为 MDP $\langle \mathcal{S}, \mathcal{A}, P, R, \gamma \rangle$:
+
+\begin{itemize}
+ \item \textbf{状态 $\mathcal{S}$:}图 $\mathcal{G}_t = (\mathcal{V}_t, \mathcal{E}_t)$,节点为三角单元,边为共享棱边的邻接关系。节点特征 13 维,边特征 1 维(相位距离,见 \S\ref{sec:features})
+ \item \textbf{动作 $\mathcal{A}$:}每个单元输出连续评分 $x_i \in \mathbb{R}$,按 $\mathrm{score}_i = -x_i$ 降序排列,在物理预算 $N_{\mathrm{budget}} \propto k^2$ 约束下选择 top-$k$ 单元进行细化(Rivara 最长边二分 + 一致性闭包)
+ \item \textbf{奖励 $R$:}基于 $\eta_K$ 的对数误差缩减(见 \S\ref{sec:reward})
+ \item \textbf{终止:}达到最大步数 $T_{\max}=4\sim6$,或预算耗尽,或网格总单元数超过上限(50k)
+ \item \textbf{关键区别(vs 传统 AMR):}策略可以跨步规划——在早期步骤有意保留预算,在后期步骤集中处理高价值区域
+\end{itemize}
+
+% ============================================================
+\section{Method(方法)}
+% ============================================================
+
+\subsection{$k$ 不变特征设计}
+\label{sec:features}
+
+为使 GNN 在不同波数 $k$ 下看到相似分布的输入,所有特征均设计为 $k$ 无关或 $k$ 尺度化的形式。
+
+\textbf{节点特征(13 维):}
+\begin{enumerate}[leftmargin=*]
+ \item 单元体积 $V_K$(经过对数压缩)
+ \item--4. 三个残差分量:$\log(1 + \eta_{K,\mathrm{int}})$, $\log(1 + \eta_{K,\mathrm{jump}})$, $\log(1 + \eta_{K,\mathrm{bnd}})$
+ \item 惩罚项标志(是否属于细化惩罚区)
+ \item 当前时间步 $t/T_{\max}$
+ \item $k\sqrt{V_K}$:波数-尺度耦合特征
+ \item SBC 边界标志:单元是否接触 Sommerfeld 边界
+ \item 到介质界面的有符号对数距离:$\mathrm{sign}(d) \cdot \log(1 + |d|)$
+ \item $\varepsilon_r$:单元所在介质的相对介电常数
+ \item 场幅值:$|u_h|$
+ \item--13. 复场的相位特征:$\cos(\angle u_h)$, $\sin(\angle u_h)$
+\end{enumerate}
+
+\textbf{边特征(1 维):}
+\begin{equation}
+ e_{ij} = k \cdot |\mathbf{x}_i^{\mathrm{mid}} - \mathbf{x}_j^{\mathrm{mid}}| \pmod{2\pi}
+\end{equation}
+即两个相邻单元中点之间的相位距离。该特征是 $k$ 自适应的——在更高波数下,物理波长更短,中点距离自然更大(以相位度量)。以此保证跨波数下边特征的分布一致。
+
+\subsection{奖励函数设计:因果隔离 + 零和预算审计}
+\label{sec:reward}
+
+奖励函数的核心原则:
+
+\begin{enumerate}[leftmargin=*]
+ \item \textbf{基于 $\eta_K$ 而非真值}(如上所述)
+ \item \textbf{因果隔离:}仅被细化的父元素获得奖励,未细化的父元素获得零奖励。全局误差变化不反馈给 Actor——因为高频亥姆霍兹的远场误差受介质内部多个区域共同影响,将全局误差直接分配给局部动作会破坏因果关系
+ \item \textbf{零和预算审计:}受 D\"{o}rfler 标记策略启发,引入零和奖励项——$\eta_K$ 高于均值的元素获得正奖励,低于均值的元素获得等量负惩罚。保证整体预算中性
+\end{enumerate}
+
+\textbf{奖励计算公式:}
+\begin{equation}
+ r_i = \underbrace{\log\eta_{K,i}^{\mathrm{old}} - \max_{j \in \mathrm{children}(i)} \log\eta_{K,j}^{\mathrm{new}}}_{\text{对数误差缩减}}
+ + \underbrace{\alpha \cdot \big(\eta_{K,i} - \bar{\eta}_K\big)}_{\text{零和 D\"{o}rfler 奖励}}
+ - \underbrace{\lambda \cdot (n_i^{\mathrm{children}} - 1)}_{\text{元素数惩罚}}
+\end{equation}
+
+其中 $\mathrm{children}(i)$ 通过 \texttt{agent\_mapping} $\phi_{ij}$ 将子元素误差映射到父元素,取 $\max$(最差子元素决定奖励,驱动策略优先处理最难改善的区域)。
+
+\textbf{奖励归一化:}每个 rollout 内对所有 agent 的奖励做 z-score 标准化,移除 reward scale 对 PPO 更新的影响。
+
+\subsection{GNN 策略架构}
+
+\subsubsection{消息传递基座(MessagePassingBase)}
+
+\begin{itemize}
+ \item 节点特征嵌入:Linear(13, 64) + Tanh
+ \item 边特征嵌入:Linear(1, 64) + Tanh
+ \item \texttt{MessagePassingStack}:2 层 $\{\text{EdgeModule} \to \text{NodeModule}\}$
+ \begin{itemize}
+ \item EdgeModule:聚合相邻节点特征 $h_i, h_j$ 与边特征 $e_{ij}$,更新边表征
+ \item NodeModule:聚合邻边表征,更新节点表征
+ \item 每层内部含残差连接 + LayerNorm
+ \end{itemize}
+ \item 训练时 Edge Dropout = 0.1
+\end{itemize}
+
+\subsubsection{全局虚拟节点(Global Virtual Node, GVN)}
+
+\textbf{设计动机:}标准消息传递 GNN 的信息传播受限于图的直径——要在相距 $d$ 跳的两个节点间传递信息,至少需要 $d$ 层消息传递。对于高频亥姆霍兹问题,介质界面的误差通过波传播影响远场,需要全局上下文。GVN 提供 $O(1)$ 的全局信息通道。
+
+\textbf{GVN 机制:}
+\begin{enumerate}[leftmargin=*]
+ \item \textbf{池化:}对所有节点特征做误差加权池化,得到全局上下文向量 $g$:
+ \begin{equation}
+ g = \sum_{i\in\mathcal{V}} w_i \cdot h_i, \quad w_i = \frac{\eta_{K,i}}{\sum_j \eta_{K,j}}
+ \end{equation}
+ 误差越大的节点对全局上下文的贡献越大
+ \item \textbf{注意力门控广播:}将 $g$ 广播回每个节点,通过可学习的注意力门控 $\gamma_i \in [0,1]$ 控制每个节点对全局信息的接收程度:
+ \begin{equation}
+ h_i' = h_i + \gamma_i \cdot g, \quad \gamma_i = \sigma\big(\mathrm{MLP}([h_i, g])\big)
+ \end{equation}
+ 不同物理区域的节点对全局信息的需求不同:介质界面附近需要远场上下文,均匀介质内部几乎不需要
+\end{enumerate}
+
+\textbf{GNN 总参数量:}92,740
+
+\subsubsection{Actor-Critic 双头}
+
+\begin{itemize}
+ \item \textbf{策略头(Actor):}MLP(64, 32) + Tanh $\to$ Linear(32, 1) $\to$ 动作均值 $\mu_i$;可学习 log\_std(初始化 $-2.0$,截断 $[-4.0, -1.0]$)$\to$ \texttt{DiagGaussianDistribution}
+ \item \textbf{价值头(Critic):}MLP(64, 32) + Tanh $\to$ Linear(32, 1) $\to$ 逐元素价值 $V_i$
+ \item 策略头和价值头不共享除 GNN backbone 外的参数
+\end{itemize}
+
+\subsection{PPO 训练}
+
+\subsubsection{处理可变智能体数量}
+
+网格细化导致元素数量变化,标准 RL 假设固定数量 agent。解决方案:在 GAE 计算阶段,通过 \texttt{scatter\_add} 将子节点价值 $V_j(s_{t+1})$ 按 \texttt{agent\_mapping} $\phi_{ij}$ 投影回父节点索引:
+
+\begin{equation}
+ \delta_i^t = r_i(s_t, a_t) + \gamma \cdot \sum_{j} \phi_{ij}^t \cdot V_j(s_{t+1}) - V_i(s_t)
+\end{equation}
+
+\subsubsection{训练超参数}
+
+\begin{table}[h]
+\centering
+\begin{tabular}{ll}
+\toprule
+参数 & 值 \\
+\midrule
+Rollout 步数 & 256 / iteration \\
+PPO epochs & 3 / iteration \\
+折扣因子 $\gamma$ & 0.99 \\
+GAE $\lambda$ & 0.95 \\
+Clip range & 0.2 \\
+Max grad norm & 0.5 \\
+学习率 & $3\times10^{-4}$(Adam) \\
+熵系数 & 0.005 \\
+价值损失系数 & 0.5 \\
+总迭代数 & 401 \\
+\bottomrule
+\end{tabular}
+\end{table}
+
+\subsection{动作掩码:Reverse D\"{o}rfler}
+
+在动作选择前,应用"反向 D\"{o}rfler"过滤:按 $\eta_K$ 升序排列单元,累计误差贡献 $< 1\%$ 总误差能量的尾部单元被标记为不可细化(排除数值噪声)。同时设 20\% 最低可选比例,确保智能体始终有充足的选择空间。
+
+% ============================================================
+\section{Experiments(实验)}
+% ============================================================
+
+\textbf{标注说明:}红色标注 \needexp{...} 表示尚未完成的实验。
+
+\subsection{实验设置}
+
+\begin{itemize}
+ \item \textbf{PDE 求解器:}scikit-fem, P1 三角单元
+ \item \textbf{计算域:}$[0,1]^2$,默认散射体为圆形介质柱
+ \item \textbf{训练 PDE 分布:}$k \in [3, 15]$ 随机采样,$\varepsilon_r \in [2.0, 4.0]$ 随机采样,圆形散射体半径和位置随机
+ \item \textbf{初始网格:}密度 $\propto k^2$,预渐近约束 $h \leq \lambda_d/1.5$
+ \item \textbf{训练配置:}401 iteration $\times$ 256 rollout steps,单 GPU 约 55 分钟
+ \item \textbf{硬件:}[填写 GPU 型号]
+\end{itemize}
+
+\subsection{基线方法}
+
+\begin{enumerate}[leftmargin=*]
+ \item \textbf{均匀细化(Uniform):}每步对所有单元无差别细化(等价于全局 $h$-refinement)
+ \item \textbf{D\"{o}rfler 标记(D\"{o}rfler):}使用 $\eta_K$ 作为误差指示子,D\"{o}rfler 参数 $\theta=0.5$,标记累计误差占比 $\geq 50\%$ 的最小单元集合
+ \item \textbf{最大策略标记(Max-marking):}每步选取 $\eta_K$ 最高的 top-$k$ 单元($k$ 与 RL 预算一致)
+ \item \textbf{随机策略(Random):}在可选单元中等概率随机选择
+ \item \textbf{RL w/o GVN(消融):}本文方法的 GVN 消融变体
+\end{enumerate}
+
+\subsection{主要结果}
+
+\subsubsection{误差-自由度曲线(Error vs.\ DOF)}
+
+\needexp{在 $k=10, 15, 20, 25, 30$ 下,绘制 RL 策略与所有基线的 error vs.\ DOF 曲线。每条曲线 4--6 个细化步。}
+
+\begin{itemize}
+ \item \textbf{预期结果:}RL 策略在所有波数下位于所有基线曲线之下(同等 DOF 误差更小,或同等误差更省计算)
+ \item \textbf{评估指标:}$\ell_2$ 相对误差(vs Mie 解析解或超精细参考解),全局 $\eta_K$ 总和
+ \item \textbf{表格:}列出各方法在不同波数 $k$ 和不同细化步下的 $\ell_2$ 误差与单元数
+\end{itemize}
+
+\subsubsection{跨波数零样本泛化}
+
+\needexp{训练集 $k\in[3,15]$,测试集 $k=20, 25, 30, 35$。绘制 error vs.\ DOF 曲线,对比 RL 策略与 D\"{o}rfler 标记在未见波数下的表现。}
+
+这是区分本文方法与所有传统 AMR 方法的核心实验:
+\begin{itemize}
+ \item D\"{o}rfler 参数 $\theta$ 固定为 0.5(在 $k=15$ 调优)——预期在高 $k$ 下性能退化
+ \item RL 策略不做任何调整——预期在 $k=30$ 下仍保持甚至扩大优势
+ \item 如果 RL 在 $k=30$ 的 error-vs-DOF 仍优于 D\"{o}rfler,直接证明 $k$ 不变特征的有效性
+\end{itemize}
+
+\subsubsection{跨几何泛化}
+
+\needexp{训练全部用圆形散射体。测试:方形介质柱、双圆柱、三圆柱。展示 error vs.\ DOF 曲线和网格快照。}
+
+\subsubsection{跨介质参数泛化}
+
+\needexp{训练集 $\varepsilon_r\in[2,4]$,测试 $\varepsilon_r=6,8$。展示 error vs.\ DOF。}
+
+\subsubsection{网格演化可视化}
+
+\needexp{选取代表性 case($k=20$,方形散射体),展示 RL 策略从初始网格到最终网格的逐步细化快照,与 D\"{o}rfler 标记的对应步快照并列对比。}
+
+预期观察:RL 策略在介质界面和高梯度区域集中细化,在均匀区域保持粗网格;D\"{o}rfler 标记可能在远离界面的区域"浪费"细化预算。
+
+\subsection{消融实验}
+
+\subsubsection{GVN 消融}
+
+\needexp{训练两个模型:完整 RL(含 GVN)vs RL w/o GVN(仅 2 层 message passing)。在 $k=10, 20, 30$ 下对比 error vs.\ DOF。}
+
+\textbf{核心假设:}
+\begin{itemize}
+ \item 低 $k$($k=10$):GVN 和 w/o GVN 表现接近(误差传播范围小,局部信息足够)
+ \item 高 $k$($k=30$):GVN 显著优于 w/o GVN(非局域误差传播范围扩大,需要全局上下文)
+ \item 交互效应:$k$ 越高,GVN 的增益越大——这直接证明 GVN 解决了非局域误差传播问题
+\end{itemize}
+
+\subsubsection{零和奖励消融}
+
+\needexp{RL w/ zero-sum vs RL w/o zero-sum,对比训练曲线和最终 error vs.\ DOF。}
+
+\subsubsection{$k$ 不变特征消融}
+
+\needexp{三组对比:
+(a) 完整 13 维节点特征 + 相位距离边特征
+(b) 移除 cos/sin 相位特征(节点特征 -2 维)
+(c) 相位距离边特征 → 普通欧氏距离边特征}
+测试跨波数泛化性能差异。
+
+\subsubsection{消息传递层数消融}
+
+\needexp{1 层 vs 2 层 vs 3 层 message passing stack,对比训练收敛速度和最终性能。}
+
+\subsection{训练诊断与分析}
+
+以下数据可从前 401 次迭代的训练日志直接提取(\textbf{无需额外实验}):
+
+\begin{itemize}
+ \item \textbf{学习曲线:}loss、explained variance、平均奖励、neg\_action\_ratio 随 iteration 的演化(附 4 合 1 图)
+ \item \textbf{neg\_action\_ratio 分析:}从 0.79(几乎所有单元都想细化)收敛到 0.05(高度选择性),解释策略如何学到"精细化是稀缺资源"
+ \item \textbf{Explained variance 分析:}从 $-0.007$(比随机还差)到 0.48(可靠的回报预测),说明价值网络学到了有意义的误差分布
+ \item \textbf{动作分布统计:}不同训练阶段策略输出 $x_i$ 的分布变化
+ \item \textbf{Mie 解验证:}\needexp{FEM 解 vs Mie 级数解析解在远场的相对 $\ell_2$ 误差,作为 FEM 求解器本身的精度基准}
+\end{itemize}
+
+% ============================================================
+\section{Discussion(讨论)}
+% ============================================================
+
+\subsection{核心发现}
+
+\begin{itemize}
+ \item \textbf{RL 策略学到了超越 D\"{o}rfler 的细化模式:}传统 D\"{o}rfler 标记是单步贪心的——每步独立标记累计误差占比 $\geq \theta$ 的最小集合。RL 策略可以在早期步骤保留预算,在后期步骤集中处理高价值区域,实现跨步优化
+ \item \textbf{GVN 解决了亥姆霍兹非局域性的信息瓶颈:}GVN 消融在高 $k$ 下的显著退化证明了全局上下文对高频波问题的重要性。这为未来将 RL-AMR 应用于其他非局域 PDE(如积分-微分方程、分数阶方程)提供了架构参考
+ \item \textbf{$k$ 不变特征是跨波数泛化的关键:}策略无需在高频下重新训练或调参——这是传统 AMR 方法无法做到的,体现了 ML 方法的核心优势
+ \item \textbf{$\eta_K$ 作为 reward 使方法具有实用性:}不依赖解析解或超精细参考网格,原则上可应用于任意复杂介质分布
+\end{itemize}
+
+\subsection{局限性}
+
+\begin{itemize}
+ \item \textbf{仅限 2D 亥姆霍兹:}拓展到 3D Maxwell 或弹性波方程需要处理更大的图规模(网格节点数 $\propto k^3$),GNN 的计算效率将成为瓶颈
+ \item \textbf{P1 单元的固有色散误差未被修正:}当前方法通过 $h$-refinement 间接补偿 P1 的色散缺陷,而非从变分形式层面消除。在高 $k$ 极限下,细化成本不可持续
+ \item \textbf{训练仍需 PDE 求解器交互:}每步 rollout 需要一次 FEM 求解,训练成本与 PDE 求解开销线性相关。离线预训练或迁移学习可缓解
+ \item \textbf{$\eta_K$ 在预渐近区的可靠性依赖于约束:}当初始网格严重欠分辨时($h \gg \lambda$),$\eta_K$ 的可靠性退化。预渐近约束是一种缓解但非根本解决
+\end{itemize}
+
+\subsection{未来方向}
+
+\subsubsection{双加权残差(DWR):引入因果律}
+
+当前 $\eta_K$ 仅衡量局部残差大小,不区分残差的"重要性"。DWR 理论通过求解伴随问题获得误差的因果权重:
+\begin{equation}
+ J(e) = \sum_{K\in\Omega_h} \Big(\langle r_{\mathrm{int}}, z-z_h\rangle_K + \langle r_{\mathrm{jump}}, z-z_h\rangle_{\partial K}\Big)
+\end{equation}
+将伴随解 $z_h$ 的梯度作为 GNN 的额外节点特征,网络可以直接"看到"哪些局部残差对关心的目标泛函(如远场散射截面)有实质性贡献。这是从"盲目的局部残差驱动"向"因果律驱动的物理感知"的关键一步。
+
+\subsubsection{相空间方法(Wigner 分布):动量解耦}
+
+在含横向动量的复杂散射中,空间域标量残差掩盖了误差的物理本质——污染效应的根源是波矢方向的失配。将波场映射到位置-动量相空间(Wigner 分布),以动量偏差作为奖励信号,智能体优化目标从"缩小数值差异"升级为"逼近真实的物理色散关系"。
+
+\subsubsection{算子层面修正(GLS / Trefftz 方法)}
+
+从变分形式出发,通过 Galerkin Least-Squares (GLS) 稳定化或 Trefftz 基函数(平面波非连续 Galerkin)在 FEM 层面消除色散误差,使 GNN 面对的是干净、局域化的残差场,而非被污染效应扭曲的误差分布。
+
+% ============================================================
+\section{Conclusion(结论)}
+% ============================================================
+
+\begin{itemize}
+ \item \textbf{贡献:}将 RL-AMR 首次拓展到高频亥姆霍兹散射问题,通过 GVN 架构解决非局域误差传播,通过 $k$ 不变特征实现跨波数零样本泛化,通过 $\eta_K$ 奖励信号使方法独立于解析解
+ \item \textbf{关键证据:}[待实验完成后填写:在 $k=30$ 下 RL 策略的 error vs.\ DOF 优于 D\"{o}rfler 标记 XX\%,GVN 在高波数下贡献 YY\%]
+ \item \textbf{影响:}为高频波传播问题的数据驱动网格优化提供了新范式,GVN 架构对非局域 PDE 的 RL-AMR 具有通用参考价值
+ \item \textbf{边界:}当前框架适用于 2D Helmholtz 散射问题,在预渐近约束满足的条件下效果最佳
+\end{itemize}
+
+% ============================================================
+% 附录:实验清单
+% ============================================================
+\clearpage
+\section*{附录 A:待完成实验清单}
+
+以下所有实验需要在投稿前完成。按优先级排列。
+
+\begin{table}[h]
+\centering
+\begin{tabular}{p{0.7cm} p{5cm} p{4cm} p{4cm}}
+\toprule
+优先级 & 实验 & 支撑的创新点 & 预计工作量 \\
+\midrule
+P0 & $k=10,15,20,25,30$ 下 Error vs.\ DOF(5种方法 $\times$ 5波数 $\times$ 4-6步) & C1, C2 & 2--3 天 GPU 计算 \\
+\hline
+P0 & 跨波数泛化:训练 $k\in[3,15]$,测试 $k=20,25,30,35$ & C2(核心卖点)& 1--2 天 GPU \\
+\hline
+P0 & GVN 消融:w/ vs w/o GVN @ $k=10,20,30$ & C1 & 1 天 GPU \\
+\hline
+P1 & 跨几何泛化:方形、多圆柱测试 & C1 的几何稳健性 & 1 天 GPU \\
+\hline
+P1 & 零和奖励消融 & C4 的奖励设计贡献 & 0.5 天 GPU \\
+\hline
+P1 & 网格演化可视化对比(RL vs D\"{o}rfler)& C1 的定性证据 & 0.5 天脚本 \\
+\hline
+P2 & 跨介质 $\varepsilon_r$ 泛化 & 特征设计的稳健性 & 1 天 GPU \\
+\hline
+P2 & $k$ 不变特征消融(去相位特征/换欧氏距离)& C2 的机制解释 & 1 天 GPU \\
+\hline
+P2 & 消息传递层数消融 & 架构设计的合理性 & 0.5 天 GPU \\
+\hline
+P3 & Mie 解定量对比 & FEM 求解器精度基准 & 0.5 天脚本 \\
+\hline
+\end{tabular}
+\end{table}
+
+\vspace{1em}
+\textbf{预计总 GPU 计算时间:}8--12 天(部分可并行)。
+
+\end{document}
diff --git a/result/test_circle.png b/result/test_circle.png
new file mode 100644
index 0000000..3562efc
Binary files /dev/null and b/result/test_circle.png differ
diff --git a/result/test_circle_steps/step00.png b/result/test_circle_steps/step00.png
new file mode 100644
index 0000000..05df0e4
Binary files /dev/null and b/result/test_circle_steps/step00.png differ
diff --git a/result/test_circle_steps/step01.png b/result/test_circle_steps/step01.png
new file mode 100644
index 0000000..463baa7
Binary files /dev/null and b/result/test_circle_steps/step01.png differ
diff --git a/result/test_circle_steps/step02.png b/result/test_circle_steps/step02.png
new file mode 100644
index 0000000..e0b5d69
Binary files /dev/null and b/result/test_circle_steps/step02.png differ
diff --git a/result/test_circle_steps/step03.png b/result/test_circle_steps/step03.png
new file mode 100644
index 0000000..99ba2eb
Binary files /dev/null and b/result/test_circle_steps/step03.png differ
diff --git a/result/test_circle_steps/step04.png b/result/test_circle_steps/step04.png
new file mode 100644
index 0000000..ee43e54
Binary files /dev/null and b/result/test_circle_steps/step04.png differ
diff --git a/result/test_multicircle.png b/result/test_multicircle.png
new file mode 100644
index 0000000..1462627
Binary files /dev/null and b/result/test_multicircle.png differ
diff --git a/result/test_multicircle_steps/step00.png b/result/test_multicircle_steps/step00.png
new file mode 100644
index 0000000..a540b2a
Binary files /dev/null and b/result/test_multicircle_steps/step00.png differ
diff --git a/result/test_multicircle_steps/step01.png b/result/test_multicircle_steps/step01.png
new file mode 100644
index 0000000..dd60bb7
Binary files /dev/null and b/result/test_multicircle_steps/step01.png differ
diff --git a/result/test_multicircle_steps/step02.png b/result/test_multicircle_steps/step02.png
new file mode 100644
index 0000000..767a78e
Binary files /dev/null and b/result/test_multicircle_steps/step02.png differ
diff --git a/result/test_multicircle_steps/step03.png b/result/test_multicircle_steps/step03.png
new file mode 100644
index 0000000..7b7247a
Binary files /dev/null and b/result/test_multicircle_steps/step03.png differ
diff --git a/result/test_multicircle_steps/step04.png b/result/test_multicircle_steps/step04.png
new file mode 100644
index 0000000..ada3a3b
Binary files /dev/null and b/result/test_multicircle_steps/step04.png differ
diff --git a/result/test_square.png b/result/test_square.png
new file mode 100644
index 0000000..c77b94e
Binary files /dev/null and b/result/test_square.png differ
diff --git a/result/test_square_steps/step00.png b/result/test_square_steps/step00.png
new file mode 100644
index 0000000..a02e43a
Binary files /dev/null and b/result/test_square_steps/step00.png differ
diff --git a/result/test_square_steps/step01.png b/result/test_square_steps/step01.png
new file mode 100644
index 0000000..fe17763
Binary files /dev/null and b/result/test_square_steps/step01.png differ
diff --git a/result/test_square_steps/step02.png b/result/test_square_steps/step02.png
new file mode 100644
index 0000000..54296eb
Binary files /dev/null and b/result/test_square_steps/step02.png differ
diff --git a/result/test_square_steps/step03.png b/result/test_square_steps/step03.png
new file mode 100644
index 0000000..c23ce4f
Binary files /dev/null and b/result/test_square_steps/step03.png differ
diff --git a/result/test_square_steps/step04.png b/result/test_square_steps/step04.png
new file mode 100644
index 0000000..11135d5
Binary files /dev/null and b/result/test_square_steps/step04.png differ
diff --git a/result/visualization.png b/result/visualization.png
index a439e0b..c6f4e25 100644
Binary files a/result/visualization.png and b/result/visualization.png differ
diff --git a/result/visualization_steps/step00.png b/result/visualization_steps/step00.png
index 861ef94..e996936 100644
Binary files a/result/visualization_steps/step00.png and b/result/visualization_steps/step00.png differ
diff --git a/result/visualization_steps/step01.png b/result/visualization_steps/step01.png
index 8c3ca72..b964308 100644
Binary files a/result/visualization_steps/step01.png and b/result/visualization_steps/step01.png differ
diff --git a/result/visualization_steps/step02.png b/result/visualization_steps/step02.png
index 81ca912..db1d337 100644
Binary files a/result/visualization_steps/step02.png and b/result/visualization_steps/step02.png differ
diff --git a/result/visualization_steps/step03.png b/result/visualization_steps/step03.png
index 7763c2a..5fe7b30 100644
Binary files a/result/visualization_steps/step03.png and b/result/visualization_steps/step03.png differ
diff --git a/result/visualization_steps/step04.png b/result/visualization_steps/step04.png
index 19a8b06..bee709c 100644
Binary files a/result/visualization_steps/step04.png and b/result/visualization_steps/step04.png differ
diff --git a/src/__pycache__/helmholtz_alt.cpython-310.pyc b/src/__pycache__/helmholtz_alt.cpython-310.pyc
new file mode 100644
index 0000000..3e08244
Binary files /dev/null and b/src/__pycache__/helmholtz_alt.cpython-310.pyc differ
diff --git a/src/__pycache__/main.cpython-313.pyc b/src/__pycache__/main.cpython-313.pyc
index 771668b..6a2ebe2 100644
Binary files a/src/__pycache__/main.cpython-313.pyc and b/src/__pycache__/main.cpython-313.pyc differ
diff --git a/src/__pycache__/network.cpython-310.pyc b/src/__pycache__/network.cpython-310.pyc
index 226e71c..70700f4 100644
Binary files a/src/__pycache__/network.cpython-310.pyc and b/src/__pycache__/network.cpython-310.pyc differ
diff --git a/src/__pycache__/network.cpython-313.pyc b/src/__pycache__/network.cpython-313.pyc
index 7b6363e..40c55e8 100644
Binary files a/src/__pycache__/network.cpython-313.pyc and b/src/__pycache__/network.cpython-313.pyc differ
diff --git a/src/__pycache__/ppo.cpython-310.pyc b/src/__pycache__/ppo.cpython-310.pyc
index 535d699..4586486 100644
Binary files a/src/__pycache__/ppo.cpython-310.pyc and b/src/__pycache__/ppo.cpython-310.pyc differ
diff --git a/src/__pycache__/ppo.cpython-313.pyc b/src/__pycache__/ppo.cpython-313.pyc
index 68b59e6..643338f 100644
Binary files a/src/__pycache__/ppo.cpython-313.pyc and b/src/__pycache__/ppo.cpython-313.pyc differ
diff --git a/src/__pycache__/test_media.cpython-310.pyc b/src/__pycache__/test_media.cpython-310.pyc
new file mode 100644
index 0000000..ded2d15
Binary files /dev/null and b/src/__pycache__/test_media.cpython-310.pyc differ
diff --git a/src/__pycache__/visualize.cpython-310.pyc b/src/__pycache__/visualize.cpython-310.pyc
index 9ef8919..d62bca8 100644
Binary files a/src/__pycache__/visualize.cpython-310.pyc and b/src/__pycache__/visualize.cpython-310.pyc differ
diff --git a/src/__pycache__/visualize.cpython-313.pyc b/src/__pycache__/visualize.cpython-313.pyc
index 523896e..e4ac375 100644
Binary files a/src/__pycache__/visualize.cpython-313.pyc and b/src/__pycache__/visualize.cpython-313.pyc differ
diff --git a/src/config.yaml b/src/config.yaml
index aa462ad..18c0de0 100644
--- a/src/config.yaml
+++ b/src/config.yaml
@@ -8,6 +8,12 @@
# 可视化:
# python src/main.py --mode viz --checkpoint checkpoints/model_iter0400.pt
# python src/main.py --mode viz --checkpoint checkpoints/model_iter0100.pt --k-test 8.0 --center 0.6,0.5 --radius 0.1
+#
+#
+# sbatch方式:
+# 训练
+# sbatch sbatch_train.sh
+#
###########################
algorithm:
@@ -15,8 +21,8 @@ algorithm:
discount_factor: 1.0
ppo:
clip_range: 0.2
- entropy_coefficient: 0.001
- epochs_per_iteration: 5 # 每轮迭代对同一批 rollout 数据重复训练几个 epoch
+ entropy_coefficient: 0.005
+ epochs_per_iteration: 3 # 每轮迭代对同一批 rollout 数据重复训练几个 epoch
gae_lambda: 0.95
initial_log_std: -2.0 # 初始动作 log 标准差,exp(-2)≈0.135
max_grad_norm: 0.5
@@ -34,7 +40,7 @@ environment:
solution_std: true
timestep: true
volume: true
- wave_number: true
+ wave_number: false
x_position: false
y_position: false
dist_to_interface: true
@@ -47,33 +53,33 @@ environment:
boundary:
- 0
- 0
- - 3
- - 3
- initial_num_elements: 75
+ - 1
+ - 1
+ initial_num_elements: 65
helmholtz:
k_ref: 6.0
k_exponent: 2.0
scatterer:
- cx: 1.5
+ cx: 0.5
cx_max: 0.8
cx_min: 0.2
- cy: 1.5
+ cy: 0.5
cy_max: 0.8
cy_min: 0.2
- eps_r: 5.0
+ eps_r: 10.0
eps_r_max: 8.0
eps_r_min: 2.0
mode: random_uniform
- radius: 0.2
+ radius: 0.1
radius_max: 0.2
radius_min: 0.05
wave_number: 30.0
- wave_number_max: 3.0
- wave_number_min: 15.0
+ wave_number_max: 15.0
+ wave_number_min: 3.0
wave_number_mode: random_uniform
num_pdes: 100
pde_type: helmholtz
- pre_asymptotic_N: 1.5
+ pre_asymptotic_N: 2.0
maximum_elements: 50000
num_timesteps: 4
refinement_strategy: continuous_sizing_field
@@ -104,5 +110,5 @@ network:
latent_dimension: 64
training:
learning_rate: 0.0003
- lr_decay: 0.995
+ lr_decay: 1
optimizer: adam
diff --git a/src/helmholtz_alt.py b/src/helmholtz_alt.py
new file mode 100644
index 0000000..52c6d96
--- /dev/null
+++ b/src/helmholtz_alt.py
@@ -0,0 +1,264 @@
+"""Alternative scatterer geometries for Helmholtz FEM problems.
+
+Supports non-circular dielectric scatterers: square, multiple circles, etc.
+Each class overrides only the geometry-dependent methods of HelmholtzProblem.
+"""
+
+from typing import Any, Dict, Union
+
+import numpy as np
+from skfem import Mesh
+
+from environment.helmholtz import (
+ HelmholtzProblem,
+ _compute_residual_indicator,
+)
+
+
+# ═══════════════════════════════════════════════════════════════════
+# Square dielectric scatterer
+# ═══════════════════════════════════════════════════════════════════
+
+class HelmholtzProblemSquare(HelmholtzProblem):
+ """Helmholtz problem with a square dielectric scatterer.
+
+ Extra config keys under helmholtz.scatterer.square:
+ half_side: float — half side length (default 0.2)
+ angle: float — rotation in radians (default 0.0)
+ """
+
+ def __init__(
+ self,
+ *,
+ fem_config: Dict[Union[str, int], Any],
+ random_state: np.random.RandomState = np.random.RandomState(),
+ ):
+ sc = fem_config.get("helmholtz", {}).get("scatterer", {})
+ sq = sc.get("square", {})
+ self._sq_cx = float(sq.get("cx", sc.get("cx", 0.5)))
+ self._sq_cy = float(sq.get("cy", sc.get("cy", 0.5)))
+ self._sq_half = float(sq.get("half_side", sc.get("radius", 0.2)))
+ self._sq_angle = float(sq.get("angle", 0.0))
+ self._sq_eps_r = float(sc.get("eps_r", 2.0))
+
+ super().__init__(fem_config=fem_config, random_state=random_state)
+ self._eps_r = self._sq_eps_r
+
+ # ── geometry helpers ──
+
+ def _rotate_xy(self, x, y):
+ """Rotate coordinates back to scatterer-local frame."""
+ if self._sq_angle == 0:
+ return x - self._sq_cx, y - self._sq_cy
+ c, s = np.cos(-self._sq_angle), np.sin(-self._sq_angle)
+ dx, dy = x - self._sq_cx, y - self._sq_cy
+ return c * dx - s * dy, s * dx + c * dy
+
+ def _in_square(self, x, y):
+ xr, yr = self._rotate_xy(x, y)
+ return (np.abs(xr) <= self._sq_half) & (np.abs(yr) <= self._sq_half)
+
+ # ── FEM assembly (called at quadrature points) ──
+
+ def _eps_r_at_quad_points(self, x, y):
+ return np.where(self._in_square(x, y), self._sq_eps_r, 1.0)
+
+ # ── midpoint eps_r for error estimation / features ──
+
+ def eps_r_at_midpoints(self, mesh: Mesh) -> np.ndarray:
+ pts = np.mean(mesh.p[:, mesh.t], axis=1).T
+ return np.where(self._in_square(pts[:, 0], pts[:, 1]), self._sq_eps_r, 1.0)
+
+ # ── override error estimation ──
+
+ def get_error_estimate_per_element(self, basis, solution):
+ eps_r_arr = self.eps_r_at_midpoints(basis.mesh)
+ return {"indicator": _compute_residual_indicator(
+ basis.mesh, solution, k=self._k, eps_r=eps_r_arr)}
+
+ # ── override features ──
+
+ def element_features(self, mesh, element_feature_names):
+ features_list = []
+ if "epsilon_r" in element_feature_names:
+ features_list.append(self.eps_r_at_midpoints(mesh)[:, None])
+ return np.concatenate(features_list, axis=1) if features_list else None
+
+ # ── Nyquist enforcement uses square bounding box ──
+
+ def _enforce_nyquist_in_dielectric(self, mesh, N=1.5, max_iter=10):
+ lambda_d = 2.0 * np.pi / (self._k * np.sqrt(self._sq_eps_r))
+ h_max = lambda_d / N
+
+ for _ in range(max_iter):
+ i0, i1, i2 = mesh.t[0], mesh.t[1], mesh.t[2]
+ x0, y0 = mesh.p[0, i0], mesh.p[1, i0]
+ x1, y1 = mesh.p[0, i1], mesh.p[1, i1]
+ x2, y2 = mesh.p[0, i2], mesh.p[1, i2]
+
+ e01 = np.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2)
+ e12 = np.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
+ e20 = np.sqrt((x0 - x2) ** 2 + (y0 - y2) ** 2)
+ h_K = np.maximum(np.maximum(e01, e12), e20)
+
+ midpoints = np.mean(mesh.p[:, mesh.t], axis=1).T
+ in_dielectric = self._in_square(midpoints[:, 0], midpoints[:, 1])
+ to_refine = np.where(in_dielectric & (h_K > h_max))[0]
+ if len(to_refine) == 0:
+ break
+ mesh = mesh.refined(to_refine)
+ return mesh
+
+ # ── visualization overlay ──
+
+ def additional_plots_from_mesh(self, mesh: Mesh) -> Dict:
+ corners = np.array([
+ [-self._sq_half, -self._sq_half],
+ [ self._sq_half, -self._sq_half],
+ [ self._sq_half, self._sq_half],
+ [-self._sq_half, self._sq_half],
+ [-self._sq_half, -self._sq_half],
+ ])
+ if self._sq_angle != 0:
+ c, s = np.cos(self._sq_angle), np.sin(self._sq_angle)
+ rot = np.array([[c, -s], [s, c]])
+ corners = corners @ rot.T
+ corners[:, 0] += self._sq_cx
+ corners[:, 1] += self._sq_cy
+ return {"square_outline": (corners[:, 0], corners[:, 1])}
+
+
+# ═══════════════════════════════════════════════════════════════════
+# Multi-circle dielectric scatterer
+# ═══════════════════════════════════════════════════════════════════
+
+class HelmholtzProblemMultiCircle(HelmholtzProblem):
+ """Helmholtz problem with multiple circular dielectric scatterers.
+
+ Extra config key under helmholtz.scatterer:
+ circles: list of dicts, each with cx, cy, radius, eps_r
+ """
+
+ def __init__(
+ self,
+ *,
+ fem_config: Dict[Union[str, int], Any],
+ random_state: np.random.RandomState = np.random.RandomState(),
+ ):
+ sc = fem_config.get("helmholtz", {}).get("scatterer", {})
+ circles_cfg = sc.get("circles", None)
+ if circles_cfg is None:
+ circles_cfg = [{
+ "cx": sc.get("cx", 0.35), "cy": sc.get("cy", 0.35),
+ "radius": sc.get("radius", 0.12), "eps_r": sc.get("eps_r", 3.0),
+ }, {
+ "cx": sc.get("cx", 0.65) if "cx2" not in sc else sc["cx2"], "cy": sc.get("cy", 0.65) if "cy2" not in sc else sc["cy2"],
+ "radius": sc.get("radius", 0.12), "eps_r": sc.get("eps_r", 3.0),
+ }]
+
+ self._circles = []
+ for c in circles_cfg:
+ self._circles.append({
+ "cx": float(c["cx"]),
+ "cy": float(c["cy"]),
+ "radius": float(c["radius"]),
+ "eps_r": float(c.get("eps_r", 2.0)),
+ })
+
+ super().__init__(fem_config=fem_config, random_state=random_state)
+ sc_primary = self._circles[0]
+ self._eps_r = sc_primary["eps_r"]
+ self._cx = sc_primary["cx"]
+ self._cy = sc_primary["cy"]
+ self._radius = sc_primary["radius"]
+
+ # ── geometry ──
+
+ def _eps_r_at_point(self, x, y):
+ """Return eps_r at arbitrary points (broadcast-safe)."""
+ out = np.ones_like(x, dtype=float)
+ for c in self._circles:
+ in_c = (x - c["cx"]) ** 2 + (y - c["cy"]) ** 2 <= c["radius"] ** 2
+ out = np.where(in_c, c["eps_r"], out)
+ return out
+
+ # ── FEM assembly ──
+
+ def _eps_r_at_quad_points(self, x, y):
+ return self._eps_r_at_point(x, y)
+
+ # ── midpoint eps_r ──
+
+ def eps_r_at_midpoints(self, mesh: Mesh) -> np.ndarray:
+ pts = np.mean(mesh.p[:, mesh.t], axis=1).T
+ return self._eps_r_at_point(pts[:, 0], pts[:, 1])
+
+ # ── error estimation ──
+
+ def get_error_estimate_per_element(self, basis, solution):
+ eps_r_arr = self.eps_r_at_midpoints(basis.mesh)
+ return {"indicator": _compute_residual_indicator(
+ basis.mesh, solution, k=self._k, eps_r=eps_r_arr)}
+
+ # ── features ──
+
+ def element_features(self, mesh, element_feature_names):
+ features_list = []
+ if "epsilon_r" in element_feature_names:
+ features_list.append(self.eps_r_at_midpoints(mesh)[:, None])
+ return np.concatenate(features_list, axis=1) if features_list else None
+
+ # ── Nyquist enforcement for all circles ──
+
+ def _enforce_nyquist_in_dielectric(self, mesh, N=1.5, max_iter=15):
+ for _ in range(max_iter):
+ i0, i1, i2 = mesh.t[0], mesh.t[1], mesh.t[2]
+ x0, y0 = mesh.p[0, i0], mesh.p[1, i0]
+ x1, y1 = mesh.p[0, i1], mesh.p[1, i1]
+ x2, y2 = mesh.p[0, i2], mesh.p[1, i2]
+
+ e01 = np.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2)
+ e12 = np.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
+ e20 = np.sqrt((x0 - x2) ** 2 + (y0 - y2) ** 2)
+ h_K = np.maximum(np.maximum(e01, e12), e20)
+
+ midpoints = np.mean(mesh.p[:, mesh.t], axis=1).T
+ eps_r_at_mid = self._eps_r_at_point(midpoints[:, 0], midpoints[:, 1])
+ lambda_local = 2.0 * np.pi / (self._k * np.sqrt(np.maximum(eps_r_at_mid, 1.0)))
+ h_max = lambda_local / N
+
+ to_refine = np.where((eps_r_at_mid > 1.0) & (h_K > h_max))[0]
+ if len(to_refine) == 0:
+ break
+ mesh = mesh.refined(to_refine)
+ return mesh
+
+ # ── visualization overlay ──
+
+ def additional_plots_from_mesh(self, mesh: Mesh) -> Dict:
+ result = {}
+ for i, c in enumerate(self._circles):
+ theta = np.linspace(0, 2 * np.pi, 128)
+ result[f"circle_{i}"] = (
+ c["cx"] + c["radius"] * np.cos(theta),
+ c["cy"] + c["radius"] * np.sin(theta),
+ )
+ return result
+
+
+# ═══════════════════════════════════════════════════════════════════
+# Factory functions (mirror create_helmholtz_problem)
+# ═══════════════════════════════════════════════════════════════════
+
+def create_helmholtz_problem_square(
+ *, fem_config: Dict[Union[str, int], Any],
+ random_state: np.random.RandomState = np.random.RandomState(),
+) -> HelmholtzProblemSquare:
+ return HelmholtzProblemSquare(fem_config=fem_config, random_state=random_state)
+
+
+def create_helmholtz_problem_multi_circle(
+ *, fem_config: Dict[Union[str, int], Any],
+ random_state: np.random.RandomState = np.random.RandomState(),
+) -> HelmholtzProblemMultiCircle:
+ return HelmholtzProblemMultiCircle(fem_config=fem_config, random_state=random_state)
diff --git a/src/main.py b/src/main.py
index 3e37230..02b5921 100644
--- a/src/main.py
+++ b/src/main.py
@@ -49,6 +49,8 @@ def train(config: dict, iterations: int, checkpoint_dir: str = "checkpoints", sa
f"agents={metrics['num_agents']:.0f} avg_r={metrics['avg_reward']:.4f} sum_r={metrics['sum_reward']:.2f} "
f"x<0={metrics.get('neg_action_ratio', 0):.2f} "
f"elig={metrics.get('eligible_ratio', 0):.2f} "
+ f"dorfler_tail={metrics.get('dorfler_tail_ratio', 0):.2f} "
+ f"floor={metrics.get('dorfler_floor_active', 0):.0f} "
f"sel={metrics.get('selected_count', 0):.0f} "
f"{time.time() - t1:.1f}s"
)
@@ -60,7 +62,7 @@ def train(config: dict, iterations: int, checkpoint_dir: str = "checkpoints", sa
def _eval_mie_error_test(env) -> float:
- """Compute relative L2 error of FEM vs Mie analytical solution."""
+ """Compute relative L2 error of FEM vs Mie analytical solution (vertex-level)."""
fp = getattr(env.fem_problem, "fem_problem", None)
if fp is None:
return float("nan")
@@ -83,6 +85,60 @@ def _eval_mie_error_test(env) -> float:
return float(np.linalg.norm(diff) / denom)
+def _eval_mie_error_area_weighted(env):
+ """Compute area-weighted relative error FEM vs Mie (triangle-level quadrature).
+
+ Returns dict with keys:
+ rel_err — area-weighted relative error (0–1)
+ w_rmse — area-weighted RMSE
+ max_err — max pointwise absolute error (L∞)
+ """
+ fp = getattr(env.fem_problem, "fem_problem", None)
+ if fp is None:
+ return {"rel_err": float("nan"), "w_rmse": float("nan"), "max_err": float("nan")}
+ _eps_r = getattr(fp, "_eps_r", None)
+ _radius = getattr(fp, "_radius", None)
+ _cx = getattr(fp, "_cx", None)
+ _cy = getattr(fp, "_cy", None)
+ _k = getattr(fp, "_k", None)
+ if any(v is None for v in [_eps_r, _radius, _cx, _cy, _k]):
+ return {"rel_err": float("nan"), "w_rmse": float("nan"), "max_err": float("nan")}
+
+ from environment.mie_solution import mie_scattered_field
+
+ mesh = env.mesh
+ pts = mesh.p.T # (num_vertices, 2)
+ tri = mesh.t.T # (num_triangles, 3) — vertex indices
+
+ u_mie = mie_scattered_field(pts, k0=_k, eps_r=_eps_r, radius=_radius, cx=_cx, cy=_cy)
+ u_fem = env.scalar_solution
+
+ err_abs = np.abs(u_fem - u_mie)
+ ref_abs = np.abs(u_mie)
+
+ v1, v2, v3 = pts[tri[:, 0]], pts[tri[:, 1]], pts[tri[:, 2]]
+ tri_areas = 0.5 * np.abs(
+ (v2[:, 0] - v1[:, 0]) * (v3[:, 1] - v1[:, 1])
+ - (v3[:, 0] - v1[:, 0]) * (v2[:, 1] - v1[:, 1])
+ )
+
+ err_tri_sq = (err_abs[tri[:, 0]] ** 2
+ + err_abs[tri[:, 1]] ** 2
+ + err_abs[tri[:, 2]] ** 2) / 3.0
+ ref_tri_sq = (ref_abs[tri[:, 0]] ** 2
+ + ref_abs[tri[:, 1]] ** 2
+ + ref_abs[tri[:, 2]] ** 2) / 3.0
+
+ total_area = np.sum(tri_areas)
+ w_rmse = np.sqrt(np.sum(err_tri_sq * tri_areas) / total_area)
+
+ ref_total = np.sum(ref_tri_sq * tri_areas)
+ rel_err = np.sqrt(np.sum(err_tri_sq * tri_areas) / ref_total) if ref_total > 1e-12 else float("nan")
+
+ return {"rel_err": float(rel_err), "w_rmse": float(w_rmse),
+ "max_err": float(np.max(err_abs))}
+
+
def test(config: dict, checkpoint_path: str, k_test=None, center=None, radius=None, eps_test=None):
setup_helmholtz_config(config, k_test=k_test, center=center, radius=radius, eps_test=eps_test)
algo = config.get("algorithm", {})
@@ -102,8 +158,11 @@ def test(config: dict, checkpoint_path: str, k_test=None, center=None, radius=No
step = 0
n_elem_init = getattr(env, "_num_elements", env.num_agents)
mie_err_0 = _eval_mie_error_test(env)
- print(f" Step {step:2d}: reward=--- mie_err={mie_err_0:.4f} elements={n_elem_init}"
- f" budget={getattr(env, '_n_budget', '?')}")
+ aw_0 = _eval_mie_error_area_weighted(env)
+ print(f" Step {step:2d}: reward=--- mie_err={mie_err_0:.4f} "
+ f"aw_rel={aw_0['rel_err']*100:.2f}% aw_rmse={aw_0['w_rmse']:.4f} "
+ f"max_err={aw_0['max_err']:.4f} elements={n_elem_init} "
+ f"budget={getattr(env, '_n_budget', '?')}")
total_reward = 0.0
while not done:
@@ -113,12 +172,29 @@ def test(config: dict, checkpoint_path: str, k_test=None, center=None, radius=No
step_r = float(np.sum(reward))
total_reward += step_r
step += 1
- mie_err = _eval_mie_error_test(env)
- print(f" Step {step:2d}: reward={step_r:+.4f} mie_err={mie_err:.4f}"
- f" elements={info.get('num_elements', '?')} "
- f"x<0={info.get('neg_action_ratio', 0):.2f} sel={info.get('selected_count', 0)}")
- print(f"\n[Test] total_reward={total_reward:.4f} final_mie_error={mie_err:.4f}")
+ # timing
+ _timing = env.fem_problem.last_solve_timing
+ _t_str = ""
+ if _timing is not None:
+ _t_str = (f" [timing] K={_timing['assemble_K']*1e3:.1f}ms"
+ f" f={_timing['assemble_f']*1e3:.1f}ms"
+ f" bnd={_timing['assemble_boundary']*1e3:.1f}ms"
+ f" solve={_timing['solve']*1e3:.1f}ms"
+ f" total={_timing['total']*1e3:.1f}ms"
+ f" n_dof={_timing['n_dof']}")
+
+ mie_err = _eval_mie_error_test(env)
+ aw = _eval_mie_error_area_weighted(env)
+ print(f" Step {step:2d}: reward={step_r:+.4f} mie_err={mie_err:.4f} "
+ f"aw_rel={aw['rel_err']*100:.2f}% aw_rmse={aw['w_rmse']:.4f} "
+ f"max_err={aw['max_err']:.4f} "
+ f"elements={info.get('num_elements', '?')} "
+ f"x<0={info.get('neg_action_ratio', 0):.2f} sel={info.get('selected_count', 0)}"
+ f"{_t_str}")
+
+ print(f"\n[Test] total_reward={total_reward:.4f} final_mie_error={mie_err:.4f}"
+ f" final_aw_rel={aw['rel_err']*100:.2f}%")
def main():
diff --git a/src/network.py b/src/network.py
index e05a186..e675594 100644
--- a/src/network.py
+++ b/src/network.py
@@ -154,10 +154,55 @@ class MessagePassingStep(nn.Module):
# ──
-# 6. MessagePassingStack — 堆叠 N 个 Step
+# 6. GlobalVirtualNode — 注意力门控全局广播
+# ──
+class GlobalVirtualNode(nn.Module):
+ """
+ Global Virtual Node (GVN) with attention-gated broadcast.
+
+ Stage A: h_V = mean(h_v) — global pooling (≈ Lippmann-Schwinger integral)
+ Stage B: α_v = sigmoid(W_att[h_v || h_V] + b_att) — per-node attention gate
+ h_v ← h_v + α_v ⊙ (W_V · h_V) — gated broadcast
+
+ Breaks the O(diameter) information bottleneck of local message passing
+ in O(1), injecting global error distribution and coherent background
+ field context into every local node.
+ """
+
+ def __init__(self, latent_dim: int):
+ super().__init__()
+ self.gate = nn.Sequential(
+ nn.Linear(2 * latent_dim, latent_dim),
+ nn.LeakyReLU(),
+ nn.Linear(latent_dim, latent_dim),
+ )
+ self.value_proj = nn.Linear(latent_dim, latent_dim)
+ # Learnable scale initialized small — prevents the GVN broadcast
+ # from homogenizing node features before the local MP signal is learned.
+ self.scale = nn.Parameter(torch.tensor(0.1))
+
+ def forward(self, graph: Data):
+ # Stage A: η_K-weighted global pooling
+ # High-error regions dominate the virtual node; free-space background is
+ # naturally suppressed. Falls back to mean if no η available.
+ if hasattr(graph, 'eta') and graph.eta is not None:
+ w = graph.eta / (graph.eta.sum() + 1e-8) # [N], Σw = 1
+ h_V = (graph.x * w.unsqueeze(-1)).sum(dim=0, keepdim=True) # [1, D]
+ else:
+ h_V = graph.x.mean(dim=0, keepdim=True) # [1, D]
+
+ # Stage B: attention-gated broadcast
+ h_V_exp = h_V.expand(graph.x.shape[0], -1) # [N, D]
+ gate_in = torch.cat([graph.x, h_V_exp], dim=-1) # [N, 2D]
+ alpha = torch.sigmoid(self.gate(gate_in)) # [N, D]
+ graph.x = graph.x + self.scale * alpha * self.value_proj(h_V_exp)
+
+
+# ──
+# 7. MessagePassingStack — 堆叠 N 个 Step + GVN
# ──
class MessagePassingStack(nn.Module):
- """Stack of multiple MessagePassingSteps with optional step repeats."""
+ """Stack of MessagePassingSteps followed by a Global Virtual Node."""
def __init__(self, latent_dim: int, stack_config: dict, scatter_reducer):
super().__init__()
@@ -169,11 +214,13 @@ class MessagePassingStack(nn.Module):
for _ in range(num_steps)
]
)
+ self.gvn = GlobalVirtualNode(latent_dim)
def forward(self, graph: Data):
for step in self.steps:
for _ in range(self.num_step_repeats):
step(graph)
+ self.gvn(graph)
# ──
diff --git a/src/ppo.py b/src/ppo.py
index bd1d2c4..ba08f08 100644
--- a/src/ppo.py
+++ b/src/ppo.py
@@ -186,7 +186,8 @@ class PPOTrainer:
_rho_keys = ("rho_int_mean", "rho_jump_mean", "rho_sbc_mean",
"w_rho_int", "w_rho_jump", "w_rho_sbc")
rho_accum = {k: 0.0 for k in _rho_keys}
- diag_keys = ("neg_action_ratio", "eligible_ratio", "selected_count")
+ diag_keys = ("neg_action_ratio", "eligible_ratio", "selected_count",
+ "dorfler_tail_ratio", "dorfler_floor_active")
diag_accum = {k: 0.0 for k in diag_keys}
diag_steps = 0
@@ -257,7 +258,7 @@ class PPOTrainer:
torch.nn.utils.clip_grad_norm_(self.policy.parameters(), self.max_grad_norm)
self.policy.optimizer.step()
if self.policy.log_std is not None:
- self.policy.log_std.data.clamp_(-4.0, -1.0)
+ self.policy.log_std.data.clamp_(-3.0, -1.0) # σ ∈ [0.05, 0.37]
total_losses.append(loss.item())
if self.policy.lr_scheduler is not None:
diff --git a/src/test_config.yaml b/src/test_config.yaml
new file mode 100644
index 0000000..ae32b0b
--- /dev/null
+++ b/src/test_config.yaml
@@ -0,0 +1,53 @@
+# Test configuration for test_media.py
+# Usage: python src/test_media.py (uses this file by default)
+# python src/test_media.py --k-test 8.0 (CLI overrides)
+# python src/test_media.py --config my_test.yaml (use a different config)
+
+# Path to base config (model/network/algo params)
+base_config: src/config.yaml
+
+# ── Test scenario ──
+test:
+ geometry: square # square | multi_circle | circle
+ checkpoint: checkpoints/model_final.pt
+ output: result/test_square.png
+ seed: 99
+
+# ── Wave number ──
+k_test: 18.0
+
+# ── Scatterer parameters ──
+# Used based on test.geometry. Comment/uncomment as needed.
+scatterer:
+ eps_r: 3.0
+
+ # Shared position
+ cx: 0.5
+ cy: 0.5
+
+ # Circle
+ radius: 0.15
+
+ # Square
+ half_side: 0.15
+ angle: 0.0
+
+ # Multi-circle (overrides cx/cy/radius above when geometry=multi_circle)
+ circles:
+ - cx: 0.35
+ cy: 0.5
+ radius: 0.12
+ eps_r: 3.0
+ - cx: 0.65
+ cy: 0.5
+ radius: 0.12
+ eps_r: 3.0
+
+# ── Reference computation ──
+# n_refine_vertex: uniform refinement levels for per-vertex error
+# n_refine_grid: uniform refinement levels for the 2D heatmap
+# grid_resolution: N x N grid points for the heatmap
+reference:
+ n_refine_vertex: 2
+ n_refine_grid: 3
+ grid_resolution: 200
diff --git a/src/test_media.py b/src/test_media.py
new file mode 100644
index 0000000..66894bc
--- /dev/null
+++ b/src/test_media.py
@@ -0,0 +1,609 @@
+#!/usr/bin/env python3
+"""Test a trained AFEM model on alternative scatterer geometries.
+
+Supports: square, multi-circle, and the original circle.
+
+Usage:
+ python src/test_media.py # uses src/test_config.yaml
+ python src/test_media.py --k-test 30.0 --geometry circle
+ python src/test_media.py --config my_test.yaml # custom config
+
+All test parameters live in the YAML config. CLI args serve as overrides.
+"""
+
+import argparse
+import copy
+import os
+import sys
+import time
+from pathlib import Path
+from typing import Optional
+
+import numpy as np
+import torch
+from torch_geometric.data import Batch
+
+_project_root = Path(__file__).resolve().parent.parent
+if str(_project_root) not in sys.path:
+ sys.path.insert(0, str(_project_root))
+
+from src.network import create_model
+from src.utils import load_checkpoint, load_config, setup_helmholtz_config
+from src.helmholtz_alt import (
+ HelmholtzProblemSquare,
+ HelmholtzProblemMultiCircle,
+ create_helmholtz_problem_square,
+ create_helmholtz_problem_multi_circle,
+)
+
+
+# ═══════════════════════════════════════════════════════════════════════
+# Geometry factory mapping
+# ═══════════════════════════════════════════════════════════════════════
+
+_GEOMETRY_FACTORIES = {
+ "square": create_helmholtz_problem_square,
+ "multi_circle": create_helmholtz_problem_multi_circle,
+ "circle": None, # default HelmholtzProblem
+}
+
+
+# ═══════════════════════════════════════════════════════════════════════
+# Epsilon_r property patching
+# ═══════════════════════════════════════════════════════════════════════
+
+def _patch_epsilon_r(env):
+ inner_fp = env.fem_problem.fem_problem
+ if hasattr(inner_fp, "eps_r_at_midpoints"):
+ def _eps_r(self):
+ return inner_fp.eps_r_at_midpoints(self.mesh)
+ type(env)._epsilon_r_elements = property(_eps_r)
+
+
+# ═══════════════════════════════════════════════════════════════════════
+# Fine FEM reference (computed once, interpolated later)
+# ═══════════════════════════════════════════════════════════════════════
+
+def _compute_fine_fem_reference(env, n_refine: int = 2):
+ """Compute fine-FEM reference on initial mesh + n_refine uniform refinement."""
+ from skfem import Basis, ElementTriP1
+
+ fp = env.fem_problem.fem_problem
+ ref_mesh = copy.deepcopy(env.mesh)
+ for _ in range(n_refine):
+ ref_mesh = ref_mesh.refined(np.arange(ref_mesh.t.shape[1]))
+ ref_basis = Basis(ref_mesh, ElementTriP1())
+ ref_sol = fp.calculate_solution(ref_basis, cache=False)
+
+ # Interpolate to coarse mesh vertices
+ pts = env.mesh.p.T
+ finder = ref_mesh.element_finder()
+ cells = finder(*pts.T)
+ cells = np.clip(cells, 0, ref_mesh.t.shape[1] - 1)
+
+ i0, i1, i2 = ref_mesh.t[0, cells], ref_mesh.t[1, cells], ref_mesh.t[2, cells]
+ p = ref_mesh.p
+ x, y = pts[:, 0], pts[:, 1]
+ x0, y0 = p[0, i0], p[1, i0]
+ x1, y1 = p[0, i1], p[1, i1]
+ x2, y2 = p[0, i2], p[1, i2]
+ denom = (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0)
+ denom = np.where(np.abs(denom) < 1e-15, 1.0, denom)
+ w0 = ((x1 - x) * (y2 - y) - (x2 - x) * (y1 - y)) / denom
+ w1 = ((x2 - x) * (y0 - y) - (x0 - x) * (y2 - y)) / denom
+ w2 = 1.0 - w0 - w1
+ u_ref_on_coarse = w0 * ref_sol[i0] + w1 * ref_sol[i1] + w2 * ref_sol[i2]
+ return u_ref_on_coarse, ref_mesh, ref_sol
+
+
+def _interpolate_ref_to_mesh(target_pts, ref_mesh, ref_sol):
+ """Interpolate cached reference solution to arbitrary mesh vertices."""
+ finder = ref_mesh.element_finder()
+ cells = finder(*target_pts.T)
+ cells = np.clip(cells, 0, ref_mesh.t.shape[1] - 1)
+
+ i0, i1, i2 = ref_mesh.t[0, cells], ref_mesh.t[1, cells], ref_mesh.t[2, cells]
+ p = ref_mesh.p
+ x, y = target_pts[:, 0], target_pts[:, 1]
+ x0, y0 = p[0, i0], p[1, i0]
+ x1, y1 = p[0, i1], p[1, i1]
+ x2, y2 = p[0, i2], p[1, i2]
+ denom = (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0)
+ denom = np.where(np.abs(denom) < 1e-15, 1.0, denom)
+ w0 = ((x1 - x) * (y2 - y) - (x2 - x) * (y1 - y)) / denom
+ w1 = ((x2 - x) * (y0 - y) - (x0 - x) * (y2 - y)) / denom
+ w2 = 1.0 - w0 - w1
+ return w0 * ref_sol[i0] + w1 * ref_sol[i1] + w2 * ref_sol[i2]
+
+
+def _compute_ref_grid(env, n_refine: int = 3, resolution: int = 200):
+ """Compute fine reference on a regular grid for smooth heatmaps."""
+ from skfem import Basis, ElementTriP1
+
+ fp = env.fem_problem.fem_problem
+ ref_mesh = copy.deepcopy(env.mesh)
+ for _ in range(n_refine):
+ ref_mesh = ref_mesh.refined(np.arange(ref_mesh.t.shape[1]))
+ ref_basis = Basis(ref_mesh, ElementTriP1())
+ ref_sol = fp.calculate_solution(ref_basis, cache=False)
+
+ boundary = fp._domain._boundary
+ x_vec = np.linspace(boundary[0], boundary[2], resolution)
+ y_vec = np.linspace(boundary[1], boundary[3], resolution)
+ X, Y = np.meshgrid(x_vec, y_vec)
+ grid_pts = np.column_stack([X.ravel(), Y.ravel()])
+
+ U_grid = np.zeros(len(grid_pts), dtype=np.complex128)
+ batch_size = 4096
+ for start in range(0, len(grid_pts), batch_size):
+ end = min(start + batch_size, len(grid_pts))
+ batch = grid_pts[start:end]
+ finder = ref_mesh.element_finder()
+ cells = finder(*batch.T)
+ cells = np.clip(cells, 0, ref_mesh.t.shape[1] - 1)
+
+ i0, i1, i2 = ref_mesh.t[0, cells], ref_mesh.t[1, cells], ref_mesh.t[2, cells]
+ p = ref_mesh.p
+ x, y = batch[:, 0], batch[:, 1]
+ x0, y0 = p[0, i0], p[1, i0]
+ x1, y1 = p[0, i1], p[1, i1]
+ x2, y2 = p[0, i2], p[1, i2]
+ denom = (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0)
+ denom = np.where(np.abs(denom) < 1e-15, 1.0, denom)
+ w0 = ((x1 - x) * (y2 - y) - (x2 - x) * (y1 - y)) / denom
+ w1 = ((x2 - x) * (y0 - y) - (x0 - x) * (y2 - y)) / denom
+ w2 = 1.0 - w0 - w1
+ U_grid[start:end] = w0 * ref_sol[i0] + w1 * ref_sol[i1] + w2 * ref_sol[i2]
+
+ return {"X": X, "Y": Y, "E_scat": U_grid.reshape(resolution, resolution)}
+
+
+def _compute_step_error(scalar, u_ref) -> float:
+ if u_ref is None:
+ return float("nan")
+ diff = np.abs(scalar - u_ref)
+ denom = np.linalg.norm(np.abs(u_ref))
+ if denom < 1e-12:
+ denom = 1.0
+ return float(np.linalg.norm(diff) / denom)
+
+
+# ═══════════════════════════════════════════════════════════════════════
+# Visualization
+# ═══════════════════════════════════════════════════════════════════════
+
+def _render_field(ax, triang, values, title, vmin, vmax, show_mesh=True):
+ tcf = ax.tripcolor(triang, values, shading="gouraud", cmap="jet",
+ vmin=vmin, vmax=vmax)
+ if show_mesh and triang is not None:
+ n = triang.triangles.shape[0]
+ ax.triplot(triang, lw=(0.5 if n < 500 else 0.3), color="black",
+ alpha=(0.7 if n < 2000 else 0.5))
+ ax.set_aspect("equal")
+ ax.set_title(title, fontsize=9)
+ ax.set_xticks([])
+ ax.set_yticks([])
+ return tcf
+
+
+def _draw_scatterer(ax, geometry: str, env):
+ fp = env.fem_problem.fem_problem
+ if geometry == "square":
+ sq = getattr(fp, "_sq_cx", 0.5), getattr(fp, "_sq_cy", 0.5)
+ hs = getattr(fp, "_sq_half", 0.2)
+ ang = getattr(fp, "_sq_angle", 0.0)
+ corners = np.array([
+ [-hs, -hs], [hs, -hs], [hs, hs], [-hs, hs], [-hs, -hs]
+ ])
+ if ang != 0:
+ c, s = np.cos(ang), np.sin(ang)
+ corners = corners @ np.array([[c, -s], [s, c]]).T
+ corners[:, 0] += sq[0]
+ corners[:, 1] += sq[1]
+ ax.plot(corners[:, 0], corners[:, 1], color="cyan", linewidth=1.5,
+ linestyle="--")
+ elif geometry == "multi_circle":
+ circles = getattr(fp, "_circles", [])
+ for c in circles:
+ theta = np.linspace(0, 2 * np.pi, 128)
+ ax.plot(c["cx"] + c["radius"] * np.cos(theta),
+ c["cy"] + c["radius"] * np.sin(theta),
+ color="cyan", linewidth=1.5, linestyle="--")
+ elif geometry == "circle":
+ cx = getattr(fp, "_cx", 0.5)
+ cy = getattr(fp, "_cy", 0.5)
+ r = getattr(fp, "_radius", 0.2)
+ theta = np.linspace(0, 2 * np.pi, 128)
+ ax.plot(cx + r * np.cos(theta), cy + r * np.sin(theta),
+ color="cyan", linewidth=1.5, linestyle="--")
+
+
+def _save_pngs(steps, stem, checkpoint_path, k, geometry, env, ref_grid):
+ import matplotlib
+ matplotlib.use("Agg")
+ import matplotlib.pyplot as plt
+ import matplotlib.tri as tri
+
+ per_step_dir = f"{stem}_steps"
+ os.makedirs(os.path.dirname(stem) or ".", exist_ok=True)
+ os.makedirs(per_step_dir, exist_ok=True)
+
+ # ── Overview grid ──
+ n = len(steps)
+ ncols = min(n, 4)
+ nrows = (n + ncols - 1) // ncols
+ fig, axes = plt.subplots(nrows, ncols, figsize=(4 * ncols, 3.5 * nrows))
+ axes_flat = np.array([axes]) if nrows * ncols == 1 else np.array(axes).flatten()
+
+ for i, step_data in enumerate(steps):
+ mesh, scalar, err_val, n_elem = step_data[:4]
+ pts = mesh.p.T
+ tg = tri.Triangulation(pts[:, 0], pts[:, 1], mesh.t.T)
+ s = np.abs(scalar) if np.iscomplexobj(scalar) else scalar
+ vmin, vmax = s.min(), s.max()
+ if vmax - vmin < 1e-12:
+ vmin, vmax = vmin - 0.5, vmax + 0.5
+ tcf = _render_field(axes_flat[i], tg, s,
+ f"Step {i}: {n_elem} elem, err={err_val:.4f}",
+ vmin, vmax)
+ fig.colorbar(tcf, ax=axes_flat[i], fraction=0.046, pad=0.04)
+ _draw_scatterer(axes_flat[i], geometry, env)
+
+ for j in range(n, len(axes_flat)):
+ axes_flat[j].set_visible(False)
+
+ fig.subplots_adjust(left=0.04, right=0.90, top=0.90, bottom=0.06,
+ wspace=0.15, hspace=0.30)
+ geo_label = {"square": "Square", "multi_circle": "Multi-Circle",
+ "circle": "Circle"}.get(geometry, geometry)
+ fig.suptitle(
+ f"Helmholtz |E_scat| [{geo_label}] — {os.path.basename(checkpoint_path)}\n"
+ f"k={k:.1f} eps_r info in scatterer overlay",
+ fontsize=12,
+ )
+ fig.savefig(f"{stem}.png", dpi=200, bbox_inches="tight")
+ plt.close(fig)
+ print(f"[Viz] Overview → {stem}.png")
+
+ # ── Per-step panels (FEM + Reference + Error) ──
+ for i, step_data in enumerate(steps):
+ mesh, scalar, err_val, n_elem = step_data[:4]
+ u_ref_at_verts = step_data[4] if len(step_data) > 4 else None
+
+ pts = mesh.p.T
+ tg = tri.Triangulation(pts[:, 0], pts[:, 1], mesh.t.T)
+ coarse_val = np.abs(scalar) if np.iscomplexobj(scalar) else scalar
+
+ fig2, axes2 = plt.subplots(1, 3, figsize=(18, 6))
+ axes2 = list(np.atleast_1d(axes2))
+
+ # Panel 1: FEM
+ cvmin, cvmax = coarse_val.min(), coarse_val.max()
+ if cvmax - cvmin < 1e-12:
+ cvmin, cvmax = cvmin - 0.5, cvmax + 0.5
+ tcf1 = _render_field(axes2[0], tg, coarse_val,
+ f"Step {i}: FEM |E_scat| ({n_elem} elem)",
+ cvmin, cvmax)
+ _draw_scatterer(axes2[0], geometry, env)
+ fig2.colorbar(tcf1, ax=axes2[0], fraction=0.046, pad=0.04)
+
+ # Panel 2: Fine FEM reference on grid
+ if ref_grid is not None:
+ g = ref_grid
+ gm = np.abs(g["E_scat"])
+ mvmin, mvmax = gm.min(), gm.max()
+ if mvmax - mvmin < 1e-12:
+ mvmin, mvmax = mvmin - 0.5, mvmax + 0.5
+ im2 = axes2[1].pcolormesh(g["X"], g["Y"], gm,
+ shading="gouraud", cmap="jet",
+ vmin=mvmin, vmax=mvmax)
+ axes2[1].set_title("Fine FEM Ref |E_scat|", fontsize=9)
+ axes2[1].set_aspect("equal")
+ axes2[1].set_xticks([])
+ axes2[1].set_yticks([])
+ _draw_scatterer(axes2[1], geometry, env)
+ fig2.colorbar(im2, ax=axes2[1], fraction=0.046, pad=0.04)
+
+ # Panel 3: Pointwise error
+ if u_ref_at_verts is not None:
+ u_fem_abs = np.abs(scalar)
+ u_ref_abs = np.abs(u_ref_at_verts)
+ error_abs = np.abs(u_fem_abs - u_ref_abs)
+ evmin, evmax = 0.0, error_abs.max() or 1.0
+ if evmax - evmin < 1e-12:
+ evmax = evmin + 1.0
+ tcf3 = _render_field(axes2[2], tg, error_abs,
+ f"||FEM|−|Ref|| L2={err_val:.4f}",
+ evmin, evmax)
+ _draw_scatterer(axes2[2], geometry, env)
+ fig2.colorbar(tcf3, ax=axes2[2], fraction=0.046, pad=0.04)
+
+ fig2.tight_layout()
+ fig2.savefig(f"{per_step_dir}/step{i:02d}.png", dpi=150,
+ bbox_inches="tight")
+ plt.close(fig2)
+
+ print(f"[Viz] Per-step PNGs → {per_step_dir}/ ({n} files)")
+
+
+# ═══════════════════════════════════════════════════════════════════════
+# Scatterer config injection
+# ═══════════════════════════════════════════════════════════════════════
+
+def _inject_scatterer_config(base_config: dict, geometry: str, sc_cfg: dict, k_test: float):
+ """Inject scatterer params from test config into the base config's helmholtz section.
+
+ Returns (config, factory) where factory is the geometry-specific create function.
+ """
+ hc = (base_config.setdefault("environment", {})
+ .setdefault("mesh_refinement", {})
+ .setdefault("fem", {})
+ .setdefault("helmholtz", {}))
+
+ sc = hc.setdefault("scatterer", {})
+ sc["mode"] = "fixed"
+ sc["eps_r"] = float(sc_cfg.get("eps_r", 3.0))
+
+ if geometry == "square":
+ sc["square"] = {
+ "cx": float(sc_cfg.get("cx", 0.5)),
+ "cy": float(sc_cfg.get("cy", 0.5)),
+ "half_side": float(sc_cfg.get("half_side", 0.15)),
+ "angle": float(sc_cfg.get("angle", 0.0)),
+ }
+ elif geometry == "multi_circle":
+ circles_raw = sc_cfg.get("circles", [])
+ circles = []
+ for c in circles_raw:
+ circles.append({
+ "cx": float(c["cx"]), "cy": float(c["cy"]),
+ "radius": float(c["radius"]),
+ "eps_r": float(c.get("eps_r", sc_cfg.get("eps_r", 3.0))),
+ })
+ sc["circles"] = circles
+ elif geometry == "circle":
+ sc["cx"] = float(sc_cfg.get("cx", 0.5))
+ sc["cy"] = float(sc_cfg.get("cy", 0.5))
+ sc["radius"] = float(sc_cfg.get("radius", 0.2))
+
+ hc["wave_number_mode"] = "fixed"
+ hc["wave_number"] = float(k_test)
+
+ factory = _GEOMETRY_FACTORIES.get(geometry)
+ return base_config, factory
+
+
+# ═══════════════════════════════════════════════════════════════════════
+# Main test function
+# ═══════════════════════════════════════════════════════════════════════
+
+def test_alt_media(
+ base_config: dict,
+ test_cfg: dict,
+ cli_overrides: Optional[dict] = None,
+):
+ """Run AFEM inference with config-driven parameters.
+
+ Args:
+ base_config: loaded from config.yaml (model/network/algo)
+ test_cfg: loaded from test_config.yaml (test-specific params)
+ cli_overrides: optional CLI arg overrides dict
+ """
+ ov = cli_overrides or {}
+
+ # ── Resolve parameters: test_cfg < CLI override ──
+ tc = test_cfg.get("test", {})
+ ref_cfg = test_cfg.get("reference", {})
+ sc_cfg = test_cfg.get("scatterer", {})
+
+ geometry = ov.get("geometry") or tc.get("geometry", "circle")
+ checkpoint_path = ov.get("checkpoint") or tc.get("checkpoint", "checkpoints/model_final.pt")
+ output_path = ov.get("output") or tc.get("output", "result/test_media.png")
+ seed = ov.get("seed") or tc.get("seed", 99)
+ k_test = ov.get("k_test") or test_cfg.get("k_test", 8.0)
+ n_refine_vertex = ov.get("n_refine_vertex") or ref_cfg.get("n_refine_vertex", 2)
+ n_refine_grid = ov.get("n_refine_grid") or ref_cfg.get("n_refine_grid", 3)
+ grid_resolution = ov.get("grid_resolution") or ref_cfg.get("grid_resolution", 200)
+
+ # Allow CLI override of scatterer params
+ for key in ("cx", "cy", "radius", "eps_r", "half_side", "angle"):
+ if ov.get(key) is not None:
+ sc_cfg[key] = ov[key]
+ if ov.get("circles") is not None:
+ sc_cfg["circles"] = ov["circles"]
+
+ algo = base_config.get("algorithm", {})
+
+ # ── 1. Inject scatterer config ──
+ config, factory = _inject_scatterer_config(
+ copy.deepcopy(base_config), geometry, sc_cfg, k_test)
+
+ # ── 2. Create env with alt factory ──
+ import environment.fem_problem as fem_problem_module
+
+ _orig_create = None
+ if factory is not None:
+ _orig_create = fem_problem_module.create_helmholtz_problem
+ fem_problem_module.create_helmholtz_problem = factory
+
+ from environment.mesh_refinement import MeshRefinement
+ env = MeshRefinement(
+ environment_config=config.get("environment", {}).get("mesh_refinement", {}),
+ seed=seed,
+ )
+
+ # ── 3. Load model ──
+ model = create_model(env, config.get("network", {}), algo.get("ppo", {}))
+ load_checkpoint(model, checkpoint_path)
+ model.eval()
+ dev = next(model.parameters()).device
+ print(f"[Device] {dev}")
+ model = model.to(dev)
+
+ # ── 4. Reset env ──
+ print(f"[Test] Geometry: {geometry} k={k_test:.3f}")
+ obs = env.reset()
+
+ # ── 5. Patch epsilon_r_elements (after reset) ──
+ _patch_epsilon_r(env)
+
+ # Restore original factory
+ if _orig_create is not None:
+ fem_problem_module.create_helmholtz_problem = _orig_create
+
+ # ── 6. Print scatterer info ──
+ fp = env.fem_problem.fem_problem
+ if geometry == "square":
+ print(f"[Test] Square: center=({getattr(fp, '_sq_cx', 0.5):.3f}, "
+ f"{getattr(fp, '_sq_cy', 0.5):.3f}) half_side={getattr(fp, '_sq_half', 0.2):.3f}")
+ elif geometry == "multi_circle":
+ circles_attr = getattr(fp, "_circles", [])
+ for i, c in enumerate(circles_attr):
+ print(f"[Test] Circle {i}: center=({c['cx']:.3f}, {c['cy']:.3f}) "
+ f"r={c['radius']:.3f} eps_r={c['eps_r']:.1f}")
+ elif geometry == "circle":
+ print(f"[Test] Circle: center=({getattr(fp, '_cx', 0.5):.3f}, "
+ f"{getattr(fp, '_cy', 0.5):.3f}) r={getattr(fp, '_radius', 0.2):.3f}")
+
+ # ── 7. Compute fine-FEM reference ONCE on initial mesh ──
+ n_init = env.mesh.t.shape[1]
+ print(f"[Test] Initial mesh: {n_init} elements")
+ print(f"[Test] Computing fine-FEM reference (n_refine_vertex={n_refine_vertex}, "
+ f"n_refine_grid={n_refine_grid}, grid={grid_resolution})...")
+
+ t0 = time.time()
+ u_ref_initial, ref_mesh, ref_sol = _compute_fine_fem_reference(env, n_refine=n_refine_vertex)
+ ref_grid = _compute_ref_grid(env, n_refine=n_refine_grid, resolution=grid_resolution)
+ print(f"[Test] Reference ready ({time.time() - t0:.1f}s, grid {ref_grid['X'].shape})")
+
+ # ── 8. Run inference ──
+ stem = output_path.rsplit(".", 1)[0] if "." in output_path else output_path
+ init_mesh = env.mesh
+ init_sol = env.scalar_solution
+ init_err = _compute_step_error(init_sol, u_ref_initial)
+ steps = [(init_mesh, init_sol, init_err, env.num_agents, u_ref_initial)]
+
+ n_elem_init = env.num_agents
+ print(f" Step 0: reward=--- err={init_err:.4f} elements={n_elem_init}")
+
+ done = False
+ step_idx = 0
+ total_reward = 0.0
+ while not done:
+ obs_g = obs.to(dev)
+ with torch.no_grad():
+ actions, _, _ = model(Batch.from_data_list([obs_g]), deterministic=True)
+ obs, reward, done, info = env.step(actions.cpu().numpy())
+ step_r = float(np.sum(reward))
+ total_reward += step_r
+ step_idx += 1
+
+ # Interpolate cached reference to current mesh vertices (no re-solve)
+ u_ref_current = _interpolate_ref_to_mesh(env.mesh.p.T, ref_mesh, ref_sol)
+ step_err = _compute_step_error(env.scalar_solution, u_ref_current)
+ steps.append((env.mesh, env.scalar_solution, step_err, env.num_agents,
+ u_ref_current))
+
+ print(f" Step {step_idx:2d}: reward={step_r:+.4f} err={step_err:.4f} "
+ f"elements={info.get('num_elements', '?')} "
+ f"sel={info.get('selected_count', 0)} "
+ f"done={done}")
+
+ print(f"\n[Test] total_reward={total_reward:.4f} final_err={steps[-1][2]:.4f} "
+ f"final_elements={steps[-1][3]}")
+
+ # ── 9. Visualize ──
+ _save_pngs(steps, stem, checkpoint_path, k_test, geometry, env, ref_grid)
+ print(f"[Viz] Done → {output_path}")
+
+
+# ═══════════════════════════════════════════════════════════════════════
+# CLI
+# ═══════════════════════════════════════════════════════════════════════
+
+def _load_yaml(path: str) -> dict:
+ """Load a YAML file, resolving relative paths against project root."""
+ import yaml
+ if not os.path.isabs(path):
+ path = os.path.join(_project_root, path)
+ with open(path, "r") as f:
+ return yaml.safe_load(f)
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Test AFEM trained model on alternative scatterer geometries")
+
+ # Config
+ parser.add_argument("--config", default="src/test_config.yaml",
+ help="Test config YAML (default: src/test_config.yaml)")
+
+ # Test scenario overrides
+ parser.add_argument("--geometry", choices=["square", "multi_circle", "circle"],
+ help="Scatterer geometry (overrides config)")
+ parser.add_argument("--checkpoint", help="Model checkpoint path (overrides config)")
+ parser.add_argument("--output", help="Output image path (overrides config)")
+ parser.add_argument("--seed", type=int, help="Random seed (overrides config)")
+ parser.add_argument("--k-test", type=float, help="Wave number (overrides config)")
+
+ # Scatterer overrides
+ parser.add_argument("--cx", type=float, help="Scatterer center x")
+ parser.add_argument("--cy", type=float, help="Scatterer center y")
+ parser.add_argument("--radius", type=float, help="Scatterer radius (circle)")
+ parser.add_argument("--eps-r", type=float, help="Dielectric constant eps_r")
+ parser.add_argument("--half-side", type=float, help="Half side length (square)")
+ parser.add_argument("--angle", type=float, help="Rotation angle in radians (square)")
+ parser.add_argument("--circles", nargs="*", default=None,
+ help="Circle specs: 'cx,cy,radius[,eps_r]' (multi_circle)")
+
+ # Reference computation overrides
+ parser.add_argument("--n-refine-vertex", type=int,
+ help="Uniform refinement levels for vertex error reference")
+ parser.add_argument("--n-refine-grid", type=int,
+ help="Uniform refinement levels for grid heatmap reference")
+ parser.add_argument("--grid-resolution", type=int,
+ help="Grid resolution N for heatmap (N x N)")
+
+ args = parser.parse_args()
+
+ # ── Load test config ──
+ test_cfg = _load_yaml(args.config)
+
+ # ── Load base config ──
+ base_config_path = test_cfg.get("base_config", "src/config.yaml")
+ base_config = _load_yaml(base_config_path)
+
+ # ── Build CLI overrides dict (only non-None values) ──
+ cli_overrides = {}
+ for key in ("geometry", "checkpoint", "output", "seed", "k_test",
+ "cx", "cy", "radius", "eps_r", "half_side", "angle",
+ "n_refine_vertex", "n_refine_grid", "grid_resolution"):
+ val = getattr(args, key.replace("-", "_"), None)
+ if val is not None:
+ cli_overrides[key] = val
+
+ # Parse --circles if provided
+ if args.circles is not None:
+ circles = []
+ for spec in args.circles:
+ parts = [float(x.strip()) for x in spec.split(",")]
+ circles.append({
+ "cx": parts[0], "cy": parts[1], "radius": parts[2],
+ "eps_r": parts[3] if len(parts) > 3 else 3.0,
+ })
+ cli_overrides["circles"] = circles
+
+ # ── Set seeds ──
+ seed = cli_overrides.get("seed", test_cfg.get("test", {}).get("seed", 99))
+ torch.manual_seed(seed)
+ np.random.seed(seed)
+
+ test_alt_media(
+ base_config=base_config,
+ test_cfg=test_cfg,
+ cli_overrides=cli_overrides,
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/visualize.py b/src/visualize.py
index 06b2068..c9451a0 100644
--- a/src/visualize.py
+++ b/src/visualize.py
@@ -176,14 +176,13 @@ def _save_png(steps, stem, checkpoint_path, k, cx=0.5, cy=0.5, radius=0.2, eps_r
if im2 is not None:
fig2.colorbar(im2, ax=axes2[1], fraction=0.046, pad=0.04)
- # ── Panel 3: ||FEM| - |Mie|| error ──
- mie_abs = np.abs(u_mie_at_verts)
- error_abs = np.abs(coarse_val - mie_abs)
+ # ── Panel 3: |FEM − Mie| complex error ──
+ error_abs = np.abs(scalar - u_mie_at_verts) # complex difference, preserves phase
evmin, evmax = 0.0, error_abs.max() or 1.0
if evmax - evmin < 1e-12:
evmax = evmin + 1.0
tcf3 = _render_field(axes2[2], pts[:, 0], pts[:, 1], tg_coarse, error_abs,
- f"||FEM|-|Mie|| L2={err_val:.4f} max={error_abs.max():.4f}",
+ f"|FEM − Mie| L2={err_val:.4f} max={error_abs.max():.4f}",
evmin, evmax, show_mesh=True, cmap="hot")
axes2[2].add_patch(plt.Circle((cx, cy), radius, fill=False,
edgecolor="cyan", linewidth=1.5, linestyle="--"))
@@ -240,6 +239,10 @@ def visualize(config: dict, checkpoint_path: str, output_path: str = "result/vis
init_mesh = env.mesh
init_sol = env.scalar_solution
init_err = _compute_step_error(env, u_mie_ref)
+ init_aw = _compute_area_weighted_error(env, u_mie_ref)
+ print(f" Step 0: verts={init_mesh.p.shape[1]} elem={env.num_agents} "
+ f"mie_err={init_err:.4f} aw_rel={init_aw['rel_err']*100:.2f}% "
+ f"aw_rmse={init_aw['w_rmse']:.4f} max_err={init_aw['max_err']:.4f}")
steps = [(init_mesh, init_sol, init_err, env.num_agents, u_mie_ref)]
print(f"[Viz] Running inference...")
@@ -259,10 +262,24 @@ def visualize(config: dict, checkpoint_path: str, output_path: str = "result/vis
diag_n_elig = int(getattr(env, "_diag_eligible_ratio", 0) * env.num_agents)
diag_n_mask = int(getattr(env, "_diag_masked_ratio", 0) * env.num_agents)
remaining = getattr(env, "_n_budget", 0) - env.num_agents
+ step_aw = _compute_area_weighted_error(env, u_mie_current)
+ # timing
+ _timing = env.fem_problem.last_solve_timing
+ _t_str = ""
+ if _timing is not None:
+ _t_str = (f" [timing] K={_timing['assemble_K']*1e3:.1f}ms"
+ f" f={_timing['assemble_f']*1e3:.1f}ms"
+ f" bnd={_timing['assemble_boundary']*1e3:.1f}ms"
+ f" solve={_timing['solve']*1e3:.1f}ms"
+ f" total={_timing['total']*1e3:.1f}ms"
+ f" n_dof={_timing['n_dof']}")
+
print(f" Step {step_idx}: verts={env.mesh.p.shape[1]} elem={n_elem} "
- f"mie_err={step_err:.4f} "
+ f"mie_err={step_err:.4f} aw_rel={step_aw['rel_err']*100:.2f}% "
+ f"aw_rmse={step_aw['w_rmse']:.4f} max_err={step_aw['max_err']:.4f} "
f"sel={diag_n_sel} elig={diag_n_elig} masked={diag_n_mask} "
- f"remaining={remaining} done={done}")
+ f"remaining={remaining} done={done}"
+ f"{_t_str}")
steps.append((env.mesh, sol, step_err, n_elem, u_mie_current))
@@ -283,6 +300,41 @@ def _compute_step_error(env, u_mie_ref) -> float:
return float(np.linalg.norm(diff) / denom)
+def _compute_area_weighted_error(env, u_mie_ref):
+ """Area-weighted relative error FEM vs Mie (triangle-level quadrature)."""
+ if u_mie_ref is None:
+ return {"rel_err": float("nan"), "w_rmse": float("nan"), "max_err": float("nan")}
+ mesh = env.mesh
+ pts = mesh.p.T
+ tri = mesh.t.T
+ u_fem = env.scalar_solution
+
+ err_abs = np.abs(u_fem - u_mie_ref)
+ ref_abs = np.abs(u_mie_ref)
+
+ v1, v2, v3 = pts[tri[:, 0]], pts[tri[:, 1]], pts[tri[:, 2]]
+ tri_areas = 0.5 * np.abs(
+ (v2[:, 0] - v1[:, 0]) * (v3[:, 1] - v1[:, 1])
+ - (v3[:, 0] - v1[:, 0]) * (v2[:, 1] - v1[:, 1])
+ )
+
+ err_tri_sq = (err_abs[tri[:, 0]] ** 2
+ + err_abs[tri[:, 1]] ** 2
+ + err_abs[tri[:, 2]] ** 2) / 3.0
+ ref_tri_sq = (ref_abs[tri[:, 0]] ** 2
+ + ref_abs[tri[:, 1]] ** 2
+ + ref_abs[tri[:, 2]] ** 2) / 3.0
+
+ total_area = np.sum(tri_areas)
+ w_rmse = np.sqrt(np.sum(err_tri_sq * tri_areas) / total_area)
+
+ ref_total = np.sum(ref_tri_sq * tri_areas)
+ rel_err = np.sqrt(np.sum(err_tri_sq * tri_areas) / ref_total) if ref_total > 1e-12 else float("nan")
+
+ return {"rel_err": float(rel_err), "w_rmse": float(w_rmse),
+ "max_err": float(np.max(err_abs))}
+
+
def _eval_mie_on_mesh(env, mie_info):
"""Re-evaluate Mie scattered field on current FEM mesh vertices."""
if mie_info is None:
diff --git a/sync.ps1 b/sync.ps1
index 0d0f9be..42469c3 100644
--- a/sync.ps1
+++ b/sync.ps1
@@ -2,7 +2,7 @@
$ServerA_User = "dxw"
$ServerA_IP = "222.20.97.222"
$RemotePath = "/public/home/dxw/Codes/afem" # 服务器A上项目的绝对路径
-$LocalPath = "F:\ASMRplusplus-main" # 本地项目路径
+$LocalPath = "F:\mine\afem" # 本地项目路径
# ==========================================
Write-Host ">>> Step 1: Downloading code from Server A..." -ForegroundColor Cyan
diff --git a/train.sh b/train.sh
new file mode 100644
index 0000000..34b63d6
--- /dev/null
+++ b/train.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+#SBATCH --job-name=afem-train
+#SBATCH --partition=gpu
+#SBATCH --gres=gpu:1
+#SBATCH --nodelist=node06
+#SBATCH --cpus-per-task=4
+#SBATCH --mem=32G
+#SBATCH --time=24:00:00
+#SBATCH --output=logs/train_%j.out
+
+# cd /public/home/dxw/Codes/afem
+
+
+
+echo "Starting training at $(date)"
+
+echo "Running on node: $(hostname)"
+
+python -u src/main.py --mode train --config src/config.yaml
+
+echo "Training finished at $(date)"
diff --git a/流程.txt b/流程.txt
deleted file mode 100644
index e69de29..0000000