动态规划_学习笔记

2021/12/19 23:23:26

本文主要是介绍动态规划_学习笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

摘自——《算法图解》

在我所知道的算法中,图算法应该是最有用的。

解决问题需要三个步骤:

  1. 分析题意;
  2. 使用相应的数据结构,来建立问题模型;
  3. 使用相应的算法来解决问题;

学习动态规划,这是一种解决棘手问题的方法,它将问题分成小问题,并先着手解决这些小问题。
学习动态规划的重点在于——如何设计问题的动态规划解决方案。

以背包问题为例:

假设你是个小偷,背着一个可装4磅东西的背包。

你可盗窃的商品有如下3件。

  • 音响:3000美元,4磅;
  • 笔记本电脑:2000美元,3磅;
  • 吉他:1500美元,1磅;

为了让盗窃的商品价值最高,你该选择哪些商品?

最简单的算法如下:尝试各种可能的商品组合,并找出价值最高的组合。

 

 在有3件商品的情况下,你需要计算8个不同的集合;有4件商品时,你需要计算16个集合。每增加一件商品,需要计算的集合数都将翻倍!这种算法的运行时间为O(2n),真的是慢如蜗牛。只要商品数量多到一定程度,这种算法就行不通。

答案是使用动态规划!下面来看看动态规划算法的工作原理。动态规划先解决子问题,再逐步解决大问题。

对于背包问题,你先解决小背包(子背包)问题,再逐步解决原来的问题。

每个动态规划算法都从一个网格开始

背包问题的网格如下:

网格的各行是商品,各列是不同容量(1~4磅)的背包。

所有这些列你都需要,因为它们将帮助你计算子背包的价值

网格最初是空的。你将填充其中的每个单元格,网格填满后,就找到了问题的答案! 

我们先来一步一步做。首先来看第一行。

这是吉他行,意味着你将尝试将吉他装入背包。

别忘了,每个单元格内,你要找出一个价值最高的商品集合

第一个单元格表示背包的容量为1磅。吉他的重量也是1磅,这意味着它能装入背包!因此这个单元格包含吉他,价值为1500美元。 

 

来看下一个单元格。这个单元格表示背包的容量为2磅,完全能够装下吉他!

 

此时你很可能心存疑惑:原来的问题说的是4磅的背包,我们为何要考虑容量为1磅、2磅等的背包呢?

前面说过,动态规划从小问题着手,逐步解决大问题这里解决的子问题将帮助你解决大问题。请接着往下读,稍后你就会明白的。

最终,第一行如下:

 你知道这不是最终的解。随着算法往下执行,你将逐步修改最大价值。

2.音响行

我们来填充下一行——音响行。你现在处于第二行,可偷的商品有吉他和音响。在每一行,可偷的商品都为当前行的商品以及之前所有行的商品

我们先来看第一个单元格,它表示容量为1磅的背包。在此之前,可装入1磅背包的商品的最大价值为1500美元。

背包的容量为1磅,能装下音响吗?音响太重了,装不下!由于容量1磅的背包装不下音响,因此最大价值依然是1500美元。

接下来的两个单元格的情况与此相同。在这些单元格中,背包的容量分别为2磅和3磅,而以前的最大价值为1500美元。

由于这些背包装不下音响,因此最大价值保持不变。

 
背包容量为4磅呢?终于能够装下音响了!原来的最大价值为1500美元,但如果在背包中装入音响而不是吉他,价值将为3000美元!因此肯定是放入音响。

 

 在这个网格中,你逐步地更新最大价值。

3.笔记本电脑行

下面以同样的方式处理笔记本电脑。笔记本电脑重3磅,没法将其装入容量为1磅或2磅的背包,因此前两个单元格的最大价值还是1500美元。

对于容量为3磅的背包,原来的最大价值为1500美元,但现在你可选择盗窃价值2000美元的笔记本电脑而不是吉他,这样新的最大价值将为2000美元! 

对于容量为4磅的背包,情况很有趣。这是非常重要的部分。

当前的最大价值为3000美元,你可不偷音响,而偷笔记本电脑,但它只值2000美元。 

价值没有原来高。但等一等,笔记本电脑的重量只有3磅,背包还有1磅的容量没用! 

在1磅的容量中,可装入的商品的最大价值是多少呢?你之前计算过。 

根据之前计算的最大价值可知,在1磅的容量中可装入吉他,价值1500美元。因此,你需要做如下比较。

你可能一开始心存疑惑:为何计算小背包可装入的商品的最大价值呢?但愿你现在明白了其中的原因!

余下了空间时,你可根据这些子问题的答案来确定余下的空间可装入哪些商品。笔记本电脑和吉他的总价值为3500美元,因此偷它们是更好的选择。
最终的网格类似于下面这样。

答案如下:将吉他和笔记本电脑装入背包时价值最高,为3500美元。 

其实,计算每个单元格的价值时,使用的公式都相同。这个公式如下:

 你可以使用这个公式来计算每个单元格的价值,最终的网格将与前一个网格相同。

现在你明白了为何要求解子问题吧?你可以合并两个子问题的解来得到更大问题的解。

 

启示:

动态规划可帮助你在给定约束条件下找到最优解。

动态规划功能强大,它能够解决子问题并使用这些答案来解决大问题。但仅当每个子问题都是离散的,即不依赖于其他子问题时,动态规划才管用。

要设计出动态规划解决方案可能很难。每种动态规划解决方案都涉及网格。单元格中的值通常就是你要优化的值。在前面的背包问题中,单元格的值为商品的价值。每个单元格都是一个子问题,因此你应考虑如何将问题分成子问题,这有助于你找出网格的坐标轴。



这篇关于动态规划_学习笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程