mysql动态规划_动态规划 - sunny-cheng - 博客园

基本思想

动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。具体的动态规划算法多种多样,但它们具有相同的填表格式。

基本概念

1. 多阶段决策问题

如果一类活动过程可以分为若干个互相联系的阶段,在每一个阶段都需作出决策(采取措施),一个阶段的决策确定以后,常常影响到下一个阶段的决策,从而就完全确定了一个过程的活动路线,则称它为多阶段决策问题。

各个阶段的决策构成一个决策序列,称为一个策略。每一个阶段都有若干个决策可供选择,因而就有许多策略供我们选取,对应于一个策略可以确定活动的效果,这个效果可以用数量来确定。策略不同,效果也不同,多阶段决策问题,就是要在可以选择的那些策略中间,选取一个最优策略,使在预定的标准下达到最好的效果.

2.动态规划问题中的术语

阶段:把所给求解问题的过程恰当地分成若干个相互联系的阶段,以便于求解,过程不同,阶段数就可能不同.描述阶段的变量称为阶段变量。在多数情况下,阶段变量是离散的,用k表示。此外,也有阶段变量是连续的情形。如果过程可以在任何时刻作出决策,且在任意两个不同的时刻之间允许有无穷多个决策时,阶段变量就是连续的。

用个示例引入一下:

斐波那契(多阶段决策问题)

def fibnacci(n):

if n ==1 or n ==2:

return 1

else:

return fibnacci(n-1)+fibnacci(n-2)

# print(fibnacci(11))

斐波那契(动态规划(DP)思想 = 递推式 + 重复子问题)

def fibnacci_no_recurision(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(fibnacci_no_recurision(100))

36bb1db6889a7af7ba2a02610c194ab5.png

aeaf720013a4dcae260362600fb08e33.png

p = [0,1,5,8,9,10,17,17,20,24,30]

def cut_rod_recurision_1(p,n): #复杂度o(2n*n)

if n == 0 :

return 0

else:

res = p[n]

for i in range(1,n):

res = max(res,cut_rod_recurision_1(p,i) + cut_rod_recurision_1(p,n-i))

# 现有方式的价值 和从第一次到最后一次+剩余次数的最大值

return res

def cut_rod_recurision_2(p,n):

if n == 0:

return 0

else:

res = 0

for i in range(1,n+1):

res = max(res,p[i] + cut_rod_recurision_2(p,n-i))

return res

def cut_rod_dp(p,n): #复杂度o(n*n)

r = [0] #将每一次的最优值存到列表,没有了子问题的重复计算

for i in range(1,n+1):

res = 0

for j in range(1,i+1):

res = max(res,p[j]+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): #左边是1 于range(1,n+1)比较,如果大于上一次保存的列表人r和s

res_r = 0 #价格最大值

res_s = 0 #价格最大值对应方案左边不切割部分长度

for j in range(1,i+1): #j=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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值