动态规划
动态规划是解决多阶段决策问题常用的最优化理论。
动态规划通过将问题细分为一系列子问题,而隐含地探查了所有可行解的空间,我们可以从某种程度上把动态规划看做接近暴力搜索边缘的危险操作。
动态规划适合求解多阶段决策问题的最优解,也可用于含有线性或非线性递推关系的最优问题,但是这些问题都必须满足最优化原理和子问题的“无后向性”。
动态规划两种特性:
最优化原理:
最优化原理就是问题的最优子结构的性质。如果一个问题的最优子结构是不论过去状态和决策如何,对前面的决策所形成的状态而言,其后的决策必须构成最优策略。
无后向性:
无后向性就是对各个阶段的子问题确定以后,对于某个特定阶段的子问题来说,它之前的各个阶段的子问题的决策只影响该阶段的决策,对该阶段之后的决策不产生影响。
基本思想:
动态规划作为解决多阶段决策最优化问题的一种思想,它没有具体的实现模式,可以用带备忘录的递归方法实现,也可以根据堆叠子问题之间的递推公式用递推的方式实现。
从算法设计的角度分析,使用动态规划一般需要4个步骤,分别是定义最优子问题、定义状态、定义决策和状态转化方程、确定边界条件
动态规划法例子:字符串的编辑距离
两个字符串的相似度定义为:一个字符串转化成另一个字符串时需要付出的代价。转换可以用插入、删除和替换三种编辑方式。
递归算法实现:
public int EditDistance1(String src ,String dest){
if( src.length() == 0 || dest.length() == 0 ){
return Math.abs(src.length() - dest.length());
}
if( src.charAt(0) == dest.charAt(0) ){
return EditDistance1(src.substring(1),dest.substring(1));
}
int edIns = EditDistance1(src,dest.substring(1))+1;
int edDel = EditDistance1(src.substring(1),dest)+1;
int edRep = EditDistance1(src.substring(1),dest.substring(1))+1;
return Math.min(Math.min(edIns, edDel), edRep);
}
递归算法的时间复杂度是O(3`n),三的n次方,指数级别。
动态规划算法实现:
public int EditDistance1(String src ,String dest){
if( src.length() == 0 || dest.length() == 0 ){
return Math.abs(src.length() - dest.length());
}
if( src.charAt(0) == dest.charAt(0) ){
return EditDistance1(src.substring(1),dest.substring(1));
}
int edIns = EditDistance1(src,dest.substring(1))+1;
int edDel = EditDistance1(src.substring(1),dest)+1;
int edRep = EditDistance1(src.substring(1),dest.substring(1))+1;
return Math.min(Math.min(edIns, edDel), edRep);
}
启动程序与测试语句:
public int EditDistance1(String src ,String dest){
if( src.length() == 0 || dest.length() == 0 ){
return Math.abs(src.length() - dest.length());
}
if( src.charAt(0) == dest.charAt(0) ){
return EditDistance1(src.substring(1),dest.substring(1));
}
int edIns = EditDistance1(src,dest.substring(1))+1;
int edDel = EditDistance1(src.substring(1),dest)+1;
int edRep = EditDistance1(src.substring(1),dest.substring(1))+1;
return Math.min(Math.min(edIns, edDel), edRep);
}
下面是我的测试图: