从工程需求到算法选型的决策流程

面对一个实际问题时,从理解需求到选定算法到验证结果的完整动作链

本页目录

把业务需求翻译成算法问题

不要直接跳到算法。先用一句话回答:这个需求的核心计算任务是什么?

"推荐可能认识的人"→ 图上的二度邻居查询。"给 10 万个用户分群"→ 聚类问题。"找出最便宜的配送路线"→ 最短路径或 VRP。"每天自动排班"→ 约束满足问题。

翻译的方式不唯一。同一个需求可能被翻译成不同的算法问题。在这一步多花时间比后面少花时间更值——因为建模方式决定了解法空间。

完成标准:能用"输入是什么、输出是什么、约束条件是什么"三句话描述清楚算法问题。

确认问题的计算复杂度

确定了问题类型之后,查一下这个问题的已知复杂度。是 P 还是 NP-hard?有没有已知的精确高效算法?

如果是经典的多项式时间可解问题(排序、最短路径、最小生成树、最大流),直接从标准算法里选。

如果是 NP-hard(TSP、集合覆盖、图着色、VRP),停下来重新评估:能不能放宽约束条件让问题变简单?近似解可不可接受?有没有现成的求解器可以用?

这一步的目的是避免花两周时间试图精确求解一个 NP-hard 问题。

列出候选算法并比较

针对确定的问题类型,列出所有候选算法。对每个算法记录:时间复杂度(最坏和平均)、空间复杂度、实现难度、对数据特征的假设。

用 Skiena 的算法目录或任何算法参考书做这个步骤。不需要记在脑子里,查就行。

从候选列表中根据实际约束筛选。数据量大 → 排除 O(n²)。需要最坏情况保证 → 排除期望复杂度的算法。内存有限 → 排除空间复杂度高的。需要在线处理 → 排除离线算法。

完成标准:有 2-3 个候选算法,每个都能说出选或不选的理由。

先写暴力解法作为基线

在实现优化算法之前,先写最简单的暴力解法。不需要快,但需要正确。

暴力解法的价值:1)验证你对问题的理解是否正确;2)提供一个正确性基线,后续优化算法的输出可以和它对比;3)如果暴力解法在实际数据量下已经够快,你不需要优化。

用实际大小的数据跑一次暴力解法。如果 100ms 以内出结果,认真考虑是否真的需要更快的算法。代码简单和维护成本低在工程中是真实的优势。

实现、测试、度量

选定算法后实现。用暴力解法的输出做正确性验证——两个算法在相同输入上应该给出相同(或在允许的近似范围内一致)的输出。

用实际数据而非随机数据做性能测试。算法在均匀分布的随机数据上可能表现很好,但在实际数据的分布上可能退化。

度量三个指标:实际运行时间(不只是大 O)、内存峰值、在不同数据量下的扩展趋势。

完成标准:算法在实际数据量下满足性能要求,正确性经过暴力解法交叉验证,扩展趋势和理论分析一致。

同分类继续看