Bläddra i källkod

feat:为reset添加物理限制

junc_WHU 4 månader sedan
förälder
incheckning
ac4a05ab93
1 ändrade filer med 44 tillägg och 7 borttagningar
  1. 44 7
      models/uf-rl/超滤训练源码/DQN_env.py

+ 44 - 7
models/uf-rl/超滤训练源码/DQN_env.py

@@ -714,6 +714,28 @@ def is_dead_cycle(info: dict) -> bool:
     # 所有条件通过
     return True  # 成功
 
+def check_pollution_dead_initial_state(p: UFParams, L_s: float = 4900, t_bw_s: float = 50) -> bool:
+    """
+    检查污染动力学是否物理可行(非即死状态)
+    若任意一次 reversible_R = 0.0,则返回 False(即死状态)
+
+    """
+    try:
+        d_R = _delta_resistance(p, L_s)
+        R0 = p.R0
+
+        for idx in [0, 30]:
+            L_h_start = (L_s + t_bw_s) / 3600.0 * idx
+            L_h_next_start = (L_s + t_bw_s) / 3600.0 * (idx + 1)
+            reversible_R = phi_bw_of(p, R0, d_R, L_h_start, L_h_next_start, t_bw_s)
+
+            if reversible_R == 0.0: #  说明原始选择的阻力组合中长期污染增长曲线上升比短期的总污染曲线还要快,该组合不符合物理常识
+                return False  # 即死状态
+        return True
+
+    except Exception:
+        # 若出现数值溢出或参数异常,也视为不可行
+        return False
 
 
 class UFSuperCycleEnv(gym.Env):
@@ -847,17 +869,27 @@ class UFSuperCycleEnv(gym.Env):
 
         return self._get_state_copy()
 
-    def reset(self, seed=None, options=None, max_attempts: int = 200):
+    def reset(self, seed=None, options=None, max_attempts: int = 1000):
         super().reset(seed=seed)
 
         attempts = 0
         while attempts < max_attempts:
             attempts += 1
-            self.generate_initial_state()  # 生成随机初始状态
-            if self.check_dead_initial_state(max_steps=getattr(self, "max_episode_steps", 15),
-                                             L_s=4900, t_bw_s=50):
-                # True 表示可行,退出循环
+            self.generate_initial_state()
+            p = self.current_params
+
+            # Step 1: 运行稳定性检测
+            ok_run = self.check_dead_initial_state(
+                max_steps=getattr(self, "max_episode_steps", 15),
+                L_s=3800, t_bw_s=60
+            )
+
+            # Step 2: 污染动力学检测
+            ok_pollution = check_pollution_dead_initial_state(self.current_params, L_s=3800, t_bw_s=60)
+
+            if ok_run and ok_pollution:
                 break
+
         else:
             # 超过最大尝试次数仍未生成可行状态
             raise RuntimeError(f"在 {max_attempts} 次尝试后仍无法生成可行初始状态。")
@@ -877,7 +909,7 @@ class UFSuperCycleEnv(gym.Env):
         """
         判断当前环境生成的初始状态是否为可行(non-dead)。
         使用最保守策略连续模拟 max_steps 次:
-            若任意一次 is_dead_cycle(info) 返回 False,则视为必死状态。
+            若任意一次 is_dead_cycle(info) 返回 False 或 next_params[0] < 0,则视为必死状态。
 
         参数:
             max_steps: 模拟步数,默认使用 self.max_episode_steps
@@ -906,10 +938,15 @@ class UFSuperCycleEnv(gym.Env):
                 # 异常即视为不可行
                 return False
 
+            # 任意一次不可行即为必死状态
             if not is_dead_cycle(info):
-                # 任意一次失败即为必死状态
                 return False
 
+            # 新增判断:下一步跨膜压差 TMP 不可能为负
+            if next_params.TMP0 < 0:
+                return False
+
+            # 更新参数,进入下一步模拟
             curr_p = next_params
 
         return True