《算法导论》之分治策略与动态规划

  • 分治策略
      分治策略是一种很重要的算法思想,很多很多问题都可以用分治策略解决。比如排序,汉诺塔以及一些最优化问题等等
      分治策略的意义就是将复杂问题还原成简单问题解决掉,且这些简单问题具有某些共同逻辑。
      递归实现的代码会很简洁,逻辑也会简单些,但复杂度分析就难了,一般要用到组合数学的知识
      但书中给了一种叫做“主方法”的通用式求解方法
      设递归方程 T(n)=aT(n/b)+f(n) 其中a>=1,b>1是常数,f(n)>0
      其意义是将T(n)的n规模的问题转化成a个T(n/b)规模的小问题,中间可能还需要一些辅助计算,就是f(n)
      那么
  
       具体细节我不多说,感兴趣的可以看书,这个东西主要是拿来快速评估的
  • 动态规划
   动态规划的大名我很早就听过,但一直不知道是什么。本科的时候还上过运筹学的。
       线性规划我到知道,看了书以后,我觉得动态规划很有用,非常有用。
       动态规划和分治策略相似,不同的是,它针对的问题所分解出的小问题数量很多且很多是重复的。
       动态规划就是使得这些重复的小问题只需要计算一次,避免重复计算。
 
       钢条切割问题:给定一段长度为n英寸的钢条和一个价格表pi(i=1,2,...,n)求切割钢条方案,使得销售收益rn最大。
    注意,如果长度为n英寸的钢条的价格p n足够大,最优解可能就是完全不需要切割。
       思路:先将钢条切成两条,有n-1种方案,每一种方案的最优解都等于两个子钢条的最优解。我们从这n-1个伪最优解再挑出最优的解了
       以下是伪代码:
1 CUT-ROD(p,n)
2 if n == 0
3     return 0
4 q=负无穷
5 for i = 1 to n
6     q=max(q,p[i]+CUT-ROD(p,n-i))
7 return q

上面只用了分治策略,这个算法的性能是很差的T(n)=2n,在子问题的求解中很多都是重复的。

动态规划就是避免这些重复。一般有两个思路1.记录中间解 

 1 MEM-CUT-ROD
 2 let r[0..n] be a new array
 3 for i = 0 to n
 4     r[i]=负无穷
 5 return MEM-CUT-ROD-AUX(p,n,r)
 6 
 7 MEM-CUT-ROD-AUX(p,n,r)
 8 if r[n]>=0
 9     return r[n]
10 if n==0
11     q=0
12 else q=负无穷
13     for i=1 to n
14         q=max(q,p[i]+MEM-CUT-ROD-AUX(p,n-i,r))
15 r[n]=q
16 return q

 2.通过对问题求解顺序的合理安排,达到避免重复

1 BOTTOM-UP-CUT-ROD(p,n)
2 let r[0..n] be a new array
3 r[0]=0
4 for j=1 to n
5     q=负无穷
6     for i=1 to j
7         q=max(q,p[i]+r[j-i])
8     r[j]=q
9 return r[n]

 

是不是很帅,反正我觉得很帅。i<=j, j>j-i>=0
后面有个更帅的,前面这两个算法都只给出了最优收益,没有返回解本身。
 1 EXTEND-BOTTOM-UP-CUT-ROD(p,n)
 2 let r[0..n] and s[0..n] be new arrays
 3 r[0]=0
 4 for j = 1 to n
 5     q=负无穷
 6     for i =1 to j
 7         if q < p[i]+r[j-i]
 8             q=p[i]+r[j-i]
 9             s[j]=i
10             r[j]=q
11 return r and s
12 
13 PRINT-CUT-ROD-SOLUTION(p,n)
14 (r,s)=EXTEND-BOTTOM-UP-CUT-ROD(p,n)
15 while n >0
16     print s[n]
17     n=n-s[n]

动态规划真的是个好东西,书中还讲了动态规划在最长公共子序列以及最优二叉搜索树上的应用,此处不细讲。

使用动态规划方法求解的最优化问题应该具备两个要素:最优子结构和子问题重叠。

转载于:https://www.cnblogs.com/2010Freeze/p/3338430.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值