# DefensePlanner 防御规划引擎 — 技术方案 - **版本**:V4 - **日期**:2026-06-15 - **状态**:已实现 --- ## 1. 概述 DefensePlanner 是防御推荐模块的核心引擎。它接收**可用火力单元池**和**威胁批次列表**,综合考虑弹药匹配、空间可达性、时间约束、资源竞争,输出**最优分配方案**和**临界边际方案**。 **当前问题**: - `DefaultDefenseAdvisor` 本质是"单威胁 → 单方案"的规则匹配器 - `Recommend()` 接收 `ThreatProfile`(不含火力单元信息),无法做资源分配 - `RecommendMultiGroup()` 接收 `List`,但决策逻辑简单(先到先服务) - 空基/地基平台类型通过 `PreferredPlatformType` 开关绕过,而非算法自主选择 **目标**:统一的规划入口,给定火力单元池和威胁列表,输出分配方案。 --- ## 2. 输入模型 ### 2.1 FireUnit(火力单元) 统一表达空基和地基平台,作为规划器的基本资产单元: ```csharp class FireUnit { string Id; // 唯一标识 PlatformType Type; // AirBased / GroundBased Vector3 Position; // 待命坐标(空基含巡航高度) // ── 发射装置 ── int GunCount; // 火炮数量(默认 1) int ChannelsPerGun; // 每炮火力通道数(默认 1) int TotalChannels => GunCount * ChannelsPerGun; float ChannelInterval; // 同通道连发最小间隔 s // ── 弹药 ── int TotalMunitions; // 总载弹量 List AmmoTypes; // 可装填的弹药类型 float Cooldown; // 通道冷却时间 s float AmmoChangeTime; // 更换弹种时间 s // ── 搜索跟踪 ── float RadarRange; // 雷达探测距离 m float EORange; // 光电探测距离 m float IRRange; // 红外探测距离 m // ── 空基 ── float CruiseSpeed; // 巡航速度 m/s float ReleaseAltitude; // 投放高度 m // ── 地基 ── float MuzzleVelocity; // 初速 m/s } ``` ### 2.2 DroneWave(威胁批次) ```csharp class DroneWave { string WaveId; // 批次 ID ScenarioDrone Profile; // 类型、数量、动力、翼展、速度、高度 List Waypoints; // 航路点 float ArrivalTime; // 预计算:到达防御区域中点的时间 s } ``` ### 2.3 CombatScene(作战环境) 沿用现有的 `CombatScene`,提供风速、风向、天气等影响扩散模型计算的参数。 --- ## 3. 输出模型 ### 3.1 UnitAssignment(单元分配) ```csharp class UnitAssignment { string FireUnitId; // 分配到的火力单元 string DroneWaveId; // 对抗的威胁批次 AerosolType AmmoType; // 装填的弹药类型 int RoundsFired; // 本次发射几发 float FirstFireTime; // 首发发射时机 s List FireEvents; // 具体发射事件(含位置、时间) } ``` ### 3.2 DefensePlan(规划结果) ```csharp class DefensePlan { List Assignments; // 分配方案 List MergedSchedule; // 合并后的发射计划(排序) float OverallProbability; // 总体拦截概率估计 int ThreatsEngaged; // 被分配方案的威胁数 int ThreatsUnengaged; // 无法分配方案的威胁数 string Summary; // 人类可读概览 } ``` ### 3.3 DefensePlanner 输出 ```csharp class PlannerResult { DefensePlan Best; // 最优方案 DefensePlan Critical; // 临界方案(刚好有效) } ``` --- ## 4. 内部流程(五步法) ``` 输入:List + List + CombatScene │ ▼ Step 1 — 威胁排序 │ 威胁指数 = 速度系数 × 目标类型系数(可扩展重量、载弹量等) │ 综合优先级 = 威胁指数 / (到达时间 + 1) │ 同到达时间下高威胁优先 │ ▼ Step 2 — 弹药匹配 │ PowerType → AerosolType(规则表) │ 输出:每个威胁需要的弹药类型 │ ▼ Step 3 — 候选生成 │ 对每个(威胁, 火力单元)组合: │ ① 弹药兼容性检查 │ ② 空间可达性(地基:弹道射程;空基:飞行距离) │ ③ 时间窗口计算(最早/最晚拦截时机) │ 输出:List │ ▼ Step 4 — 分配求解 │ 贪心策略(v1,后续可升级回溯/匈牙利): │ 按威胁优先级遍历 │ → 选最早可拦截的兼容单元 │ → 弹药必须精确匹配,不降级(ActiveMaterial 不能替代 InertGas) │ → 标记单元占用(冷却 + 换弹 + 飞行时间) │ → 弹药耗尽则移除 │ ▼ Step 5 — 时序生成 │ 对每个分配: │ 地基:FireTime = 最佳交汇时刻 − 炮弹飞行时间 │ 空基:FireTime = 最佳交汇时刻 − 弹药下落时间(固定阵位水平发射) │ 合并排序 → MergedFireSchedule │ ▼ 输出:PlannerResult { Best, Critical } ``` --- ## 5. 关键算法详设 ### 5.1 威胁排序 **威胁指数** = 速度系数 × 目标类型系数(后续可扩展重量、载弹量等要素) | 目标类型 | 类型系数 | 理由 | |----------|:------:|------| | 高速目标(300km/h+) | 4 | 最快突防 | | 喷气式 | 3 | 高温发动机,毁伤窗口短 | | 固定翼 | 2 | 速度中等 | | 活塞式 | 2 | 速度中等 | | 旋翼 | 1 | 慢速 | | 电推 | 1 | 慢速,无热源 | 速度系数 = TypicalSpeed / 60(以 60 km/h 为基准归一化) **综合优先级** = 威胁指数 / (ArrivalTime + 1),按降序排列。同到达时间下高威胁优先。 ### 5.2 InterceptCandidate(拦截候选) ```csharp class InterceptCandidate { FireUnit Unit; AerosolType AmmoType; float EarliestTime; // 最早可拦截时刻(仿真秒) float LatestTime; // 最晚可拦截时刻 float Coverage; // 有效覆盖时长 float KillProbability; // 预计杀伤概率 } ``` **候选生成逻辑**: 对于给定的威胁批次和火力单元: 1. **弹药兼容性**:`Unit.AmmoTypes` 包含威胁需要的弹药类型 2. **地基可达性**:计算目标与部署点的水平距离,校验 `MuzzleVelocity` 射程 3. **空基可达性**:计算飞行距离,`飞行时间 = distance(巡逻点, 投放点) / CruiseSpeed` 4. **时间窗口**: - 威胁到达防御区域的时间段 `[tEnter, tExit]` - 单元可拦截的时间段 = 威胁窗口 ∩(单元可用时间 + 弹药飞行时间) - 空基额外加平台飞行时间 5. **覆盖率**:基于云团有效半径、持续时间、无人机速度的综合估计 ### 5.3 贪心分配算法 ``` pending = threats.OrderBy(t => t.ArrivalTime) available = fireUnits.Clone() timeNow = 0 assignments = [] for each threat in pending: candidates = GenerateCandidates(threat, available, timeNow) if candidates.isEmpty: threats.Unengaged++ continue best = candidates.OrderBy(c => c.EarliestTime) .ThenByDescending(c => c.KillProbability) .First() assignment = Commit(best, threat) assignments.Add(assignment) // 更新单元状态 unit = best.Unit unit.TotalMunitions -= assignment.RoundsFired timeNow = max(timeNow, assignment.LastFireTime + unit.Cooldown) ``` ### 5.4 临界方案(Critical Plan) 临界方案 = 刚好达到可接受下限概率(默认 50%)的最小配置: - 从最优方案的分配列表出发 - 逐次减少每个单元分配的弹药数 - 直到整体拦截概率刚好跌破 50% - 上一轮(≥50% 的最小配置)即为临界方案 > 作用:给操作员一个置信区间——最优 vs 临界,展示"再少就不够了"的底线。 ### 5.5 多批次合并 ``` Step 4 的贪心算法天然支持多威胁: - 按优先级顺序处理 - 前一威胁占用的单元在后续威胁中不可用(直到冷却/换弹完成) - 弹药消耗全局追踪 ``` --- ## 6. 接口设计 ### 6.1 规划器接口 ```csharp public interface IDefensePlanner { /// 为给定火力单元池和威胁列表生成规划方案 PlannerResult Plan(List fireUnits, List threats, CombatScene environment); } ``` ### 6.2 兼容现有接口 `DefaultDefenseAdvisor` 改造为 `DefaultDefensePlanner`: ```csharp public class DefaultDefensePlanner : IDefensePlanner { private readonly List _ammoCatalog; public DefaultDefensePlanner(List ammoCatalog) { ... } public PlannerResult Plan(List fireUnits, List threats, CombatScene env) { // Step 1-5 } // 内部方法 private List Prioritize(List threats) { ... } private AerosolType MatchAmmo(PowerType power) { ... } private List GenerateCandidates(DroneWave threat, List units, float now) { ... } private DefensePlan Solve(List threats, List units) { ... } private DefensePlan DeriveCritical(DefensePlan best) { ... } } ``` ### 6.3 接口迁移(已完成) | 旧接口 | 新接口 | 状态 | |--------|--------|------| | `IDefenseAdvisor.Recommend(ThreatProfile)` | `IDefensePlanner.Plan(fireUnits, threats, env)` | ✅ 已替换 | | `IDefenseAdvisor.GetDefenseRecommendation(scenarioId)` | 不再需要 | ✅ 已删除 | | `DefaultDefenseAdvisor.RecommendMultiGroup()` | Planner 原生支持多批次 | ✅ 已删除 | --- ## 7. 数据流改造(已实现) ``` SimulationEngine.Initialize(scenarioId) │ │ // 引擎内部组装 ├── BuildFireUnits(config) → List ├── BuildDroneWaves(config) → List └── _scene (CombatScene) │ ▼ IDefensePlanner.Plan(fireUnits, threats, scene) │ ▼ PlannerResult.Best.MergedSchedule │ ▼ 引擎 Tick() 按发射计划执行 ``` > 引擎是 Planner 的唯一调用者。测试和 UI 代码不再直接接触 Planner。 --- ## 8. 实现状态 ### ✅ 已实现 - `IDefensePlanner` + `DefaultDefensePlanner`(五步流水线) - `FireUnit` 通道模型(GunCount/ChannelsPerGun/ChannelInterval/搜索跟踪设备) - 贪心分配 + 物理间隔错发 + 按目标点独立计时 - 空基/地基弹道统一处理 - `SimulationEngine` 内部调用 Planner 自动生成发射计划 - `DefaultFireUnits` 4 种模板 - 报告显示 per-unit 发射数和火力单元列 - 所有硬编码默认值和静默 fallback 已删除 ### ❌ 已删除 - `IDefenseAdvisor` / `DefaultDefenseAdvisor` / `RecommendMultiGroup` - `ThreatProfile` / `DefenseSolution` / `DefenseRecommendation` / `MultiGroupRecommendation`(AlgorithmTypes 中保留但未使用) - `Models.SimEvent`(死代码) - 所有 `?.` + 任意默认值模式 ### 🔒 不变 - `Kinematics` / `GaussianPuffDispersion` / `DamageModelRouter` - 所有 Repository 和数据模型(ScenarioUnit 新增 GunCount/ChannelsPerGun/ChannelInterval) - `ScenarioService` 接口 --- ## 9. 风险与应对 | 风险 | 影响 | 应对 | |------|------|------| | 贪心算法局部最优,整体非最优 | 部分威胁可能被跳过 | 后续可升级为匈牙利算法或回溯搜索;贪心结果对大多数场景足够 | | 覆盖率估算依赖简化模型 | 拦截概率不精确 | 使用现有的 `GaussianPuffDispersion` + `Kinematics`,与仿真引擎一致 | | 空基/地基混合分配复杂 | 边界情况遗漏 | Step 3 候选生成对每种平台类型独立计算,Step 4 统一排序;单元测试覆盖典型混合场景 | --- ## 10. 已决策事项 | # | 议题 | 决策 | |---|------|------| | 1 | 威胁排序 | 综合威胁指数:类型系数(高速4/喷气3/固定翼2/活塞2/旋翼1/电推1)× 速度系数(km/h ÷ 60),除以到达时间。可扩展重量、载弹量等要素 | | 2 | 临界方案 | 概率阈值定义:刚好 ≥ 50% 的最小资源配置 | | 3 | 分配算法 | v1 贪心;后续按需升级回溯搜索或匈牙利算法 | | 4 | Failover | 不做降级。弹药必须精确匹配(ActiveMaterial 不能替代 InertGas) |