Skip to content

方法Method

势能法

施工中 · 内容逐步修订

Potential method

用数据结构状态势函数的增量调整单步记账,以控制操作序列的总成本。

形式陈述 ​

势能法是摊还分析的一种具体方法:为数据结构的每个状态 Di 指定一个实值函数 Φ(Di)。先采用最常见的约定,要求全部可达状态的势非负。其中 D0 为初态,ci 为从 Di−1 变成 Di 的实际成本,定义摊还成本为

c^i=ci+Φ(Di)−Φ(Di−1).

势增加时,本步除了支付实际工作还要预存信用;势下降时,可以取出过去的信用支付实际工作。求和后中间状态各出现一次正号和一次负号,故

∑i=1mci=∑i=1mc^i−Φ(Dm)+Φ(D0)≤∑i=1mc^i+Φ(D0).

若初始势为零,总摊还成本便直接控制总实际成本。单步摊还成本甚至可以为负;需要有下界的是终态势,不能让一串操作不断从无底的账户借钱。

直觉

设计势函数时,可以先问:昂贵操作会消耗哪一种积累下来的结构?若一次批量删除会清掉许多元素,就让这些元素事先各携带一点信用;若一次重建会清掉许多待处理标记,就让势记录标记数。势函数不是物理能量,而是把将来要付的工作对应到当前状态上,使昂贵操作发生时恰有足够的势下降。

势能变化平滑实际操作成本
例子与边界

动态数组可令势与长度、容量的差额相关,让普通追加积累的势支付下一次整体复制;具体扩缩阈值和常数摊还界集中在对应条目。二进制计数器可令势为 1 的位数:翻转许多 1 为 0 的昂贵递增同时大幅降低势。栈的 multipop(k) 则取势为当前元素数,弹出每个元素的实际成本由势能下降抵消。

以栈为例,先只数元素写入与删除:push 成本为 1,批量弹出 r 个元素的成本为 r;函数调用和停止检查另加常数。先试 Φ(D)=α|D|:push 的摊还成本是 1+α,弹出 r 个元素则为 (1−α)r。要让后者不随 r 增长,必须选 α≥1;取最小的 α=1,就得到 push 成本 2、批量弹出成本至多一个常数。这展示了势的系数如何由所需不等式反推出来。

从空栈连续压入三个元素,再执行一次弹出三项,实际成本依次为 1,1,1,3,势依次为 0→1→2→3→0,摊还成本为 2,2,2,0。总实际与总摊还成本都是 6。若从已有三个元素的栈直接开始弹出,摊还成本仍为 0,实际却是 3;差额恰由初始势 Φ(D0)=3 支付,不能在总界中省略。

二进制计数器的完整逐位计算见摊还分析。其昂贵进位会消耗末尾的 1,所以适合数 1 的个数;若改用“位串的数值”,递增反而总使势增加 1,无法抵消长进位。非负性只保证账本合法,能否得到有用的界还取决于势与操作结构是否匹配。

非负势是方便的充分条件,并非唯一合法选择。更一般地,只要所有可能终态满足 Φ(Dm)≥L,总成本就不超过总摊还成本加 Φ(D0)−L;这个差额须由已声明的初态与模型统一控制。给势整体加一个常数不改变任何单步摊还成本,也不改变这个差额。随意挑一个能无限下降的函数,则可能靠不断透支制造虚假的低成本。摊还界是任意操作序列上的确定总界,不等于随机输入期望。

推论与应用

势能法建立在摊还分析与状态上的势函数之上。先让势函数表达需要长期维护的不变量,再逐类核对操作如何改变它,便能系统地设计证明并界定任意长操作序列的总成本,而不是只解释某一个昂贵步骤。

伸展树把辅助树形状编码进势,Fibonacci 堆用根数与标记节点数为延迟合并和级联切断记账;两页分别给出具体势函数,本页不重复其旋转或堆操作。栈的批量弹出、动态数组和并查集也使用同一望远镜机制,会计法则可视为把总势拆成存放在各对象上的 credits。这样的摊还结论控制操作序列总成本,却不承诺每次操作的尾延迟。

算法分析中的“势”还有别的量词。竞争分析常令势比较在线算法与离线最优的两个状态,用单步不等式累积竞争比;乘法权重更新与Hedge跟踪总权重或对数配分函数,以界定累计 regret。它们都利用势的增量,却不把真实数据结构操作成本重新分摊,不能因此统称为摊还时间复杂度。

参考资料
  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Introduction to Algorithms, 4th ed., MIT Press, 2022,§16.3:势能法与摊还成本。
  • Cornell University, CS 3110 Lecture 20: Amortized Analysis, Fall 2010,“Potential (Physicist’s) Method”:初始势、非负势与望远镜求和。
关系图谱9 个相邻概念 · 3 类关系

拖动节点调整位置。

显示关系

显示:依赖

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

上位 / 更一般

下位 / 直接特例

暂未标注直接特例。

类型化关系