动态规划算法_chengqiuming的博客-CSDN博客_动态规划算法
动态规划
动态规划(Dynamic Programming)算法的核心思想是:将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法。
动态规划算法与分治算法类似。其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解。
动态规划可以通过填表的方式来逐步推进,得到最优解。
1、从斐波那契数列看 动态规划
def feibonqie(n):#非动态规划
if n== 1 or n==2:
return 1
else:
return feibonqie(n-1)+feibonqie(n-2)#子问题重复计算
def fei(n):#动态规划
f=[0,1,1]
if n>2:
for i in range(n-2):
num=f[-1]+f[-2]
f.append(num)
return f[n]
print(feibonqie(50))
print(fei(50))
两者计算速度差距太大!!!
2、钢条切割问题
钢条切割问题Python实现-动态规划 Dynamic Programming_地上悬河的博客-CSDN博客
钢条切割问题——最优子结构
1、可以将求解规模为n的原问题,划分为规模更小的子问题:完成一次切割后,可以将产生的两段钢条看成两个独立的钢条切个问题。
2、组合两个子问题的最优解,并在所有可能的两段切割方案中选取组合收益最大的,构成原问题的最优解。
3、钢条切割满足最优子结构︰问题的最优解由相关子问题的最优解组合而成,这些子问题可以独立求解。
一般实现:
p=[0,1,5,8,9,10,17,17,20,24,30]
def cut(p,n):
if n==0:
return 0
else:
res=p[n]
for i in range (1,n):
res=max(res,cut(p,i)+cut(p,n-i))
return res
def cut1(p,n):
if n==0:
return 0
else:
res=0
for i in range(1,n+1):
res=max(res,p[i]+cut1(p,n-i))
return res
print(cut(p,9))
print(cut1(p,9))
自顶向下递归实现:
def _cut_rod(p,n):
if n == 0:
return 0
q = o
for i in range(1,n+1):
q = max(q. p[i]+_cut_rod(p, n-i))
return q
动态规划实现:
def cut_rod_dpCP(p,n):
r =[0]
for i in range(1,n+1):
res =0
for j in range(1, i+1):
res =max(res,P[i]+r[i -j])
r.append(res)
return r[n]
重构解
def cut_rod_extend(p,n):
r=[0]
s=[0]
for i in range(1,n+1):
res_r = 0#价格的最大值
res_s =0 #价格最大伯对应方案的左边不切割部分的长度
for j in range(1, i+1):
if p[j]+r[i-j ]>res_r:
res_r = p[j]+r[i-j]
res_s=j
r. append(res_r)
s.append(res_s)
return r[n],s
r,s=cut_rod_extend(p,5)
def cut_rod_solution(p,n):
r,s=cut_rod_extend(p,n)
ans=[]
while n>0:
ans.append(s[n])
n-= s[n]
return ans
print(s)
print(cut_rod_solution(p,7))