Files
mcm-26-b/src/mcm26b/config.py
T

89 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""全项目参数中心:题面常量、协议限制、会话策略与搜索规划参数。
任何魔法数字只允许在这里出现一次。各模块通过 :class:`ProblemConfig` 读取;
命令行需要覆盖时用 ``dataclasses.replace`` 派生新配置,不散落字面量。
来源标注约定:
- ``[题面]`` 出自 issue/B题.pdf、附件1《模拟器使用说明》、附件2《通信接口说明》原文;
- ``[工程]`` 本队工程参数,可依演练实测调整,不代表官方规定。
"""
from __future__ import annotations
from dataclasses import dataclass
Vec2 = tuple[float, float]
@dataclass(frozen=True)
class FieldConfig:
"""题目物理世界与协议硬限制。[题面]"""
omega_radius_m: float = 1800.0 # 目标区域半径,圆心为原点
channel_min: int = 1 # 有效频道范围
channel_max: int = 20
source_count_min: int = 10 # 一局源总数范围(接口不直接告知)
source_count_max: int = 16
r_eff_min_m: float = 1000.0 # 有效接收半径下界:no_signal 只能排除该圆盘
r_eff_max_m: float = 1500.0 # 有效接收半径上界:direction 隐含距离上界
near_radius_m: float = 5.0 # "距离过近"阈值,不返回示向度
clear_radius_m: float = 20.0 # 清除半径;与定向朝向无关
bearing_error_half_deg: float = 1.0 # 示向度误差幅度(题设模型)
bearing_decimals: int = 2 # 返回示向度小数位
coord_abs_limit_m: float = 2_000_000.0 # 提交坐标的绝对值上限(超出返回 HTTP 400)
directional_half_angle_deg: float = 90.0 # 定向源朝向两侧各90度覆盖(含边界)
max_virtual_duration_s: float = 360_000.0 # 虚拟世界限时(100小时)
max_real_duration_s: float = 1200.0 # /enter 成功后程序运行上限(20分钟)
test_window_s: float = 1500.0 # 确认开始后的测试窗口(25分钟)
@dataclass(frozen=True)
class CostConfig:
"""虚拟世界动作耗时模型。[题面] 附件1表1、附件2第4节。"""
speed_mps: float = 5.0 # 移动速度;耗时=直线距离/speed
measure_s: float = 5.0 # 每次检测动作耗时(无论结果)
switch_s: float = 1.0 # 任意两频道间切换耗时,仅由合法 /measure 触发
clear_success_s: float = 5.0 # 清除成功耗时 = 光学定位3s + 激光清除2s
clear_fail_s: float = 3.0 # 未发现可清除目标 = 仅光学定位3s
@dataclass(frozen=True)
class SessionConfig:
"""会话与网络策略。arena/robot/request 规则为 [题面],其余为 [工程]。"""
arena_id: str = "default" # [题面] 固定值
base_url: str = "http://127.0.0.1:2026" # [题面] 模拟器默认接口地址
robot_id_max_bytes: int = 64 # [题面] UTF-8 长度 1..64
request_id_max_bytes: int = 128 # [题面] UTF-8 长度 1..128
request_body_max_bytes: int = 65_536 # [题面] 超出返回 HTTP 413
connect_timeout_s: float = 5.0 # [工程] 连接超时
read_timeout_s: float = 15.0 # [工程] 读超时;覆盖"服务器已处理但响应丢失"
max_attempts: int = 3 # [工程] 单动作最多尝试次数(含首次)
retry_backoff_s: float = 0.25 # [工程] 重试退避基数,按 2^n 放大
reserve_exit_s: float = 60.0 # [工程] 预留退出与故障恢复的现实秒数
real_rtt_p95_s: float = 1.0 # [工程] 现实单请求高分位估计,预算核算用
@dataclass(frozen=True)
class SearchConfig:
"""搜索与覆盖规划参数。[工程] 推导依据见 docs/B题建模分析与实施计划.md。"""
grid_step_m: float = 700.0 # P4 覆盖网格步长;单元对角 700*sqrt(2)≈989.95<=1000
grid_half_cells: int = 3 # i,j ∈ [-3,3],49 点覆盖 [-2100,2100]^2 ⊇ Ω
fallback_clear_grid_m: float = 20.0 # P5 后备清除网格;10*sqrt(2)<=20
bearing_rounding_margin_deg: float = 0.0 # 默认不加舍入裕量;敏感性分析时显式设 0.005
@dataclass(frozen=True)
class ProblemConfig:
"""聚合配置。各模块函数的第一个默认参数,便于单测替换。"""
field: FieldConfig = FieldConfig()
cost: CostConfig = CostConfig()
session: SessionConfig = SessionConfig()
search: SearchConfig = SearchConfig()
DEFAULT_CONFIG = ProblemConfig()