动态规划

参考链接

漫画算法,什么是动态规划?

DP

动态规划是一种分阶段求解决策问题的数学思想

题目一

问:下楼梯问题,有一座高度是10级台阶的楼梯,从下往上走,每跨一步只能向上1级或者2级台阶,请问有多少中走法。

思路

刚才这个题目,你每走一步就有两种走法,暂时不管0级到8级台阶的过程。想要走到10级,必然是从8级或者9级走的。那么问题来了,如果我们以及0到9级台阶的走法有x种,0到8级台阶有Y种,那0到10级台阶就是X+Y。

公式就是:
F(10) = F(9)+ F(8)

当只有1级台阶的时候只有一种解法,2级台阶的时候有两种方法。

递推公式就是:
F(1) = 1
F(2) = 2
F(N) = F(N-1)+ F(N-2)

动态规划的三个概念:

  1. 最优子结构
  2. 边界
  3. 状态转移公式


当只有1级台阶或2级台阶,我们直接得出结果,无需建华,我们就成F(1)F(2)为边界。
F(N) = F(N-1)+ F(N-2)是阶段与阶段之间的状态转移公式。

求解问题

方法一:递归法


但是复杂度很高,因为当中有很多大量的重复计算。复杂度 O ( 2 N ) O(2^N) O(2N)。具体分析见开头的链接。
遇到这种情况,我们只需要创建一个哈希表,在python种建立一个字典就好了。把每次不同参数的计算结果存入哈希,当遇到相同参数时,再从哈希表里面取出,就不会重复计算了。

方法二


感觉红色箭头少了个参数。

在以上代码中,集合map是一个备忘录。当每次需要计算F(N)的时候,会首先从map中寻找匹配元素。如果map中存在,就直接返回结果,如果map中不存在,就计算出结果,存入备忘录中


其实不用对F(N)自顶向下做递归运算,可以从下往上算。已知1,2是不是就能求3了。以此类推。

题目二

国王和金矿
问:有一个国家发现了5座金矿,每座金矿的黄金储量不同,需要参与挖掘的工人数也不同。参与挖矿工人的总数是10人。每座金矿要么全挖,要么不挖,不能派出一半人挖取一半金矿。要求用程序求解出,要想得到尽可能多的黄金,应该选择挖取哪几座金矿?

解答


最优子结构:
10个人4金矿(第五金矿不挖的时候),10减去挖第五金矿的人数要求然后剩下4金矿(第五金矿挖的时候)。
最终问题:
10个人5金矿的最优选择。
最优子结构和最终问题的关系:
设几个变量便于描述:
N:金矿数量
W:工人人数
G[]:金矿黄金含量
P[]:金矿的用工量
关系:
F(5,10) = Max(F(4,10),F(4,10-P[4])+ G [4])
==> F(N,W) = Max(F(N-1,W),F(N-1,W-P[N-1])+G[N-1])

边界条件:

if N == 1:if W>= P[0]:return G[0]else:return 0

总结:

和之前一样,有三种实现方式,简单递归,备忘录算法,动态规划。

方法二:简单递归

把状态转移方程式翻译成递归程序,递归的结束的条件就是方程式当中的边界。因为每个状态有两个最优子结构,所以递归的执行流程类似于一颗高度为N的二叉树。方法的时间复杂度是 O ( 2 N ) O(2^N) O(2N)。

方法三:备忘录算法

在简单递归的基础上增加一个HashMap备忘录,用来存储中间结果。HashMap的Key是一个包含金矿数N和工人数W的对象,Value是最优选择获得的黄金数。方法的时间复杂度和空间复杂度相同,都等同于备忘录中不同Key的数量。

方法四:动态规划





规律





However ,当总工人数变成1000人,每个金矿的用工数也相应增加,这时候如何实现最优选择呢?

