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

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

今天跟大家分享下算法思想中比较难的一种"动态规划",动态规划给人像是作战时常用的“迂回战术”,或者说是

游击战,在运动中寻找突破口。

 

一: 思想

   首先要了解”动态规划“,必须先知道什么叫做”多阶段决策“,百科里面对这个问题解释的很全,我就load一段出来,

大家得要好好品味,好好分析。

 

上面图中最后一句话就定义了动态规划是要干什么的问题。

 

二:使用规则

    现在我们知道动态规划要解决啥问题了,那么什么情况下我们该使用动态规划呢?

   ①  最优化原理(最优子结构性质):

           如果一个问题的最优策略它的子问题的策略也是最优的,则称该问题具有“最优子结构性质”。

   ②  无后效性:

           当一个问题被划分为多个决策阶段,那么前一个阶段的策略不会受到后一个阶段所做出策略的影响。

   ③  子问题的重叠性:

          这个性质揭露了动态规划的本质,解决冗余问题,重复的子问题我们可以记录下来供后阶段决策时

        直接使用,从而降低算法复杂度。

 

三:求解步骤

      ①   描述最优解模型。

      ②   递归的定义最优解,也就是构造动态规划方程。

      ③   自底向上的计算最优解。

      ④   最后根据计算的最优值得出问题的最佳策略。

 

四:与其他算法的差异

     ① 递归:  递归采用的是“由上而下”的解题策略并带有可能的”子问题“重复调用,时间复杂度自然高。

                   而”动态规划“采用”自下而上“并带有临时存储器保存上一策略的最优解,空间换时间。

     ② 分治:  同样两者都是将问题划分为很多的子问题,不同的是”动态规划“中各子问题是相互联系的。

     ③ 贪心:  要注意的是贪心算法每走一步都是不可撤回的,而动态规划是在一个问题的多种策略中寻找

                   最优策略,所以动态规划中前一种策略可能会被后一种策略推翻。

 

五:举例

  动态规划中,最经典最著名的例子莫过于”背包问题“,现有:

    苹果: 1kg    12¥

    梨子: 1kg     3¥

    葡萄: 1kg    10¥

    板栗: 1kg    25¥  

现有一个背包,只能装3kg水果,那么如何得到物品价值最大化?

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace BeiBao {
public class Program {
static void Main(string[] args) {
Goods goods = new Goods() {
LimitWeight = 3, LimitNum = 4, Weight = new double[4] { 1, 1, 1, 1 }, Value = new double[4] { 12, 3, 10, 25 } }; BackPack(goods, 0, 0, goods.Value.Sum()); Console.WriteLine("经过最优化求解:\n"); for (int i = 0; i < goods.Selected.Length; i++) {
if (goods.Selected[i]) {
Console.WriteLine("重量:" + goods.Weight[i] + " 价值:" + goods.Value[i]); } } Console.Read(); } static double maxValue; static bool[] selected = new bool[4]; static void BackPack(Goods good, int i, double tw, double tv) {
//当前追加物品的重量 var currentWeight = tw + good.Weight[i]; //当前重量小于限制重量则继续追加 if (currentWeight <= good.LimitWeight) {
selected[i] = true; //如果当前不是最后一个商品,则继续追加 if (i < good.LimitNum - 1) {
BackPack(good, i + 1, tw + good.Weight[i], tv); } else {
for (int k = 0; k < good.LimitNum; k++) {
good.Selected[k] = selected[k]; } maxValue = tv; } } selected[i] = false; //这里就体现了动态规划的根本目的,解决冗余 if (tv - good.Value[i] > maxValue) {
if (i < good.LimitNum - 1) {
//排除当前物品所剩余的价值总值 var exceptNotSelectedValue = tv - good.Value[i]; BackPack(good, i + 1, tw, exceptNotSelectedValue); } else {
for (int k = 0; k < good.LimitNum; k++) {
good.Selected[k] = selected[k]; } maxValue = tv - good.Value[i]; } } } } #region 商品的实体 /// /// 商品的实体 /// public class Goods {
public double[] Value = new double[4]; public double[] Weight = new double[4]; public bool[] Selected = new bool[4]; public int LimitNum { get; set; } public double LimitWeight { get; set; } } #endregion }

 

转载于:https://www.cnblogs.com/songacm/p/3335885.html

你可能感兴趣的文章
自定义的JavaScript定时器
查看>>
smarty对数组进行json_encode
查看>>
Django model 字段类型及选项解析(二)
查看>>
《Linux命令行与shell脚本编程大全》第十四章 处理用户输入
查看>>
189. Rotate Array 从右边开始翻转数组
查看>>
用wget命令下载jdk
查看>>
python之路 Javascript的学习
查看>>
无法远程连接MySQL数据库服务器-(1130错误)
查看>>
C#读写Config配置文件
查看>>
k8s 核心功能 - 每天5分钟玩转 Docker 容器技术(116)
查看>>
LeetCode 简单 -旋转字符串(796)
查看>>
激活函数可视化
查看>>
雅虎的这个效果,有机会实现一下
查看>>
第五周学习进度情况
查看>>
【旧文章搬运】Windbg+Vmware驱动调试入门(四)---VirtualKD内核调试加速工具
查看>>
Linux GDB Debugging
查看>>
代码智能提示
查看>>
Bootstrap 模态对话框只加载一次 remote 数据的解决办法
查看>>
SpringBoot源码解析:AOP思想以及相应的应用
查看>>
神的回帖
查看>>