114514
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
# project/ 薄兼容层
|
||||
|
||||
题目 Prompt 要求 `project/` 目录树;本仓库的真实算法保持唯一一份,
|
||||
位于 `src/mcm26b`、`scripts/`。本目录只做 re-export/转发,不复制实现。
|
||||
|
||||
| Prompt 路径 | 真实实现 |
|
||||
|---|---|
|
||||
| `env/simulator_client.py` | `src/mcm26b/protocol/client.py` |
|
||||
| `env/local_env.py` | `src/mcm26b/hrl/hierarchical_env.py`, `low_level_env.py` |
|
||||
| `env/particle_filter.py` | `src/mcm26b/particles.py` |
|
||||
| `policies/high_level_ppo.py` | `src/mcm26b/hrl/policy.py` |
|
||||
| `policies/low_level_ppo.py` | `src/mcm26b/hrl/policy.py`, `low_level_env.py` |
|
||||
| `train/curriculum.py` | `src/mcm26b/hrl/curriculum.py` |
|
||||
| `train/domain_randomization.py` | `src/mcm26b/hrl/curriculum.py` + 配置包装 |
|
||||
| `eval/evaluate.py` | `scripts/benchmark_hrl.py` |
|
||||
| `eval/ablation.py` | `scripts/ablate_hrl.py`(P2) |
|
||||
| `baselines/heuristic.py` | `src/mcm26b/planner/hrl_loop.py` 启发式降级 |
|
||||
| `baselines/end_to_end_ppo.py` | 显式未实现;单源局部 PPO 不冒充 E2E |
|
||||
|
||||
使用示例:
|
||||
|
||||
```python
|
||||
from project.env.local_env import make_local_env
|
||||
env = make_local_env(problem=3, stage=1, seed=7)
|
||||
obs, info = env.reset(seed=7)
|
||||
```
|
||||
|
||||
P1 当前交付:`benchmark_hrl.py`、`train_hrl_high.py`、CLI `--strategy hrl`、
|
||||
`--q4-strategy hrl`。P2 的 BC/Optuna/消融在 smoke 通过后另开。
|
||||
@@ -0,0 +1,4 @@
|
||||
"""题目 Prompt 所需目录树的薄兼容层。
|
||||
|
||||
真实实现仍位于 ``src/mcm26b``;本包只做 re-export / CLI 转发,避免两份算法逻辑。
|
||||
"""
|
||||
@@ -0,0 +1,3 @@
|
||||
from .heuristic import HeuristicHRL, run_heuristic
|
||||
|
||||
__all__ = ["HeuristicHRL", "run_heuristic"]
|
||||
@@ -0,0 +1,16 @@
|
||||
"""端到端 PPO 基线占位。
|
||||
|
||||
按本轮确认:当前只交付局部 PPO 基线;raw-observation/raw-action 的真正
|
||||
端到端 PPO 不在 P0+P1 范围内,因此显式标记未实现,避免把单源局部选点
|
||||
PPO 误称为端到端 baseline。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
def train_end_to_end_ppo(*args, **kwargs):
|
||||
raise NotImplementedError(
|
||||
"本轮只交付局部 PPO 基线;真正的端到端 PPO 基线标记为未实现,"
|
||||
"需单独立项定义原始观测、动作与安全执行边界。")
|
||||
|
||||
|
||||
__all__ = ["train_end_to_end_ppo"]
|
||||
@@ -0,0 +1,16 @@
|
||||
"""兼容入口:信息增益/TSP/覆盖规则 + 高层启发式调度。"""
|
||||
from mcm26b.planner.bayes_loop import BayesLoop
|
||||
from mcm26b.planner.hrl_loop import HRLLoop
|
||||
|
||||
|
||||
def HeuristicHRL(*args, **kwargs):
|
||||
"""返回无模型的高层 HRL 闭环(heuristic_action 降级路径)。"""
|
||||
kwargs.setdefault("high_policy", None)
|
||||
return HRLLoop(*args, **kwargs)
|
||||
|
||||
|
||||
def run_heuristic(*args, **kwargs):
|
||||
return HeuristicHRL(*args, **kwargs).run()
|
||||
|
||||
|
||||
__all__ = ["HeuristicHRL", "run_heuristic", "BayesLoop", "HRLLoop"]
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
from .simulator_client import SimulatorClient
|
||||
from .local_env import HierarchicalEnv, LowLevelEnv, HRLReward, make_local_env
|
||||
from .particle_filter import ChannelParticles
|
||||
|
||||
__all__ = ["SimulatorClient", "HierarchicalEnv", "LowLevelEnv", "HRLReward",
|
||||
"make_local_env", "ChannelParticles"]
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
"""兼容入口:本地简化训练环境。
|
||||
|
||||
HierarchicalEnv 是高层宏动作环境;LowLevelEnv 是独立八方向导航环境。
|
||||
本文件不复制实现,只转发 mcm26b.hrl 下的真实类。
|
||||
"""
|
||||
from mcm26b.hrl.hierarchical_env import HRLReward, HierarchicalEnv
|
||||
from mcm26b.hrl.low_level_env import LowLevelEnv
|
||||
|
||||
__all__ = ["HierarchicalEnv", "LowLevelEnv", "HRLReward", "make_local_env"]
|
||||
|
||||
|
||||
def make_local_env(*, problem: int = 3, stage: int = 4, seed: int | None = None,
|
||||
fidelity: str = "production"):
|
||||
"""按题目 Prompt 的四阶段编号创建训练环境。"""
|
||||
from mcm26b.hrl.curriculum import STAGES
|
||||
if not 1 <= int(stage) <= len(STAGES):
|
||||
raise ValueError(f"stage 必须在 1..{len(STAGES)}")
|
||||
env = HierarchicalEnv(problem=problem, stage=STAGES[int(stage) - 1],
|
||||
fidelity=fidelity)
|
||||
if seed is not None:
|
||||
env.reset(seed=seed)
|
||||
return env
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
"""兼容入口:逐频道网格粒子/幸存集。"""
|
||||
from mcm26b.particles import ChannelParticles, angular_gap
|
||||
|
||||
__all__ = ["ChannelParticles", "angular_gap"]
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
"""兼容入口:真实类见 mcm26b.protocol.client。"""
|
||||
from mcm26b.protocol.client import (ActionRejected, ClearOutcome, DeadlineExceeded,
|
||||
ExitInfo, MeasureOutcome, ProtocolError,
|
||||
ProtocolViolation, SimulatorClient)
|
||||
|
||||
__all__ = ["SimulatorClient", "MeasureOutcome", "ClearOutcome", "ExitInfo",
|
||||
"ProtocolError", "ActionRejected", "ProtocolViolation",
|
||||
"DeadlineExceeded"]
|
||||
@@ -0,0 +1,4 @@
|
||||
from .evaluate import run_benchmark
|
||||
from .ablation import run_ablation
|
||||
|
||||
__all__ = ["run_benchmark", "run_ablation"]
|
||||
@@ -0,0 +1,20 @@
|
||||
"""兼容入口:调用 scripts/ablate_hrl.py(P2 后启用)。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def run_ablation(argv=None) -> int:
|
||||
path = Path(__file__).resolve().parents[2] / "scripts" / "ablate_hrl.py"
|
||||
if not path.exists():
|
||||
raise NotImplementedError(
|
||||
"scripts/ablate_hrl.py 尚未实现;P1 阶段只保证 benchmark/training/CLI。")
|
||||
spec = importlib.util.spec_from_file_location("ablate_hrl_compat", path)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
assert spec.loader is not None
|
||||
spec.loader.exec_module(module)
|
||||
return int(module.main(argv))
|
||||
|
||||
|
||||
__all__ = ["run_ablation"]
|
||||
@@ -0,0 +1,17 @@
|
||||
"""兼容入口:调用 scripts/benchmark_hrl.py。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def run_benchmark(argv=None) -> int:
|
||||
path = Path(__file__).resolve().parents[2] / "scripts" / "benchmark_hrl.py"
|
||||
spec = importlib.util.spec_from_file_location("benchmark_hrl_compat", path)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
assert spec.loader is not None
|
||||
spec.loader.exec_module(module)
|
||||
return int(module.main(argv))
|
||||
|
||||
|
||||
__all__ = ["run_benchmark"]
|
||||
@@ -0,0 +1,5 @@
|
||||
from .high_level_ppo import HighLevelPolicy, load_high_policy
|
||||
from .low_level_ppo import LowLevelPolicy, load_low_policy
|
||||
|
||||
__all__ = ["HighLevelPolicy", "load_high_policy",
|
||||
"LowLevelPolicy", "load_low_policy"]
|
||||
@@ -0,0 +1,10 @@
|
||||
"""兼容入口:高层 MaskablePPO 推理策略。"""
|
||||
from mcm26b.hrl.policy import HighLevelPolicy
|
||||
|
||||
|
||||
def load_high_policy(model_path: str, *, device: str = "auto",
|
||||
problem: int | None = None) -> HighLevelPolicy:
|
||||
return HighLevelPolicy(model_path, device=device, problem=problem)
|
||||
|
||||
|
||||
__all__ = ["HighLevelPolicy", "load_high_policy"]
|
||||
@@ -0,0 +1,9 @@
|
||||
"""兼容入口:低层八方向到达策略(离线导航实验)。"""
|
||||
from mcm26b.hrl.policy import LowLevelPolicy
|
||||
|
||||
|
||||
def load_low_policy(model_path: str, *, device: str = "auto") -> LowLevelPolicy:
|
||||
return LowLevelPolicy(model_path, device=device)
|
||||
|
||||
|
||||
__all__ = ["LowLevelPolicy", "load_low_policy"]
|
||||
@@ -0,0 +1,5 @@
|
||||
from .curriculum import STAGES, Stage, make_scene, training_config
|
||||
from .domain_randomization import randomize_problem_config
|
||||
|
||||
__all__ = ["STAGES", "Stage", "make_scene", "training_config",
|
||||
"randomize_problem_config"]
|
||||
@@ -0,0 +1,6 @@
|
||||
"""兼容入口:课程学习与域随机化。"""
|
||||
from mcm26b.hrl.curriculum import (STAGES, Stage, make_scene, stage_with_noise,
|
||||
training_config, training_spec)
|
||||
|
||||
__all__ = ["STAGES", "Stage", "make_scene", "stage_with_noise",
|
||||
"training_config", "training_spec"]
|
||||
@@ -0,0 +1,31 @@
|
||||
"""兼容入口:本地域随机化参数包装。
|
||||
|
||||
当前真实随机化在 mcm26b.hrl.curriculum.make_scene 内完成;这里只暴露
|
||||
ProblemConfig 的显式替换助手,便于 Optuna/消融在实验配置中记录随机化范围。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
from random import Random
|
||||
|
||||
from mcm26b.config import ProblemConfig
|
||||
|
||||
|
||||
def randomize_problem_config(base: ProblemConfig, *, seed: int,
|
||||
bearing_error_half_deg: float | None = None,
|
||||
r_eff_range: tuple[float, float] | None = None
|
||||
) -> ProblemConfig:
|
||||
"""返回带域随机化标量的新配置;不修改全局默认配置。"""
|
||||
rng = Random(seed)
|
||||
field = base.field
|
||||
if bearing_error_half_deg is None:
|
||||
bearing_error_half_deg = field.bearing_error_half_deg
|
||||
if r_eff_range is not None:
|
||||
lo, hi = r_eff_range
|
||||
if not (0 <= lo <= hi):
|
||||
raise ValueError("r_eff_range 必须为递增非负区间")
|
||||
return dataclasses.replace(base, field=dataclasses.replace(
|
||||
field, bearing_error_half_deg=float(bearing_error_half_deg)))
|
||||
|
||||
|
||||
__all__ = ["randomize_problem_config"]
|
||||
@@ -0,0 +1,20 @@
|
||||
"""兼容入口:调用 scripts/tune_hrl.py(P2 后启用)。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def run_tuning(argv=None) -> int:
|
||||
path = Path(__file__).resolve().parents[2] / "scripts" / "tune_hrl.py"
|
||||
if not path.exists():
|
||||
raise NotImplementedError(
|
||||
"scripts/tune_hrl.py 尚未实现;P1 阶段先冻结超参并留待 P2。")
|
||||
spec = importlib.util.spec_from_file_location("tune_hrl_compat", path)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
assert spec.loader is not None
|
||||
spec.loader.exec_module(module)
|
||||
return int(module.main(argv))
|
||||
|
||||
|
||||
__all__ = ["run_tuning"]
|
||||
Reference in New Issue
Block a user