博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
动态规划
阅读量:5160 次
发布时间:2019-06-13

本文共 2544 字,大约阅读时间需要 8 分钟。

基本思想

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

基本概念

  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))
 

 

 

 

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
 
 

转载于:https://www.cnblogs.com/sunny666/p/10756762.html

你可能感兴趣的文章
SQL SERVER 如何修改数据库文件路径
查看>>
抽象类和接口的比较
查看>>
关闭Windows 10 自动更新
查看>>
Swift泛型协议的N种用法
查看>>
数量加减
查看>>
swift中数据之间的转换
查看>>
【iOS】Swift4.0 GCD的使用笔记
查看>>
Swift - 将String类型的数字转换成数字类型(支持十进制、十六进制)
查看>>
学校简易管理系统(python面向对象无界面版)
查看>>
运动员喝饮料问题
查看>>
[IMX6]Android6.0移植和分析
查看>>
第一章 spring boot实例项目快速搭建
查看>>
巧用UserAgent来解决浏览器的各种问题
查看>>
Java 新手学习 CSS样式列表 排版 格式布局
查看>>
jQuery概述
查看>>
(ios实战)实现类似于android 的toast控件
查看>>
mysql传统主从、双主复制+keepalived配置步骤
查看>>
关于MarshalByRefObject的解释
查看>>
vue之路由传参
查看>>
基于jquery的页面分屏切换模板
查看>>