编辑距离
转自:http://www.gdcp.cn/jpkc/sjjg/app/jm/edit_distance/problem.htm
问题描述
当一个智能终端将一行正文更新,并用新的目标串y[1..n]来替换现存的源串X [l..m]时,可有几种方式来做这种变换:源串中的单个字符可被删除(delete);被替换 (replace);或被复制到目标串中去(copy);字符也可被插入(insert);源串中的两个相邻字符可进行交换并复制到目标串中去(twiddle);在完成其它所有操作之后,源串中余下的全部后缀就可用删至行末的操作删除(kill)。
例如,将源"algorithm"转换成目标串"altruistic"的一种方法是采取下面的操作序列:
操作 目标串 源串 copy a a lgorithm copy l al gorithm replace g by t alt orithm delete o alt rithm copy r altr ithm insert u altru ithm insert i altrui ithm insert s altruis ithm twiddle it into ti altruiti hm insert c altruitic hm kill hm altruitic
要达到这个结果还可有其它一些操作序列。操作delete,replace,copy,insert,twiddle和kill中每一个都有一个相联系的代价cost。例如
cost(delete)=3;
cost(replace)=6;
cost(copy)=5;
cost(insert)=4;
cost(twiddle)=4;
cost(kill)=被删除的串长*cose(delete)-1;
一个给定的操作序列的代价为序列中各操作代价之和。例如上述操作序列的代价为
3*cost(copy)+cost(replace)+cost(delete)+3*cost(insert)+cost(twiddle)+cost(kill)
=3*5+6+3+3*4+4+2*3-1
=45
给定两个序列x[1..m],y[1..n]和一些操作代价集合,X到Y的编辑距离为将X转化为Y的最"便宜"的转换序列的代价。请给出一个算法来找出x[1..m]至y[1..n]的编辑距离,并输出一个最优转换序列。
参考解答
我们按目标串长递增的顺序进行变换:先变换Yn,再变换Yn-1Yn ,…直到变换至Y1Y2…Yn为止。
设
C1 —— delete操作的代价; C2 —— replace操作的代价;
C3 —— copy操作的代价; C4 —— insert操作的代价;
C5 —— twiddle操作的代价;C6 —— kill操作的代价,其值为当前源串长*C1-1;
c[i,j] —— 将Xj…Xm变换至Yi…Yn的编辑距离。变换的可能方式有五种:
- delete操作:删除源串中的Xj;
- replace操作:源串中的Xj被替换到目标串的Yi位置;
- copy操作:源串中的Xj被拷贝到目标串的Yi位置,使得Yi=Xj;
- insert操作:插入一个字符至目标串的Yi位置;
- twiddle操作:XjXj+1交换并复制到目标串的YiYi+1位置,使得Yi=Xj+1,Yi+1=Xj;
要使c[i,j]最小,必须使得Xj…Xm与Yi…Yn中除参与变换的字符外的子串间的变换代价最小:即delete操作前Xj+1…Xm变换至Yi…Yn的代价和要最小;replace或copy操作前Xj+1…Xm变换至Yi+1…Yn的代价和最小;insert操作前Xj…Xm变换至Yi+1…Yn的代价和要最小;twiddle操作前Xj+2…Xm变换至Yi+2…Yn的代价和要最小。我们还不可能知道究竟使用哪一种操作可得出Xj…Xm至Yi…Yn的编辑距离,因此必须比较五种操用的代价和,从中找出代价和最小的一种。
由此得出c[i,j]的递归式:
c[i,j]=min{c[i,j+1]+C1,c[i+1,j+1]+C2,c[i+1,j+1]+C3,c[i+1,j]+C4,c[i+2,j+2]+C5 |(i<n)∧(j<m)∧(yi=xj+1)∧(yi+1=xj)}
我们专门设置了一个记忆表k[i,j],以记下c[i,j]最小时的操作序号Ci(1≤i ≤5)。
显然c[i,j]的递归边界有三个:
- c[i,m+1]=(N-i+1)*C4; k[i,M+l]=4 (1≤i ≤N) ,即源串空时,要变换目标串Yi…Yn必须进行N-i+1次insert操作。
- c[n+1,i]=(M-i+1)*C1-1;k[n+1,i]=6;即目标串空时,进行一次kill操作删除源串中余下的全部后缀。kill的代价为删除后缀Xi…Xm(M-i+1个字符)的delete代价减1。
- 3.c[n+1,m+1]=0;即源串和目标串空时的编辑距离为0。
由c[i,j]的递归式可以看出,求c[i,j]最优解的子问题,包含了求c[i..n,j+1..M]的子子问题,要使c[i,j]的值最优,必须保证这些子子问题的值最优,因此具有“最优于结构”和“重叠子问题”两个要素,可用动态规划解决。我们从变换Yn字符出发,按目标串长度递增的顺序自下而上地依次计算c[n,1..m]→c[n-1,1..m]→…→c[1,1..m],充分利用了重叠子问题,使得算法效率显著提高。