refactor(arch): redesign the code structure

This commit is contained in:
Horldsence
2026-09-10 22:38:27 +08:00
parent 21e8a8bf52
commit 83d2e24448
42 changed files with 2514 additions and 251 deletions
+56
View File
@@ -0,0 +1,56 @@
"""P4 全域覆盖:49 点网格与逐频道覆盖记录。
覆盖基线(推导见 docs/B题建模分析与实施计划.md §4):
S = {(700i, 700j) : i, j ∈ [-3,3]},|S| = 49,覆盖 [-2100,2100]² ⊇ Ω,
且允许访问目标圆域外(边界朝外发射的定向源不漏)。
单元内任意点到 4 顶点距离 <= 700·√2 ≈ 989.95 <= 1000 <= 最小接收半径。
验收标准:
- "路过某点"不算"测过某频道":必须按 (频道, 点) 二维记录;
- 已清除/已定位频道可跳过剩余点,但跳过原因必须留痕;
- 自适应跳点(P6)必须保留逐频道覆盖证据,否则不得启用。
"""
from __future__ import annotations
from dataclasses import dataclass, field
from ..config import ProblemConfig, Vec2
def coverage_points(config: ProblemConfig = ProblemConfig()) -> list[Vec2]:
"""49 点覆盖网格生成(纯几何,可独立测试)。"""
step = config.search.grid_step_m
half = config.search.grid_half_cells
return [(step * i, step * j)
for j in range(half, -half - 1, -1)
for i in range(-half, half + 1)]
@dataclass
class CoverageLedger:
"""逐频道覆盖账本:(频道, 网格点) -> 是否已测。"""
config: ProblemConfig = field(default_factory=ProblemConfig)
points: list[Vec2] = field(default_factory=lambda: coverage_points())
measured: set = field(default_factory=set) # {(channel, point_index)}
skipped: dict = field(default_factory=dict) # channel -> 原因
def mark_measured(self, channel: int, point_index: int) -> None:
self.measured.add((channel, point_index))
def measured_at(self, channel: int, point_index: int) -> bool:
return (channel, point_index) in self.measured
def skip_channel(self, channel: int, reason: str) -> None:
"""记录整频道跳过原因(如 already_cleared / located_pending_clear)。"""
self.skipped[channel] = reason
def pending_points(self, channel: int) -> list[int]:
"""该频道尚未测量的网格点下标。扫描调度策略未实现(P4)。"""
return [index for index in range(len(self.points))
if not self.measured_at(channel, index)]
def coverage_complete(self, channel: int) -> bool:
"""该频道覆盖是否完成(含显式跳过)。"""
return channel in self.skipped or not self.pending_points(channel)