动态规划 求解 Minimum Edit Distance

时间:2021-08-01 15:54:00

自然语言处理(NLP)中,有一个基本问题就是求两个字符串的minimal Edit Distance, 也称Levenshtein distance。受到一篇Edit Distance介绍文章的启发,本文用动态规划求取了两个字符串之间的minimal Edit Distance. 动态规划方程将在下文进行讲解。 


1. what is minimal edit distance?

简单地说,就是仅通过插入(insert)、删除(delete)和替换(substitute)个操作将一个字符串s1变换到另一个字符串s2的最少步骤数。熟悉算法的同学很容易知道这是个动态规划问题。 

其实一个替换操作可以相当于一个delete+一个insert,所以我们将权值定义如下:

I  (insert):1

D (delete):1

S (substitute):2


2. example:

intention->execution

Minimal edit distance:

delete i ; n->e ; t->e ; insert c ; n->u 求和得cost=8

3.calculate minimal edit distance dynamically
思路见注释,这里D[i,j]就是取s1前i个character和s2前j个character所得minimal edit distance

三个操作动态进行更新:

D(i,j)=min { D(i-1, j) +1, D(i, j-1) +1 , D(i-1, j-1) + s1[i]==s2[j] ? 0 : 2};中的三项分别对应D,I,S。(详见我同学的博客


[cpp] view plaincopy
  1. /* 
  2.  * minEditDis.cpp 
  3.  * 
  4.  *  @Created on: Jul 10, 2012 
  5.  *      @Author: sophia 
  6.  *  @Discription: calculate the minimal edit distance between 2 strings 
  7.  * 
  8.  *  Method : DP (dynamic programming) 
  9.  *  D[i,j]: the minimal edit distance for s1的前i个字符和 s2的前j个字符 
  10.  *  DP Formulation: D[i,j]=min(D[i-1,j]+1,D[i,j-1]+1,D[i-1,j-1]+flag);//其中if(s1[i]!=s2[j])则flag=2,else flag=0; 
  11.  * 
  12.  */  
  13.   
  14. #include"iostream"  
  15. #include"stdio.h"  
  16. #include"string.h"  
  17. using namespace std;  
  18.   
  19. #define N 100  
  20. #define INF 100000000  
  21. #define min(a,b) a<b?a:b  
  22.   
  23. int dis[N][N];  
  24. char s1[N],s2[N];  
  25. int n,m;//length of the two string  
  26.   
  27.   
  28. int main()  
  29. {  
  30.     int i,j,k;  
  31.     while(scanf("%s%s",&s1,&s2)!=EOF)  
  32.     {  
  33.         n=strlen(s1);m=strlen(s2);  
  34.         for(i=0;i<=n+1;i++)  
  35.             for(j=0;j<=m+1;j++)  
  36.                 dis[i][j]=INF;  
  37.         dis[0][0]=0;  
  38.   
  39.         for(i=0;i<=n;i++)  
  40.             for(j=0;j<=m;j++)  
  41.             {  
  42.                 if(i>0) dis[i][j] = min(dis[i][j],dis[i-1][j]+1); //delete  
  43.                 if(j>0) dis[i][j] = min(dis[i][j],dis[i][j-1]+1);//insert  
  44.   
  45.                 //substitute  
  46.                 if(i>0&&j>0)  
  47.                 {  
  48.                     if(s1[i-1]!=s2[j-1])  
  49.                         dis[i][j] = min(dis[i][j],dis[i-1][j-1]+2);  
  50.                     else  
  51.                         dis[i][j] = min(dis[i][j],dis[i-1][j-1]);  
  52.                 }  
  53.             }  
  54.   
  55.         printf("min edit distance is: %d\n",dis[n][m]);  
  56.     }  
  57.     return 0;  
  58. }  

运行结果:


intention
execution
min edit distance is: 8
abc
acbfbcd
min edit distance is: 4
zrqsophia
aihposqrz
min edit distance is: 16


Reference: 

1. https://www.coursera.org/course/nlp

2. http://blog.csdn.net/huaweidong2011/article/details/7727482