""" env_params.py 超滤(UF)强化学习环境的参数定义文件。 本文件集中定义 UF 强化学习环境中使用的所有【参数类(Parameter Schemas)】。 这些类仅用于描述系统配置、状态语义和约束边界,不包含任何数值计算、 物理模型、奖励逻辑或 Gym 接口实现。 ======================== 参数类总览 ======================== 1. UFState ------------------------ 【环境动态状态】 - 描述超滤系统在某一时刻的运行状态 - 这些变量会在 env.step() 中随动作不断演化 - 构成强化学习算法可观测的 observation - 生命周期:每个 step 更新一次 包含内容: - 实时运行工况(流量、温度、TMP) - 膜污染状态参数(短期污染、长期污染) - CEB 去除能力等可随 episode 演化的量 使用方: - 强化学习环境(step / reset) - 膜阻力物理模型(作为 forward 的 state 输入) - reward 计算逻辑 2. UFPhysicsParams ------------------------ 【物理与工艺固定参数】 - 描述超滤系统的客观工艺与设备配置 - 在整个 episode 甚至整个训练生命周期中保持不变 - 典型为“物理常数 / 工艺设定值” 设计约束: - 使用 frozen dataclass,防止运行时被意外修改 包含内容: - 物理反洗效率时间尺度 - 反洗流量 - CEB 间隔与用水量 - 膜组件面积等硬件参数 使用方: - 膜阻力模型(上升 / 下降) - 回收率、能耗等物理量计算 - 环境内部的物理约束判断 3. UFActionSpec ------------------------ 【动作空间定义】 - 描述智能体“可以选什么动作”,而不是“如何执行动作” - 仅定义动作的物理含义、取值范围和离散粒度 - 不负责构造 Gym action_space 包含内容: - 过滤时长(L)范围与步长 - 物理反洗时长(t_bw)范围与步长 使用方: - 环境初始化时构建离散动作空间 - 不同算法(DQN / Dueling / PPO)共用同一动作语义 4. UFRewardSpec ------------------------ 【奖励函数与安全约束参数】 - 集中管理 reward 计算所需的权重、阈值与约束 - 同时用于 episode 终止(terminated)判断 - 不包含 reward 的计算公式本身 包含内容: - TMP 硬 / 软安全上限 - 回收率与污染惩罚的敏感度系数 - 回收率合理区间与参考污染比例 使用方: - reward 函数 - 环境终止条件判断 5. UFStateBounds ------------------------ 【状态初始化约束】 - 仅用于 reset() 阶段的随机初始化 - 不参与 step() 中的状态演化 - 用于保证初始状态物理合理、覆盖足够多工况 包含内容: - TMP、流量、温度的初始化范围 - 污染模型参数的合理区间 - CEB 去除能力的上下限 使用方: - env.reset() - 用于构造多样化初始工况,增强策略鲁棒性 ======================== 设计原则(请勿破坏) ======================== 1. 本文件只描述“参数是什么”,不描述“参数如何使用” 2. 禁止在本文件中出现: - torch / numpy 数值计算 - Gym / Gymnasium space 定义 - step / forward / reward 等逻辑 3. 若需要新增参数,请优先判断其生命周期: - 是否随 step 变化 → UFState - 是否全局不变 → UFPhysicsParams / Spec 类 4. 若发现需要在此文件中写计算代码,说明模块边界已经被破坏,应重构调用方 """ from dataclasses import dataclass, field from typing import Dict """ 【说明:拆分 UFParams】 原 UFParams 类同时承担了多种不同职责,包括: 1. 环境状态(会在 step 中动态变化) 2. reset 时的初始状态约束 3. 超滤系统的物理 / 工艺固定参数 4. 强化学习动作空间定义 5. 奖励函数与安全约束参数 在强化学习工程中,这种参数结构会带来以下问题: - 状态与参数混杂,容易在 step() 中被误修改 - reset 初始化逻辑与运行逻辑强耦合,难以调试 - 奖励函数修改会影响环境动力学,增加不可控风险 - 不利于算法切换(DQN / Dueling Q / PPO) 因此,现将 UFParams 拆分为多个“职责单一”的参数类, 每个类只负责一类明确的功能,从而实现: - 语义清晰 - 边界明确 - 易于维护 - 算法无关(一个环境,多种算法共用) 【注意】 本次拆分不改变任何物理意义、数值含义与默认参数,仅做结构重组。 """ # ==================== 超滤系统参数配置类 ==================== @dataclass class UFState: """ 【环境动态状态】 描述超滤系统在当前时刻的运行状态。 这些变量会在 step() 中随动作不断演化,并构成强化学习的 observation。 """ # ========== 膜动态运行参数 ========== # 这些参数描述超滤膜的实时运行状态,在环境模拟中会动态变化 q_UF: float = 360.0 # 过滤进水流量(m³/h) # 说明:影响膜通量,进而影响污染速率 # 典型范围:250-400 m³/h TMP: float = 0.03 # 跨膜压差(MPa,兆帕) # 说明:反映膜阻力状态,TMP 越高表示膜污染越严重 # 正常范围:0.01-0.035 MPa,超过 0.08 MPa 需停机检修 temp: float = 25.0 # 水温(摄氏度) # 说明:影响水的粘度,进而影响跨膜压差 # 典型范围:10-40℃,25℃为标准温度 R: float = 200.0 # 膜阻力(缩放至1e2) # 说明:实际上的膜阻力应该根据q_UF/TMP0/temp动态计算,此处仅为构造状态类占位使用 # ========== 膜阻力模型参数 ========== # 这些参数描述膜污染的物理化学特性,基于历史数据拟合得到 nuK: float = 1.7e+02 # 过滤阶段膜阻力增长系数(缩放后单位) # 说明:反映水质污染特性,nuK 越大表示水质越差、膜污染越快 # 物理意义:单位膜通量、单位时间的阻力增长速率 slope: float = 2 # 全周期不可逆污染增长斜率 # 说明:描述长期不可逆污染的累积速率(幂律模型的系数) power: float = 1.032 # 全周期不可逆污染增长幂次 # 说明:描述长期污染的非线性特性(幂律模型的指数) # power > 1 表示污染加速累积,power < 1 表示污染增速放缓 ceb_removal: float = 100 # 化学增强反洗(CEB)可去除的膜阻力(缩放后单位) # 说明:CEB 比物理反洗更彻底,可去除部分不可逆污染 @dataclass(frozen=True) class UFPhysicsParams: """ 【物理与工艺固定参数】 描述超滤系统的客观工艺条件,在整个 episode 中保持不变。 """ global_TMP_hard_limit: float = 0.08 # TMP 硬上限(MPa) # 说明:超过此值将导致episode失败,需立即停机 global_TMP_soft_limit: float = 0.06 # TMP 软上限 (MPa) # 说明:此上限用于指导奖励函数中膜阻力允许上升值,越接近该上限,系统对膜阻力上升控制的更严格 # ========== 反洗参数(固定配置) ========== tau_bw_s: float = 20.0 # 物理反洗时长影响的时间尺度(秒) # 说明:反洗效率的特征时间,当反洗时长 = tau 时,达到约 63% 效率 gamma_t: float = 1.0 # 物理反洗时长作用指数(保留参数,当前未使用) q_bw_m3ph: float = 1000.0 # 物理反洗流量(m³/h) # 说明:反洗流量通常为正常过滤流量的 2-3 倍 # ========== CEB 化学反洗参数 ========== T_ceb_interval_h: float = 48.0 # CEB 间隔时间(小时) # 说明:每运行约 60 小时执行一次化学增强反洗 TODO: PARAM 当前采用保守测试参数48h v_ceb_m3: float = 20.0 # CEB 用水体积(m³) t_ceb_s: float = 40 * 60.0 # CEB 时长(秒,这里为 40 分钟) # ========== 新增:膜面积 ========== # 膜有效面积(锡山水厂配置:128组膜,每组40m²) A = 128 * 40.0 # [m²] # 吨水电耗查找表 energy_lookup: Dict[int, float] = field(default_factory=lambda: { 3600: 0.1034, 3660: 0.1031, 3720: 0.1029, 3780: 0.1026, 3840: 0.1023, 3900: 0.1021, 3960: 0.1019, 4020: 0.1017, 4080: 0.1015, 4140: 0.1012, 4200: 0.1011, 4260: 0.1008, 4320: 0.1007, 4380: 0.1005, 4440: 0.1003, 4500: 0.1001, 4560: 0.0999, 4620: 0.0998, 4680: 0.0996, 4740: 0.0995, 4800: 0.0993, }) @dataclass(frozen=True) class UFActionSpec: """ 【动作空间定义】 描述智能体可选的过滤-反洗策略组合。 """ # ========== 强化学习动作空间搜索范围 ========== # 定义智能体可选择的动作范围(离散化) L_min_s: float = 3800.0 # 过滤时长下限(秒,约 63 分钟) L_max_s: float = 4800.0 # 过滤时长上限,当前为 4800s 80分钟 t_bw_min_s: float = 40.0 # 物理反洗时长下限(秒) t_bw_max_s: float = 60.0 # 物理反洗时长上限(秒) # ========== 动作离散化网格 ========== L_step_s: float = 60.0 # 过滤时长步长(秒) t_bw_step_s: float = 5.0 # 物理反洗时长步长(秒) @dataclass(frozen=True) class UFRewardParams: """ 【奖励函数与安全约束参数】用于 reward 计算和 episode 终止判断。 """ # TMP 限值 global_TMP_hard_limit: float = 0.08 # TMP 硬上限(MPa) # 说明:超过此值将导致 episode 失败,需立即停机 global_TMP_soft_limit: float = 0.06 # TMP 软上限 (MPa) w_tmp_hard: float = 5.0 # TMP超硬限固定惩罚 w_tmp: float = 1.5 # TMP软限惩罚 p: float = 3 # TMP软限非线性指数 w_trend: float = 1.0 # TMP趋势惩罚权重 # 回收率 k_rec: float = 5.0 rec_low: float = 0.92 rec_high: float = 0.99 w_rec: float = 1.0 # 回收率权重 # 残余污染 k_res: float = 10.0 residual_ref_ratio: float = None # 动态=1/max_episode_steps w_res: float = 2.0 # 残余污染权重 # 吨水电耗 k_energy: float = 5.0 energy_low: float = 0.0993 energy_high: float = 0.1034 energy_ref: float = 0.1011 w_energy: float = 1.0 # 能耗权重 @dataclass(frozen=True) class UFStateBounds: """ 【状态初始化约束】 仅用于 reset() 时随机初始化环境状态, 不参与 step() 中的状态演化。 """ # --- 流量约束 --- q_UF_max: float = 380.0 # 进水流量上限(m³/h) q_UF_min: float = 210.0 # 进水流量下限(m³/h) # --- 温度约束 --- temp_max: float = 32.0 # 温度上限(℃) temp_min: float = 16.0 # 温度下限(℃) # --- 初始TMP约束 --- TMP0_max: float = 0.045 # 初始TMP上限(MPa) TMP0_min: float = 0.01 # 初始TMP下限(MPa) # --- TMP上限约束 --- global_TMP_hard_limit: float = 0.08 # --- 短期污染模型参数约束 --- nuK_max: float = 2.6e+02 # 阻力增长系数上限 nuK_min: float = 4e+01 # 阻力增长系数下限 # --- 长期污染模型参数约束 --- slope_max: float = 27 # 不可逆污染斜率上限 slope_min: float = 0.03 # 不可逆污染斜率下限 power_max: float = 2.2 # 不可逆污染幂次上限 power_min: float = 0.4 # 不可逆污染幂次下限 # --- CEB去除能力约束 --- ceb_removal_max: float = 250 # CEB去除阻力上限(缩放后) ceb_removal_min: float = 40 # CEB去除阻力下限(缩放后)