3. 算法需求分析与接口设计
在工程算法开发中,最昂贵的错误往往不是代码写错,而是算法做对了数学、却做错了需求。需求分析阶段的一个歧义,可能在集成测试时才暴露,届时修改成本已是设计阶段的数十倍。本节聚焦如何把模糊的工程需求,逐步收敛为可编码、可测试、可验收的算法规格与接口契约。
一、从工程需求到算法规格的三层分解
工程需求通常以自然语言描述,例如“雷达在强杂波背景下应能稳定检测低速小目标”。这句话无法直接编码,需要经过三层分解:
- 功能需求:算法要完成什么——检测目标、估计距离与速度、输出航迹。
- 性能需求:达到什么指标——检测概率 Pd ≥ 0.9、虚警率 Pfa ≤ 1e-6、距离精度 σ_R ≤ 5 m。
- 约束需求:在什么条件下——单帧处理时间 ≤ 10 ms、定点实现、内存 ≤ 2 MB。
这三层必须同时明确,否则规格不完整。例如只写“检测概率高”无法验收,只写“处理快”也无法判断是否达标。工程实践中建议用一张需求—规格追溯表,把每条工程需求映射到具体的算法指标、验证方法和验收阈值。
二、输入输出定义:接口的第一道防线
输入输出定义不是简单写“输入是信号、输出是结果”,而要精确到工程可对接的程度。以恒虚警率(CFAR)检测算法为例,其输入输出规格应包含:
| 项目 | 规格说明 |
|---|---|
| 输入数据 | 复数基带采样矩阵,维度 [N_range × N_pulse],double 或 int16 |
| 采样率 | 10 MHz,距离分辨率 15 m |
| 参考窗 | 左右各 16 个距离单元,保护单元各 4 个 |
| 虚警率 | Pfa = 1e-6,对应门限因子由参考窗长度计算 |
| 输出 | 检测标志矩阵 [N_range × N_pulse],逻辑型;附带估计信噪比 |
| 坐标系 | 距离维沿行方向递增,脉冲维沿列方向递增 |
这里特别强调坐标系与方向约定:距离维是行还是列、索引从 0 还是 1 开始、单位是米还是采样点,必须在接口文档中写死。工程中大量集成故障源于“你以为是列优先,我以为是行优先”。
三、接口契约:比函数签名更重要的约定
接口契约描述调用方与被调方之间的权利与义务,包括:前置条件、后置条件、异常行为、边界处理。例如 CFAR 检测函数的契约可以写成:
前置条件:输入矩阵非空,参考窗长度 < 距离维长度
后置条件:输出检测标志与输入同维度;门限矩阵已内部计算
异常行为:输入含 NaN 时返回全零检测并置错误码 -1
边界处理:距离维两端不足参考窗时,采用单侧参考窗或补零
契约的价值在于:调用方知道“我该保证什么”,被调方知道“我必须交付什么”。当契约被违反时,责任边界清晰,排障效率大幅提升。
四、可测试性设计:让验证成为设计的一部分
可测试性不是测试阶段才考虑的事,而是设计阶段就要植入的属性。具体做法包括:
- 可观测性:算法内部关键中间量(如噪声功率估计、门限值)应可输出,便于定位问题。
- 可注入性:支持注入已知测试信号,例如人工构造的单目标回波,用于验证检测逻辑。
- 确定性:相同输入必须产生相同输出,避免随机初始化或未定义行为。
- 可分解性:算法拆分为可独立测试的子函数,如噪声估计、门限计算、比较判决。
五、需求到接口的映射关系
下图展示了从工程需求出发,经过规格分解、输入输出定义、接口契约,最终落到可测试性设计的完整映射链路。图中同时标注了每层的关键交付物与验证手段,便于在实际项目中对照检查。
六、实操示例:CFAR 检测算法的接口规格片段
以下给出一个可直接参考的接口规格片段,用于说明如何把上述方法落到具体算法上。示例参数为教学假设,实际项目需根据雷达参数重新计算。
函数名:cfar_detect
输入:
data — [N_range × N_pulse] 复数矩阵,单位:归一化幅度
guard_cell — 保护单元数,默认 4
ref_cell — 参考单元数,默认 16
pfa — 虚警率,默认 1e-6
输出:
det_flag — [N_range × N_pulse] 逻辑矩阵,true 表示检测到目标
threshold — [N_range × N_pulse] 门限矩阵,便于观测
snr_est — [N_range × N_pulse] 估计信噪比,单位 dB
契约:
前置:N_range > 2*(guard_cell + ref_cell)
后置:det_flag 与 data 同维度;threshold 已按 pfa 计算
异常:data 含 NaN/Inf 时返回全 false,并记录错误码
边界:距离维首尾不足参考窗时,采用单侧参考窗
注意这里把 threshold 和 snr_est 作为输出,而不是内部隐藏变量。这是可观测性设计的直接体现:当检测结果异常时,工程师可以立即查看门限是否合理、信噪比估计是否偏离预期,而不需要重新插桩或修改代码。
七、可测试性检查清单
在设计评审时,可用以下清单快速检查算法接口是否具备可测试性:
| 检查项 | 合格标准 |
|---|---|
| 输入边界是否明确 | 空输入、单点输入、极值输入均有定义行为 |
| 输出是否可观测 | 关键中间量可作为可选输出返回 |
| 是否支持注入测试 | 可用已知信号验证检测/估计逻辑 |
| 是否确定性 | 相同输入多次运行结果一致 |
| 是否可分解 | 核心子步骤可独立调用与测试 |
| 异常是否可区分 | 不同错误返回不同错误码,而非统一报错 |
需求分析与接口设计是算法工程化的起点。把工程需求翻译成可量化的算法规格,把算法规格固化为精确的输入输出定义,再用接口契约约束调用关系,最后以可测试性设计保证验证可行——这条链路走通,后续的编码、集成与验收才有稳固基础。