32个重要算法之动态规划
来源:互联网 发布:淘宝网哪家手机店靠谱 编辑:程序博客网 时间:2024/06/05 03:55
我们知道动态规划是求解全局最优解的有效方法,一般来说能用动态规划算法求解的问题具有以下两个显著特称:
1)具有最优子结构,也就是说可以递归的定义最优解。
2)这些最优子结构存在很多的重叠,就像递归的求解斐波那契数列一样,会导致很多子问题求解不止一次,这将导致算法复杂度急剧增加。
下面结合具体例子进行说明:
此处选择的问题是编辑距离的求法,所谓的编辑距离,是如下定义的:
存在两个字符串A和B,对A进行四中操作:copy、delete、insert和replace,将A转换为B,在此过程中所进行的操作代价最小的过程就是编辑距离了。例如字符串algorithm可以经过上面
所说四中操作转换为altruistic。在进行求解的工程中,我们要对上述四种操作的代价进行定义,要注意的是copy和replace的代价要小于delete和insert,否则的话copy和replace操作都不
会使用。
下面利用动态规划算法进行求解:
首先,要找出最优子结构,假设原字符串为x[1,...,i],目标字符串为y[1,...,j],编辑距离定义为c[i,j],于是我们可以得到如下的公式:
c[i,j] = min{c[i-1,j]+cost(delete),c[i,j-1]+cost(insert),c[i-1,j-1]+cost(x[i]==y[j]?copy:replace)}
其中cost代表代价。这就是这个问题的最优子结构啦,之所以分成以上几种情况是因为,最优解 c[i,j]的上一步有四种可能,也就是上面所说的四种操作啦。我们可以明显的看到,如果要是
递归的求解上述问题会出现很多重叠子问题,例如,在递归求解c[i,j]时,我们就得求解四次 c[i-1,j-1]子问题。这也就是动态规划问题的第二个特征啦。
接下来,通过编程实现。
我们知道,从另一个方面看,动态规划问题就是一种自底而上填表的过程(dynamic programming中的programming就是用表格求解的意思)。接下来还是以上面的将algorithm转换
此处列去了如何得到结果的一些列操作,那个是保存在condition中的,只需递归的输出下就可以了 。
1)具有最优子结构,也就是说可以递归的定义最优解。
2)这些最优子结构存在很多的重叠,就像递归的求解斐波那契数列一样,会导致很多子问题求解不止一次,这将导致算法复杂度急剧增加。
下面结合具体例子进行说明:
此处选择的问题是编辑距离的求法,所谓的编辑距离,是如下定义的:
存在两个字符串A和B,对A进行四中操作:copy、delete、insert和replace,将A转换为B,在此过程中所进行的操作代价最小的过程就是编辑距离了。例如字符串algorithm可以经过上面
所说四中操作转换为altruistic。在进行求解的工程中,我们要对上述四种操作的代价进行定义,要注意的是copy和replace的代价要小于delete和insert,否则的话copy和replace操作都不
会使用。
下面利用动态规划算法进行求解:
首先,要找出最优子结构,假设原字符串为x[1,...,i],目标字符串为y[1,...,j],编辑距离定义为c[i,j],于是我们可以得到如下的公式:
c[i,j] = min{c[i-1,j]+cost(delete),c[i,j-1]+cost(insert),c[i-1,j-1]+cost(x[i]==y[j]?copy:replace)}
其中cost代表代价。这就是这个问题的最优子结构啦,之所以分成以上几种情况是因为,最优解 c[i,j]的上一步有四种可能,也就是上面所说的四种操作啦。我们可以明显的看到,如果要是
递归的求解上述问题会出现很多重叠子问题,例如,在递归求解c[i,j]时,我们就得求解四次 c[i-1,j-1]子问题。这也就是动态规划问题的第二个特征啦。
接下来,通过编程实现。
我们知道,从另一个方面看,动态规划问题就是一种自底而上填表的过程(dynamic programming中的programming就是用表格求解的意思)。接下来还是以上面的将algorithm转换
为altruistic为例进行说明。我们以横轴表示altruistic,以纵轴表示algorithm,所填的表格如下:
此处只是为了方便没有自己去画,而是通过程序进行打印而已。此处定义copy代价为1,delete的代价为2,所以第一列 和第一行会是那样。
下面给出主要的代码:
<span style="font-family:Courier New;font-size:14px;">static const int COPY_COST = 1;static const int REPLACE_COST = 1;static const int DELETE_COST = 2;static const int INSERT_COST = 2;enum status{DELETE,INSERT,COPY,REPLACE};void edit_distance(const std::string src,const std::string des){ size_t row = src.size(); size_t col = des.size(); std::vector<std::vector<size_t> >table(row,std::vector<size_t>(col)); std::vector<std::vector<status> >condition(row,std::vector<status>(col)); size_t i=0; while(i<row){ table[i][0] = i*COPY_COST; condition[i][0] = COPY; ++i; } size_t j = 1; while(j<col){ table[0][j] = j*DELETE_COST; condition[0][j] = DELETE; ++j; } for(i=1;i<row;++i){ for(j=1;j<col;++j){ size_t x = table[i][j-1]+INSERT_COST; size_t y = table[i-1][j]+DELETE_COST; size_t z = table[i-1][j-1] + (src[i]==des[j] ? (COPY_COST) : (REPLACE_COST)); if(x<y){ if(x<z){ table[i][j]=x; condition[i][j] = INSERT; } else{ table[i][j]=z; condition[i][j] = src[i]==des[j]?COPY:REPLACE; } } else{ if(y<z){ table[i][j]=y; condition[i][j] = DELETE; } else{ table[i][j]=z; condition[i][j] = src[i]==des[j]?COPY:REPLACE; } } } }}</span>
此处列去了如何得到结果的一些列操作,那个是保存在condition中的,只需递归的输出下就可以了 。
参考文献:
算法导论:192~221
此文出处:http://blog.chinaunix.net/uid-28311809-id-3874518.html
0 0
- 32个重要算法之动态规划
- 算法之动态规划
- 算法之动态规划
- 算法之动态规划
- 算法之动态规划
- 算法之动态规划
- 算法之动态规划
- 算法之动态规划
- 算法之动态规划
- 【算法】之动态规划
- 算法分析之动态规划
- 动态规划算法之二
- 算法实验之动态规划
- 算法实验之动态规划
- 算法设计之动态规划
- 常用算法之动态规划
- 算法笔记之动态规划
- 算法之动态规划法
- struts2核心
- Java图片处理开源框架
- wikioi m进制转十进制c
- jquery通过ajax向后台发送(checkbox)数组,并在后台接收,(发送的数据是checkedbox)
- Oracle rman 自动清理归档日志
- 32个重要算法之动态规划
- wikioi 二叉树最大高度和宽度
- JAVA 线程与锁
- 第九十五题(判断一字符串是不是对称的)
- TCP3次握手连接协议和4次握手断开连接协议
- wikioi 回家c
- 全栈JavaScript之路(十一)学习 Attr 类型 节点
- unix中的 sync(), fsync(), fdatasync()函数
- 28个实用的源码/文档比较合并工具