可能你觉得还是之前的动态规划方法。其实是不对的,我们可以来计算一下,
1000工人5个金矿,需要计算1000 * 5 次,需要开辟 1000 单位的空间。
然而我们用之前的简单递归,需要计算2^n次也就是32次,只需要开辟5单位(递归深度的空间)。
所以从上面计算可以知道,动态规划方法的时间和空间都和W成正比,而简单递归却与W无关,当工人数量很多的时候,动态规划反而不如递归。
(我又一个想法,思路来源于Glibc 中的 qsort() 的实现在这个链接的举例分析排序函数板块中,我的思路是这样的,两个算法都可以写在函数实现上,如果当N特别大的时候,可以选择动态规划的方法,而当N不大,而W特别大的时候,且空间有限制,此时就可以让算法退化成简单递归。不知道对不对这个思路,如果哪里考虑的不对的话,请告诉我,万分感谢)

以上就是漫画算法的全部内容。以下是我的补充内容

背包问题 和迪杰特斯拉(Dijkstra算法–求图最短路径)

背包问题


如果认真读了上面的过程,看到这个题目是不是觉得和前面矿工和金矿很像是不是。背包问题就是,钱和重量,而前面矿工和金矿问题是,钱和人数的限制。
接下来的思路是算法图解中关于动态规划的讲解,可以参考看一下。


























写出正确的动态规划












Dijkstra’s Algorithm(是求从一点出发的最短路径)

伪代码

Data: G, s, dist[], pred[] and
vSet: set of vertices whose shortest path from s is unknown
Algorithm:
dist[] // array of cost of shortest path from s
pred[] // array of predecessor in shortest path from s
dijkstraSSSP(G,source):
|   Input graph G, source node
|
|    initialise dist[] to all ∞, except dist[source]=0
|    initialise pred[] to all -1
|   vSet=all vertices of G
|   while vSet is not NULL do
|    |  find s in vSet with minimum dist[s]
|    |  for each (s,t,w) in edges(G) do
|    |  relax along (s,t,w)
|    |  end for
|    |  vSet=vSet \ {s}
|    end while

以上伪代码仅供参考作用,喜欢的话,可以研究一下。下面通过一道题目来了解整个过程。

  1. 根据伪代码进行初始化:
  2. 根据题目的要求,从node 0开始,遍历与0相连的每条边的权重,更新列表,pred代表是从哪里来的,比如,第二列的0,代表从0来到1。(图中绿色的代表当前遍历的点)
  3. 然后遍历dist中除去0以外的,最小的值,以这个最小值作为起始点,遍历它连的边,更新列表。
  4. 其实就是重复3的动作,先找剩下的最小边,遍历它连的边,更新列表,你可以动手写一下剩下的内容。当dist发生变化时,pred也要相应的发生变化,毕竟你要记录最短路径,当然要记录这个路径是从哪里来的。

算法复杂度分析

每条边都需要遍历一边,O(E)
外循环是遍历所有点,则是O(V)
“find s in vSet with minimum dist[s]” 这段代码
尝试找s in vSet,cost为O(V)
==>overall cost 为 O ( E + V 2 ) = O ( V 2 ) O(E+V^2) = O(V^2) O(E+V2)=O(V2)
如果用优先队列来实现找最小距离,那么
Overall cost = O ( E + V l o g V ) O(E+VlogV) O(E+VlogV)

附加题

旅行者问题,动态规划详解

