← 算法课堂:换一种算法到底换了什么

换一种算法到底换了什么

同一件事有两种写法:一种不需要准备,拿到数据就开始算;另一种先整理出一份索引,之后每次查询都很快。只查一次时前者更省;查十万次时后者可能反超。

"哪个更快"这个问题缺少主语。完整的问题至少包含四项:输入规模、查询次数、设备、允许误差。四项定了,算法之间才有共同的比较标准。

预计用时:30 分钟。本篇说明这门课的方法、契约、路线与交付物,并从《揭开黑盒》第二章的 章末接口 接续。

一个可以量化的分歧

一份 n 项数据,任务是回答 q 次"某个数在不在里面",每次返回是否。

以 n = 100000、每次二分 17 次比较计:

查询次数 q方案 A 比较次数方案 B 比较次数更省的一方
1100000约 1.7×10⁶(含排序)A
101.0×10⁶约 1.7×10⁶A
1001.0×10⁷约 1.7×10⁶B
1000001.0×10¹⁰约 1.7×10⁶B

分歧不在"谁更快",在转折点的位置。这个位置依赖 n、q、排序与比较的常数因子,是可以测的,不需要争。

两种解释可以同时成立:

一次实验能区分它们:固定 n 与数据,只改 q,记录两条曲线的交点。

契约:每单元交付八个字段

沿用 算法课堂接续任务单。八项缺一不算交付:

字段要求
输入与输出规模、取值范围、输出含义
正确性独立参考或可检查性质;误差上限;非法输入的处理
基线实现可运行、有版本号的起点
候选变化只改公式、顺序、表示、预处理、并行、近似中的一项
成本账本计算、搬运、准备、存储、同步、维护分开记
实验设计固定什么、改变什么、什么观察会反驳预测
证据原始样本、运行环境、计时边界、失败路径
未解决的问题哪一项原因尚未排除,下一步打开哪一层

两条要求需要单独说明。

正确性一栏不能写"跑过几个样例看起来对"。 有效内容只有两类:一个独立参考(暴力解、整数精确解、另一份实现的输出),或一条可检查性质(输入的排列不变性、已知的恒等式、边界值)。没有这两类之一,后面所有计时都不成立——一个算错的程序可以跑得很快。

成本账本不是只记运算次数。 六项要分开:计算(乘加次数)、搬运(内存与网络访问)、准备(预处理)、存储(额外数据结构)、同步(并行时的协调)、维护(代码与状态变更的复杂度)。常见错误是只记第一项,于是漏掉"运算少但准备贵"的反例。

三条规矩

规矩违反后的症状
先有独立参考,再比较快慢性能曲线正确,答案错误
一次只改一个条件无法把差异归因到算法
写下尚未排除的原因结论看似确定,实为未被追问

第三条对应《揭开黑盒》贯穿全书的表述:"我现在还不知道它为什么这样,但我知道下一步可以怎样查。" 这门课不要求每单元都有定论,要求每个结论都标注它的适用范围。

六条路线

出发的问题新增的方法
改循环与分块仍不够分治、渐近复杂度、交叉规模
重复查询越来越多排序、查找、哈希、树、摊还分析
数据大量为空或有结构稀疏表示、图表示、压缩、局部性
长计算链挡住并行归约、扫描、依赖图、通信代价
迭代如何更快接近答案求根、优化、数值稳定性、收敛条件
近似能换来什么随机化、采样、误差界、概率保证

这是问题清单,不是目录保证。每单元从一个具体问题进入,交付一套方法、一份证明、一次可复核的实验。

从哪里开始

第一单元接续 assets/math-lab/ 的矩阵乘法。改循环顺序与分块之后,乘法次数没有变,因此存在天花板。下一步不是继续调块大小,而是减少乘法次数本身——这会引入分治,以及实践里绕不开的一个量:交叉规模(crossover point),即两种做法耗费相等的规模阈值。

开篇提出的"转折发生在第几次"是它的一个实例。第一单元要回答的是:这个阈值由什么决定,怎样测出来,什么条件下会移动。

与后续课程的接口

《揭开黑盒》计划转向"给现实中的物品注入灵魂"。一个会感知、保持状态、作出判断并反馈的物品,必须回答三问:该算多准、最多等多久、算不出来时返回什么。这三问的依据来自本课程——精度、延迟与成本如何随算法改变。

本课程的产出不是一份算法排名,而是一套判断:面对具体任务,说清为什么选这个算法,以及别人给出什么条件时会改选。