《算法分析与设计》
课程设计报告
题 目:完成最小编辑距离问题的求解
专 业: 数据科学与大数据技术
班 级: 19 大数据本科二班
姓 名: 孙晓云 王菲 于佩颖
指导教师: 湛维明
2021年06月07日
目录
一、问题分析
1.1 问题描述
编辑距离是针对二个字符串的差异程度的量化量测,量测方式是看至少需要多少次处理才能将一个字符串变成另一个字符串。编辑距离可以用在自然语言处理中,最短编辑距离算法,用于对用户输入的查询进行纠错,从而优化查询结果。例如拼写检查可以根据一个拼错的字和其他正确的字的编辑距离,判断哪一个(或哪几个)是比较可能的字。
具体点来说,什么是最短编辑距离呢?假定有两个字符串l1和l2,允许对字符串进行以下三种操作:
1. 插入一个字符
2. 删除一个字符
3. 替换一个字符
将字符串l1转换成字符串l2的最少操作次数就是字符串l1和字符串l2之间的最短编辑距离。两个字符串的最短编辑距离越短,意味着两个字符串越相似。
1.2 基本要求
给定两个序列,假设可以有插入、替换和删除(单个字符)三种编辑操作,设计算法求出这两个序列的最小编辑距离。
- 我们已经知道串l1,串l2之间修改有三种操作:即修改、删除、插入。
2.因为我们是要求最小的编辑距离,所以转移的时候,要比较这三种操作的最小值,即min(step[i-1][j-1],step[i-1][j]+d,step[i][j-1]+d)。
3.修改是什么意思:我们要看l1的第 i 个字符要不要修改成l2的第 j 个字符,如果这两个字符是相同的,那么就要改0个字符,否则,就要改 1 个字符,所以,这个 里面的d就是要修改的字符的个数的意思
4.什么是删除?这里我们要把l1的第i个字符给删除,那么这个时候的编辑距离就是d[i-1,j]+d的距离
5.同理,什么是插入呢?插入就是我们把l2的第 j 个字符插入到 l1 的 第 i 个字符前面,那么这个时候的编辑距离就是step[i,j-1]
6.之后,只要比较这三种操作哪一种花费最小即可,所得即为需要求解的最小编辑距离。
1.3 算法分析
最小编辑距离的求解问题可以用递归或者动态规划的方法来进行求解,但是我们都知道递归会存在大量的重复计算,因此,显然不是最优解。在这里,我们可以利用动态规划的方法来进行求解。
因此,最终应用动态规划的方式来求解。
动态规划的基本思想与分治法类似,也是将待求解的问题分解成若干份的子问题,先分别解决好子问题,然后从子问题中得到最终解。但动态规划中的子问题往往不是相互独立的,而是彼此之间有影响,因为 些子问题可能要重复计算多次,所以利用动态规划使这些子问题只计算一次。将字符串A变换为字符串所用的最少字符操作数称为字符串A到B的编辑距离。
二、设计思路
2.1 描述解决方案
首先使用def定义mindistance函数,设字符串a对应A[i],字符串b对应B[j],对于A[i]和B[j]的比较情况不同进行讨论。使用range()函数遍历字符串A,B中的所有元素。
比较A[i]和B[j]的末位字符,当A[i]==B[j]时,对末位字符不需要进行编辑,此时d=0,step[i][j]=step[i-1][j-1];当A[i]!=B[j]时,需要对其中之一的末位进行编辑,此时d=1,step[i][j]=min(step[i-1][j],step[i][j-1],step[i-1][j-1])+d;如果A==null,step[0][j]=j;如果B==null,step[i][0]=i。
最后以print()函数输出。
表2-1
2.2 功能结构框图
图2-1
三、解决方案
3.1 设计问题
编写代码时对于表达两个字符串之间的关系,以及两个字符串相比较的不同情况下如何设置代码存在困难。
3.2 解决方案
利用动态规划的思想,分析两个字符串,比较两字符串之间的关系和改变方法,逐步减少变量,将影响结果的因素集中在更少的步骤,从而解决问题。
动态规划的基本思想是将待求解的问题分解成若干份的子问题,先分别解决好子问题,然后从子问题中得到最终解。但动态规划中的子问题往往不是相互独立的,而是彼此之间有影响,因为一些子问题可能要重复计算多次,所以利用动态规划使这些子问题只计算一次。将字符串A变换为字符串所用的最少字符操作数称为字符串A到B的编辑距离。
四、关键技术
4.1 求解特色
4.1.1 基本思想
动态规划的基本思想:动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。
动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。
我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。
具体的动态规划算法多种多样,但它们具有相同的填表格式。
4.1.2 方法特点
最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
无后效性。即子问题的解一旦确定,就不再改变,不受在这之后、包含它的更大的问题的求解决策影响。
子问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。
4.1.3 基本过程
大致可以通过以下四步进行解决。
- 划分状态,即划分子问题。
- 状态表示,即如何让计算机理解子问题。
- 状态转移,即父问题是如何由子问题推导出来的。
- 确定边界,确定初始状态是什么?最小的子问题?最终状态又是什么。
4.2 关键技术
图4-1
图4-2
五、算法测试
图5-1
图5-2
在这一次的课程设计中,我们经历了确定小组,讨论选题,编写代码,调试程序,撰写设计报告,制作PPT一系列过程。小组成员不约而同,一拍即合,顺利的结为了一个学习小组,经历对多个选题的对比分析,我们考虑了题目的难度、趣味等方面,结合自身对于知识的把握,选择了我们都比较感兴趣的题目:完成最小编辑距离问题的求解。编写代码时,我们一起分析了题目要求,根据题目理解,查阅大量资料来完成代码的编写。其中遇到了许多问题,对于题目的理解,代码的实现不不能很顺利地完成,通过网络上的资讯,在其中收益颇多。最终小组合作完成设计报告的撰写,根据报告和设计内容完成PPT的制作用于演示。
Python的学习已经是两个学期之前的课程,在计算机二级考试之前只进行了简单的复习,并不能完美的应用。对于编写代码掌握的并不是很熟练,对于语句的结合,结构问题,进行了深入的思考。对于动态规划也不能很好的应用。在课程设计开始之前,我们首先对于学过的内容进行复习,相应的知识有了更好地理解之后才开始进行下一步。通过网络,我们查阅了大量资料,关于概念知识类的内容,以及编码前辈们对于这一问题的理解和思路,进行参考以及改进,对于题目的实现更进一步。最重要的是大家互相鼓舞,面对困难不轻易退缩,而是一起思考,想办法解决,我们共同进步。在这一次课程设计中,我们学到的不仅仅是如何解决题目所要求的这一问题,同时我们收获更多的是面对一个没有把握的课题时,如何去了解他,思考他,深入解决他。我们学会了面对问题的态度以及解决问题的思维。在这一次的作业中,我们受益颇多。
[2]知乎韩宜飞专栏第9章《动态规划》
[3]CSDN博主我就是嗨嗨嗨的转载《动态规划的特征》
[4]代码参考自:https://blog.csdn.net/qq_33085753/article/details/86595452