一文弄懂动态规划(DP Dynamic Programming)下楼梯,国王和金矿,背包问题,Dijkstra算法相关推荐

  1. 最长非降子序列(动态规划dp dynamic programming)

    首先要理解一下什么叫做非降子序列 非降子序列,简单来说就是指给出一个数字序列,在不改变整体顺序的情况下摘出几个来组成一个子序列,这个序列满足从小到大的排序顺序. 所以,最长非降子序列,不难理解就是从这 ...

  2. 动态规划(Dynamic Programming, DP)简介

    动态规划(Dynamic programming,DP)是一种在数学.计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法. 动态规划常常适用于有重叠子问题和最优子结 ...

  3. 一道有关动态规划(Dynamic Programming)的网易面试题

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:机器学习算法实验室 最近遇到一道很经典的有关动态规划的网 ...

  4. 一文弄懂元学习 (Meta Learing)(附代码实战)《繁凡的深度学习笔记》第 15 章 元学习详解 (上)万字中文综述

    <繁凡的深度学习笔记>第 15 章 元学习详解 (上)万字中文综述(DL笔记整理系列) 3043331995@qq.com https://fanfansann.blog.csdn.net ...

  5. 数据结构与算法(C++)– 动态规划(Dynamic Programming)

    动态规划(Dynamic Programming) 理解动态规划的好文:https://www.sohu.com/a/153858619_466939 1.基础 **定义:**递归算法经常会有一些重复 ...

  6. 一文弄懂神经网络中的反向传播法

    最近在看深度学习的东西,一开始看的吴恩达的UFLDL教程,有中文版就直接看了,后来发现有些地方总是不是很明确,又去看英文版,然后又找了些资料看,才发现,中文版的译者在翻译的时候会对省略的公式推导过程进 ...

  7. 一文弄懂各种loss function

    有模型就要定义损失函数(又叫目标函数),没有损失函数,模型就失去了优化的方向.大家往往接触的损失函数比较少,比如回归就是MSE,MAE,分类就是log loss,交叉熵.在各个模型中,目标函数往往都是 ...

  8. 一文弄懂神经网络中的反向传播法——BackPropagation【转】

    本文转载自:https://www.cnblogs.com/charlotte77/p/5629865.html 一文弄懂神经网络中的反向传播法--BackPropagation 最近在看深度学习的东 ...

  9. 一文弄懂String的所有小秘密

    文章目录 简介 String是不可变的 传值还是传引用 substring() 导致的内存泄露 总结 一文弄懂String的所有小秘密 简介 String是java中非常常用的一个对象类型.可以说ja ...

最新文章

  1. create_metrology_model创建测量几何形状所需的数据结构(原理)
  2. Oracle入门(五)之基本命令操作
  3. SIM800C 使用基站定位
  4. 惠普打印机136w硒鼓芯片怎么清零_惠普136w打印机怎么清零
  5. BP神经网络分类算法
  6. 点云数据实时在线浏览共享与逆向建模应用
  7. 电子元器件之电容如何测量
  8. 我为什么要选软件工程专业
  9. 在Linux系统中搭建web服务器
  10. Postgresql备份恢复用backup文件(pgadmin恢复功能不能点击)
  11. python处理grd格式文件_python基础
  12. matlab 概率分布程序,常见的概率分布(matlab作图)
  13. 二维坐标基本变换(平移、旋转、缩放、镜像、阵列)
  14. 使用python实现图像对比度增强
  15. python 空矩阵_在NumPy中创建空数组/矩阵的方法
  16. android访问SD卡的权限
  17. Oracle-分析函数之sum(...) over(...)
  18. 数字病理切片处理---------组织学处理学习
  19. 大学生职业规划大赛计算机专业,计算机系召开大学生职业生涯规划大赛动员会...
  20. 算法竞赛宝典 棋子移动 递归

热门文章

  1. echarts 如何覆盖源码样式——dataview为例
  2. CONTEXT AUGMENTATION AND FEATURE REFINE- MENT NETWORK FOR TINY OBJECT DETECTION
  3. MVC与MVVM的理解
  4. 中南大学python考试_中南大学教务系统学生成绩爬虫【图】
  5. 2021-2027全球与中国热电堆红外传感器市场现状及未来发展趋势
  6. Access to XMLHttpRequest at ‘http://localhost:8080/VXApplets/UserInfoService/login‘ from origin ‘htt
  7. 安卓SurfaceView截屏
  8. python把数据写在文件内
  9. 小米开源监控系统Open-falcon部署笔记(上)
  10. 基于asp.net的公安报案登记管理系统的设计与实现