动态规划之最小编辑距离问题

       先说点题外话,早上同学给我了一套卷子,让我做,他对象的机试题,第一题是求点队中的最小距离点对,没说数据量,那肯定直接暴力就行了(有给分点,正确输入给5分,什么什么给五分),或者分治算法(编程之美里的);第二题是替换字符串;第三题是求给出的四边形的面积,逼着认为这个不能用海伦公式,因为可能是凹四边形,需要向量公式。题目如此简单,这就是北邮,这种题目能考察出来水平么,哎,或许真是考研的学生水平都不高,只是会看书会考试而已。

       昨晚吃饭,本科的张同学惊讶于我说的体重,找了个诊所,直接进去测,发现真的是70kg,本科时候我从来不到60kg。

一、问题来源

       看云计算的书,提到微博去重,因为数据量巨大,需要先Hash再MapReduce,那么如何Hash把相似的微博尽可能放到同一个桶里呢?用哪个Hash呢,作者提出了局部敏感Hash算法,中间的距离度量函数可以使用编辑距离(Edit Distance),但是编辑距离右脚Levenshtein莱温斯坦距离,即LD,写到这,笔者突然想到,ED距离是不是就是编辑距离,原来我认为是欧几里得距离。哈哈,这真是“文章本天成,妙手偶得之”。

       我查了资料发现编辑距离在NLP(神经语言程序学)中应用广泛。

二、问题分析

       下面资料,来自北大,这真是人才的摇篮,我不知道我咋找到这个资料的,记得以前这类资料也都是pdf链接,现在依旧。而且笔者发现,他们的资料更加细致,可能出现的问题都做了标注,这些问题包括读者能想到的和不能想到的,很有启发性和警醒作用,为何说警醒,因为你突然发现自己的误解,那么就不会那么自满了;北大和我校的区别,就像高中老师和大学老师的区别。此偶之愚见也。

       1.引入

       源文:She is a star with the theatre company.

       机器译文:她 是 与 剧院 公司 的 一 颗 星。

       参考译文:她 是 剧团 的 明星。
            imageimage

 

 

       2.算法分析

             imageimage

 

       看完接下来的资料,我发现,Dijkstra算法从后往前推结果,编程却是从前往后,但是不理解,现在想来,这是必然的。因为d[i][j]=min{d[i-1][j-1]……},结果是d[m][n]不算出前面的怎么计算出d[m][n],从前往后是递推,从后往前类似递归,哈哈。

       参考资料:http://ccl.pku.edu.cn/doubtfire/Course/Computational%20Linguistics/contents/Minimum%20Edit%20Distance.pdf

 

三、算法实现

       1.Java版本

        上面算法的变形实现,或者直接写个min(a,b,c)函数就是上面的算法实现了。

public class MinimumEditDistance { public static int minEditDistance(String dest, String src) { int[][] f = new int[dest.length()+1][src.length() + 1]; f[0][0] = 0; for (int i = 1; i < dest.length() + 1; i ) { f[i][0] = i; } for (int i = 1; i < src.length() + 1; i ) { f[0][i] = i; } for (int i = 1; i < dest.length() + 1; i ) { for (int j = 1; j < src.length() + 1; j ) { // 替换的开销 int cost = 0; if (dest.charAt(i - 1) != src.charAt(j - 1)) { cost = 1; } int minCost; if (f[i - 1][j] < f[i][j - 1]) { minCost = f[i - 1][j] + 1; } else { minCost = f[i][j - 1] + 1; } if (minCost > f[i - 1][j - 1] + cost) { minCost = f[i - 1][j - 1] + cost; } f[i][j] = minCost; } } return f[dest.length()][src.length()]; } public static void main(String[] args) { System.out.println(minEditDistance("kindle", "ainelw")); } }

       2.C/C++版本

#include #include char s1[1000],s2[1000]; int min(int a,int b,int c) { int t = a < b ? a : b; return t < c ? t : c; } void editDistance(int len1,int len2) { int** d=new int*[len1+1]; for(int k=0;k<=len1;k++) d[k]=new int[len2+1]; int i,j; for(i = 0;i <= len1;i++) d[i][0] = i; for(j = 0;j <= len2;j++) d[0][j] = j; for(i = 1;i <= len1;i++) for(j = 1;j <= len2;j++) { int cost = s1[i] == s2[j] ? 0 : 1; int deletion = d[i-1][j] + 1; int insertion = d[i][j-1] + 1; int substitution = d[i-1][j-1] + cost; d[i][j] = min(deletion,insertion,substitution); } printf("%d\n",d[len1][len2]); for(int k=0;i<=len1;k++) delete[] d[k]; delete[] d; } int main() { while(scanf("%s %s",s1,s2) != EOF) editDistance(strlen(s1),strlen(s2)); }
posted @ 2015-03-15 11:16  加拿大小哥哥  阅读(3799)  评论(2编辑  收藏  举报