编辑距离

转自: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-1Y,…直到变换至Y1Y2…Yn为止。

C1 —— delete操作的代价; C2 —— replace操作的代价;

C3 —— copy操作的代价;   C4 —— insert操作的代价;

C5 —— twiddle操作的代价;C6 —— kill操作的代价,其值为当前源串长*C1-1;

c[i,j] —— 将Xj…Xm变换至Yi…Yn的编辑距离。变换的可能方式有五种:

  1. delete操作:删除源串中的Xj
  2. replace操作:源串中的Xj被替换到目标串的Yi位置;
  3. copy操作:源串中的Xj被拷贝到目标串的Yi位置,使得Yi=Xj
  4. insert操作:插入一个字符至目标串的Yi位置;
  5. 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]的递归边界有三个:

  1. c[i,m+1]=(N-i+1)*C4; k[i,M+l]=4   (1≤i ≤N) ,即源串空时,要变换目标串Yi…Yn必须进行N-i+1次insert操作。
  2. c[n+1,i]=(M-i+1)*C1-1;k[n+1,i]=6;即目标串空时,进行一次kill操作删除源串中余下的全部后缀。kill的代价为删除后缀Xi…Xm(M-i+1个字符)的delete代价减1。
  3. 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],充分利用了重叠子问题,使得算法效率显著提高。

posted @ 2012-10-25 09:56  liangflying  阅读(286)  评论(0编辑  收藏  举报