“Hirschberg 分解用前向、反向滚动行找出最优路径的中间穿越点,再递归恢复脚本。若应用规定只有插入和删除,并且差异很少,Myers 算法则按修改数扩展前沿,避免填满网格。前者主要节省重…”
形式陈述
编辑距离的网格动态规划可以只留两行算出距离,却通常依靠整张表回溯。Hirschberg 方法回答的是:不保存整张表,怎样仍找回一条最优对齐路径?
先以单位插入、删除、替换费用为例。对子问题
前者从左上角向中线推进,后者从右下角反向推进。选取使
空串子问题直接输出全部插入或删除。某一串只剩一个字符时,直接扫描另一串:若能找到相同字符,选最早的一个与它配对,其余插入或删除;找不到时,替换第一个字符并处理剩余部分。这个基例不分配一张细长的完整表。
直觉
任意从左上角到右下角的合法路径都要经过中间行。设最优路径在该行经过
这个等式就是切分证书。即使一条路径沿中间行走过多个格点,取其中任何一个都仍是合法切口;不要求每条路径只穿线一次。
普通分治往往先按输入大小切开,再处理两边。本方法必须先做两次分数计算,才能知道目标串应该在哪里切开。左右两块不是任意拼接:中线最小和保证至少存在一条全局最优路径经过共同角点。
例子与边界
两行数值怎样恢复删除位置
令 CAB,右半为 ACDA。对应目标串切点
| 0 | 1 | 2 | 3 | 4 | 5 | |
|---|---|---|---|---|---|---|
| 3 | 2 | 1 | 2 | 3 | 4 | |
| 1 | 1 | 1 | 2 | 3 | 4 | |
| 4 | 3 | 2 | 4 | 6 | 8 |
最小和为 CAB 对 AB,以及 ACDA 对 CDA。前一块再把 CAB 切成 C 与 AB,最优目标切点为零,直接删除第一个 C。后一块删除开头的 A,剩余 CDA 全部配对。连接后是
长度差已经给出至少两次删除的下界,因此结果与最小费用一致。更重要的是,每个具体删除位置都是由中线费用和递归基例恢复的,并未保留全部格点的父指针。
平局与费用方向
有多个最小和时,最左切点只是确定性约定,不保证与完整表“先对角”的回溯得到相同脚本。验收应比较生成的目标串和总费用。若费用不对称,交换源串与目标串以缩短行宽时,必须同时交换插入、删除的含义及费用;带方向的替换费用也要转置。单位对称费用下,转换回原方向时仍须把插入与删除互换,并交换每条操作记录中的源字符与目标字符;替换
反向计算同样是在原编辑图上求从中线到终点的费用。若费用依赖字符位置,简单反转字符串以后重新按新位置收费可能算错;应反向访问原图边,并保持原代价。具有仿射空隙费用的比对还要把“当前是否处于空隙”等状态带到切口,不能只用一个标量
推论与应用
时间为什么没有多乘一个对数
一层中线计算做
空间要把数组、栈和输出分开
开始时让较短串作为滚动行宽度。每个递归结点只保存整数范围,不复制子串;选定切点后先释放前向、反向及求和数组,再进入两个孩子。于是工作数组为
递归只平分源串,调用栈深度为
另外还有最多
这种用数值重算换取路径存储的思路适合长序列比对,也适合其他能沿分隔面组合前向与后向最优值的网格问题。关键不是矩形外观,而是切口状态足以连接两边,且连接后的费用确实可加。