Skip to content

方法Method

记忆化

Memoization

缓存递归子问题结果以避免重复计算的自顶向下动态规划技术。

形式陈述 ​

记忆化把递归函数对参数状态 x 的结果存入表 M[x]。一次调用先查表:有结果就返回;没有结果才递归求依赖项,并在计算完成后写入 M[x]。这里的“尚未缓存”要与合法结果(例如 0)区分。本页讨论结果只依赖状态、且从目标可达的依赖图有限无环的递推,并要求各状态的依赖可有效枚举、基例与组合计算均终止。假定缓存不淘汰已完成结果。若共有 N 个可达状态,一次性预处理成本为 I,每个状态首次求值的全部本地工作(包括基例或组合计算、表项初始化、键和值的存储)连同它引出的所有调用与查表成本合计至多 C≥1,则总时间为 O(I+NC)。缓存按需分配,且每个键、结果和表项元数据都占常数空间时,缓存为 O(N);另计递归栈及预处理工作区。它是自顶向下动态规划;在相同递推和基例下,与按依赖次序填表得到相同结果,但访问状态集合、栈深与常数开销可以不同。

直觉

递归树中许多分支会反复询问同一个子问题;记忆化把已经求出的输入—输出对缓存起来,将递归树折叠成状态 DAG,使同一状态再次出现时直接复用、每个节点只真正求值一次。它保留自顶向下、按需展开的控制流,只计算从初始问题可达的状态;代价是递归开销、哈希或数组查表和缓存空间。正确性依赖函数在同一状态上结果稳定,若状态遗漏了影响结果的环境,缓存会复用错误答案。

记忆化把递归树折叠成缓存 DAG
例子与边界

令 F(0)=0,F(1)=1,F(k)=F(k−1)+F(k−2)。求 F(4) 时,先递归求 F(3),它再求 F(2);基例给出 F(2)=1,写入缓存。返回上层得到 F(3)=2 后,F(4) 的另一个依赖 F(2) 已经存在,可以直接读出,于是 F(4)=3。图中重复出现的调用分支因此合并成同一状态,而不是同一计算仍执行多次。

求 F(n) 只会访问 0,…,n。每个状态最多做一次加法,因而是 O(n) 次算术运算、O(n) 个缓存项和最坏 O(n) 栈深。这里把加法视作单位成本;若要求任意大整数的精确值,还要计算随 n 增长的位数成本。缓存消除了重复求值,并没有缩短最初向下递归的链。

状态键必须包含所有影响答案的信息。区间问题只缓存左端点而遗漏右端点,会把不同区间合并;网格路径只用 (i,j) 作键,要求障碍布局在这次求解期间固定。布局改变后应失效缓存或把布局版本纳入键。随机性、副作用和外部环境同样不能在没有语义说明时被缓存隐藏。

无环本身还不足以保证终止:状态 x 若总要先求 x+1,依赖链没有环,却永远到不了基例。有限可达图排除了这种情况。

有环依赖需要另行处理。例如 A 要先算 B,B 又要先算 A,两个结果都尚未写入缓存,普通记忆化仍会无限递归。访问中标记可以发现环,却不能自动算出环上的答案;若问题具有固定点语义,还需专门的迭代或图算法。

缓存淘汰对纯函数可以保持结果正确,却会让被删状态再次计算,因此不能继续无条件宣称“每个状态只计算一次”。在状态很多或结果很大时,应同时比较缓存空间与重算成本。

推论与应用

解析中的PEG有序选择先规定唯一识别结果,Packrat再以“规则、输入位置”为键,同时缓存成功与失败。固定良构文法、结果不依赖外部可变状态且每格工作有界时,才能由线性表项数推出线性时间;需要保留CFG多种语法树时,不能把所有结果硬压成一个成功终点。记忆化也用于图搜索、游戏求值和最优化递推,关键仍是正确界定子问题及其全部结果。

它是 动态规划 的自顶向下实现,函数 的输入构成状态键。与表格法相比,记忆化适合稀疏可达状态和复杂转移;解析、博弈搜索、递归下降与 DAG 计算都可通过缓存把重叠子问题降为一次求值。

在上述有限无环模型中,缓存不淘汰时,记忆化保证每个实际到达状态计算一次;若状态空间本身为全部子集,便得到子集 DP的指数上界,而非自动多项式。树宽 DP在树分解 bag 上缓存边界赋值,复杂度指数集中在宽度。自顶向下是否访问更少状态取决于实例可达性,最坏仍需与完整状态 DAG 比较,不能把“有缓存”当复杂度证明。

参考资料
  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Introduction to Algorithms, 4th ed., MIT Press, 2022,Ch. 14 “Dynamic Programming”。

  • Jon Kleinberg and Éva Tardos, Algorithm Design, Pearson, 2005,Ch. 6 “Dynamic Programming”。

  • Erik Demaine and Srini Devadas, MIT 6.006 Introduction to Algorithms, Fall 2011,Lecture 19: Dynamic Programming I — Fibonacci, Shortest Paths。

关系图谱7 个相邻概念 · 3 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
分类位置

上位 / 更一般

下位 / 直接特例

暂未标注直接特例。

类型化关系