grokking algorithms Dynamic programming 第九章 动态规划中文翻译

第九章 动态规划
···········································································································································
在本章中:
你会学习到动态规划,将大的难题分解为小的难题,然后先解决小的难题的方法;
用例子来说明,怎么解决动态规划引入的新问题。
····················································································································································
背包问题

这里写图片描述
你是一个用背包偷东西的小偷,你的被告只能装4英镑的东西。你可以往背包中放入以下物品:立体声系统、笔记本电脑和吉它。
这里写图片描述

图9-1
你怎样才能使偷的所有物品的总价值最大呢?
简单解决方案
最简单的算法如下:你讲所有的可能组合列出来,然后找出最值钱的那个方案。
这里写图片描述

图9-2 图9-3
这样可以解决问题,但是这样太慢了,你有3个物品,你需要计算8种不同的可能,若是有4种物品,你需要计算16种不同的组合,每多加一项物品,你需要计算的可能情况就要翻倍。这个算法需要的时间复杂度为O(2n),这个算法非常非常慢。

这里写图片描述
图9-4
计算每一种可能的情况杜雨大多数的数字(比如100)都是不现实的。在第8章中,我们学习了贪婪算法,这个解决方案是接近最优解,但是却不是最优解。
那么怎样才能得到最优解呢?
动态规划
答案:动态规划!动态规划算法是怎样发挥作用的呢?动态规划通过解决一个个的小问题,然后逐渐小问题组成的大问题解决掉。
这里写图片描述

图9-5
对于背包问题,我们先解决小的背包问题,然后逐步把原来的背包问题解决掉。
动态规划是个比较难的概念。若是你不能立刻掌握它也不要担心,我们会举很多例子。
我们开始通过解决问题来讲算法,我们在解决问题的过程中,你可能有很多疑问,我会尽我所能的来解答这些疑问。
每个动态规划算法都是从表格开始,下面是背包问题的表格。

这里写图片描述

图9-6
列代表背包的容量,从1英镑到4英镑。行代表可以选择的物品。
你需要这个表格中的每个单元格来计算每个小背包里的物品的价值。
从空表格开始,你需要计算每个单元格的值。当所有的单元格都计算了,你也就得到答案了。
你可以创建自己的表格,跟着我,我们一起计算。
吉它行
我稍后会将公式列出来,我们先来讲解一遍,从第一行开始。

这里写图片描述
图9-7
这是吉它行,意思是将吉它放入背包中。在第一行第一列中有一个简单的选择,偷吉它或者不偷?
记住:你要偷价值最高的物品。
第一个单元格的背包可以装1英镑的物品,吉它是1英镑,你可以把它装进背包里。所以这一个单元格的价值是1500美元,它里面包含吉它。
把价值1500美元填入第一行第一列中。

这里写图片描述
图9-8
像这样,每个单元格中都会装一些物品。看第2个单元格,这个单元格可以装入2英镑,吉它也可以装进来。

这里写图片描述
图9-9
第一行中剩下的几列也可以装入吉它,这是第一行,你只能选择吉它。你可以假装其他2项你现在还不能偷。

这里写图片描述
图9-10
在这点上,你可能很困惑。我们为什么要用到只能装1英镑或者2英镑的小背包呢?还记得我说的动态规划吗,动态规划是将问题分解为小问题,先解决小问题,然后逐渐将大问题解决掉?继续吧,过一会你就明白了。
现在,你的表格是这样的了。

这里写图片描述
图9-11
记住,你需要使背包中装入的物品的价值最大,现在每行中的价格是现阶段中最高的。从行中可以看出,尽管你有一个可以装4英镑的背包,但是你只能往里面装1500美元的物品

这里写图片描述
图9-12
你知道这不是最终方案。通过这个算法,你会证明你的推论。
立体声系统所在的行
第二行是立体声系统。现在你在第二行,你可以偷立体声系统或者吉它。在这一行,你可以偷这一行或者上一行的物品,因此,你现在还不能偷笔记本电脑。但是可以偷立体声系统或者吉它。让我们从能装1英镑的背包开始。你能放入该背包的物品中,价值最高的是1500美元。

这里写图片描述
图9-13
你要偷立体声系统吗?
你的背包可以装1英镑,立体声系统能放进来吗?
不行,它太重了,因此对于只能放1英镑的小背包来说,它能存放的物品的最大价值依然是1500美元。

这里写图片描述
图9-14
第2行第2列和第2行第3列这两个单元格是一样的,它们的容量分别是2英镑和3英镑。它们以前的最大价值是1500美元。立体声系统不适合(立体声系统重4英镑),因此前3个单元格的值是不改变的。

这里写图片描述
图9-15
若是背包的容量是4英镑呢?阿哈,立体声系统可以放进去了。以前的最大价值是1500美元,但是若是换成立体声系统,它就是3000美元。因此,我们选择立体声系统。
这里写图片描述

图9-16
现在你更新了值。如果你有一个可以装4英镑的背包,你至少可以装3000美元的物品,你现在可以看到,表格中的单元格中的值有些被更新了。
这里写图片描述

图9-17
笔记本电脑行
让我们来看笔记本,它重3英镑。因此不能放入1英镑或者2英镑的背包,因此这行的前两个单元格中的值依然是1500美元。

这里写图片描述
图9-18
当背包容量是3英镑时,里面存储的物品的价值时1500美元,但是你也可以选择笔记本电脑,它的价值是2000美元。因此,新的价值值是2000美元。
这里写图片描述

图9-19
在背包容量为4英镑的单元格比较有意思,现在的价值是3000美元,你可以把笔记本放进去,但是笔记本只值2000美元。
3000.vs. 3000. v s . 2000
STEREO. LAPTOP
图9-20
嗯,这个的价值不如原来的高,但是笔记本电脑只重3英镑,你还可以再装1英镑的物品进来,你要装哪种1英镑的物品呢?
3000.vs.( 3000. v s . ( 2000 +. ???/1LB of FREE SPACE)
STEREO. LAPTOP
图9-21
1英镑的物品中,哪种价值最高呢?你看,你一直都在计算呢。

这里写图片描述
图9-22
根据表格的数据,我们发现吉它只重1英镑,而且价值为1500美元,因此,真正的价值比较为立体声系统 VS (笔记本电脑+吉它)
3000.vs.( 3000. v s . ( 2000 + $1500)
STEREO. LAPTOP + GUITAR
图9-23
你可能很疑惑,为什么我们要计算容量小的背包可以存放的最大价值。现在你明白了吧,当你有容量剩余的时候,可以从这些小背包中找到答案。因此,对于容量为4英镑俄背包,最好选择存放笔记本电脑和吉它,它们的价值为3500美元。
最后的表格是这样子的:

这里写图片描述
图9-24
因此,答案如下:放入背包中的物品的最大价值为3500美元,由吉它和笔记本电脑组成。
可能你会说在计算最后一个值时,我用了一个不同的共识,那是因为在算前面的值时,我忽略了一些不必要的复杂步骤,每个单元格用的公式都相同。

这里写图片描述
图9-25
表格中的每个单元格都可以用这个公式来计算,你得到的结果会和这个结果完全相同。记住,我们在讨论如何解决小问题,两个小问题都解决了,那么由这两个小问题组成的大问题也就解决了。

这里写图片描述
图9-26
背包问题FAQ
你可能感觉很神奇,这个部分我会回答一些普遍的问题。
若是再加一项物品,会怎样呢?
假设还有一件物品也可以偷,只不过你原来没有发现,假设你也可以偷iPhone。
你需要重新计算表格中的每一项的值吗?不需要。记住,动态规划可以在原来的基础上继续计算,迄今为止,这是表格中每项的最大值。

这里写图片描述
图9-27
这意味着,对于容量为4英镑的背包,你可以偷3500美元的物品,你以为这是最好的偷的物品组合了。但是现在又加入了iPhone。
这里写图片描述

图9-28
似乎你会找到一个新的最大值,在往下看之前,先试着将所有空的单元格填上值。
我们从第一个单元格开始,iphone重为1英镑,原来最大值为1500美元,但iphone为2000美元,因此,我们将它替换为iPhone。

这里写图片描述
图9-29
下一个表格,我们装iPhone和吉它
这里写图片描述

图9-30
第3个单元格,最好的选择还是iPhone和吉它。
最后一个单元格,事情变得有意思了。现在最大的价值组合是3500美元,你可以选择偷iPhone,那么还剩3英镑的空间。
3500.vs.( 3500. v s . ( 2000 +. ???/3LBs of FREE)
LAPTOP + GUITAR
图9-31
这3英镑物品的价值为2000美元,2000+2000=4000美元。新的最大值为4000美元。新的表格如下:
这里写图片描述

图9-32
问题:有没有可能存在一列,使值变小呢?如下图:

这里写图片描述
图9-33
先思考一下
答案:不会。在每一个循环中,我们都会存储最大值,因此现在的值不会比以前的值更低。
练习
9.1 假设你还可以偷另一种物品,MP3播放器。它重1英镑,价值为1000美元,你要偷这个吗?
若是每行的顺序变了会怎样呢?
若是我们把立体声系统、笔记本电脑和吉它的顺序变一下,结果会改变吗?
表格是怎样的呢?在往下读之前,请你自己先试着写一下。

这里写图片描述
图9-34
答案是没有改变。因此,行的顺序没有关系,你可以按列来填充表格吗?自己试一下,对于这个例子来说,结果是一样的,对其他的例子来说,结果可能是不同的。
若是增加一个更小的值,会怎样呢?
假设你还可以偷项链,它重0.5英镑,价值1000美元,原来我们都假设重量是整数,现在你决定偷项链,你还剩3.5英镑的容量。什么物品组合重3.5英镑而且价值最大呢?我们知道,我们只计算了1英镑、2英镑、3英镑和4英镑的值,我们需要知道3.5英镑的背包可以装的物品的最大价值。这里写图片描述

图9-35
因为项链的加入,我们需要将容量再细分一下,因此,我们的表格要变化一下了。
你可以偷一种物品的一部分吗?
假设你是一个小偷,去杂货店偷东西。你可以偷袋装小扁豆和大米。若是不能成袋偷,你可以打开袋子,装多少都可以。所以现在不是全部装或者不装,你可以选择装物品的一部分。你怎样利用动态规划来解决问题呢?
答案:不能。动态规划只能解决选择或者不选择,不能解决选择一部分的问题。
但是这类问用贪婪算法比较简单。首先,挑最贵的,然后尽可能的多偷,若是不能再装更多时,选择第二贵的物品,一直这样做。
例如,假设你有以下物品可以选择。

这里写图片描述
图9-36
藜麦最贵,因此先偷藜麦,若果背包中还有空间,选择木豆,一直这样做。

这里写图片描述
优化旅行路线
假设你去伦敦度假,你很自由2天时间,有很多想去的地方,但是你不可能每个地方都去,下面是清单。

这里写图片描述
图9-37
对于每一个景点,你都写下了花费的时间和你想去的程度。根据这个清单,你能算出如何选择这些景点吗?
这是另一种背包问题,这个不是背包的容量限制,而是有时间限制,不是一些要偷的物品,而是一些要去的景点。先画一张动态规划表格。这个是动态规划表格。
这里写图片描述

图9-38
你画对了吗?填充这张表格,哪些景点你可以去看呢?这是答案。
这里写图片描述

图9-39
处理相互间有依赖的项
假设你计划去巴黎,在巴黎你有3个地方想去。
这里写图片描述

图9-40
这些地点需要很多时间,因为你需要从伦敦到巴黎,这需要半天时间。如果这3个景点你都去,那么需要4.5天。
但是,这是不对的,你不需要每次都花费时间去巴黎,你若是住在巴黎的话,这些项每个只需要1天,那么总共需要3.5天。,而不是4.5天。
若果你要选择埃菲尔铁塔,那么Louvre更便宜了。—因为它只需要花1天,而不是1.5天。用动态规划怎么标示这些模型呢?
这是不行的。动态规划可以解决小问题,小问题加起来就是大问题。动态规划算法只对相互独立的小问题起作用—这些小问题相互间无依赖关系。这也就是说,用动态规划算法无法解决上述巴黎旅游的问题。
问题解决需要两个以上的小背包,这是可能的吗?
最佳方案需要偷2个以上的物品,这是可能的。这个算法设定你只能将一个大问题分解为两个小问题,但是每个小问题都可以继续分解为2个其他更小的问题。
这里写图片描述

图9-41
有没有可能最佳方案并没有将背包的容量使用完全?
是的,假设你也可以偷钻石。
这里写图片描述

图9-42
这个是个大钻石,它重3.5英镑。它值1000,000美元。其他项的价值比这个差远了。你肯定偷这个,但是现在只剩下0.5英镑的空间了。其他项都装不进去了。
练习
9.2 假设你去露营,你的背包只能装6英镑。你需要装的物品如下:每个物品的值代表它的重要程度。
水,3英镑,重要程度10
书,1英镑,重要程度3
食物,2英镑,重要程度9
夹克,2英镑,重要程度5
相机,1英镑,重要程度6
你要怎么选择要带的物品呢?

最长的子字符串
你现在了解了动态规划问题,它们都有什么特征呢?
这里写图片描述

图9-43
当你要解决带有限制条件的问题时,比如背包问题呢,由于背包的容量有限,你需要选择最大价值组合的物品;
当问题可以被拆分成相互独立的小问题时,你可以利用动态规划算法。
找到动态规划问题的解决方法比较难,这正是我们现在要做的,这些是关键步骤。
先画一张表格;
表格中的值时你要找的最优解,背包问题,表示的是装入背包的物品的价值;
每个单元格都是一个小问题,因此,要学会如何拆分问题,这有助于我们找到解决问题的关键点

让我门来看另一个例子。假设你运营一个词典网站

这里写图片描述

图9-44
其他人输入一个单词,你要将单词的意思呈现出来,但是若是其他人把单词拼写错了,你需要猜测正确的单词。比如Alex想查找fish,但是他错误的输入了hish,这个词在词典中找不到,但是你可以找到一些相似的词。
SIMILAR TO “HISH”:
FISH
VISTA
这只是个简单的例子,我们只列举了2个词,实际上,可能有 这种相似的词。
那么Alex输入了hish,他到底想输入什么词呢?fish或者visa?
画一张表格
解决这个问题的表格长什么样子呢?你需要回答以下问题:
1.每个单元格的值是啥?
2.怎样将问题分解为更小的问题呢?
动态规划中,你要找到某一类的最大值。在这个例子中,我们需要找到两个字符串中相同的子字符串,hish和fish的相同子字符串是啥?hish和vista的相同子字符串是啥?这是我们需要计算的。
记住,单元格中天蝎的是你要找出最优解的项。这个例子中,这个值是个数字,即子字符串的长度。
怎样将问题分解为更小的问题呢?
你可以比较子字符串,再比较hish和fish前,你需要先比较his和fis。每个单元格填写两个字符串的相同子字符串的长度,这也就寓示着关键点是子字符串的长度。因此,这个表格是这样的:
这里写图片描述

图9-45
若你还是没有明白也没有关系,这个比较难。这也是我把它放在这本书靠后面部分的原因。我会给出一些练习动态规划的练习。
填充表格
现在你设计好表格了,怎样填充表格中的每个单元格呢?你可以省力一些,因为你知道解决问题的方法了—hish和fish有3个字符是相同的:ish。但是这并没有告诉我们怎样使用算法。一些计算机科学家戏称为费曼算法。Feynman算法源于一个著名的物理学家理查德·费曼。它是这么工作的:
1.将问题记下来
2.思考答案
3.将答案写下来。
这里写图片描述

图9-46
计算机科学家是很有趣的一群人。真相是,很难找出一个计算公式,你需要做一些实验,然后来验证哪些是起作用的,有时,光靠算法是不够的,你可以将你的想法以算法(公式)的方式表述出来。
试着自己找出这个问题的解决方案,我可以提示一下。
这里写图片描述
图9-47
其他的值怎么填写呢?记住每一个单元格都是一个小问题。为啥(3,3)的值时2,(3,4)的值是0.
你先试着自己填写出来,再往下读,就算你答的不对,也会帮助你更好地理解我的解释。
解决方案
这是最终的答案。
这里写图片描述

图9-48
这是计算公式。
这里写图片描述

图9-49
这个是代码描述。

if word_a[i] == word_b[j]:
    cell[i][j] = cell[i-1][j-1] + 1
else:
    cell[i][j] = 0

这个是hish vs vista的计算结果
这里写图片描述
有一点需要注意,对于这个问题,最终答案不是在最后一个单元格,对于背包问题,最后一个单元格里是最终答案,但是对于寻找最长的子字符串的问题,答案是在表格中,但不在最后一个单元格中。
让我们来回到最初的问题:那个字符串和hish含有的的相同字符串数最多?hish和fish有3个相同的字符,Alex想输入的单词基友极有可能是fish。
最相似的情形
假设,Alex输入了fosh来查询,那么他真正想输入的是fish还是fort?
让我们利用最长相同子字符串来比较它们。
这里写图片描述

图9-51
它们是一样的,子字符串有2个字符,但是fosh和fish更像。
这里写图片描述

图9-52
你比较的是最长的子字符串,但是你真正需要比较的是最大的相同字符数。这两个单词都含有的字符。那怎么计算两个单词的相同字符数呢?
这里写图片描述

图9-53
你可以找到公式吗?这个和查找最长子字符串相似。它们非常相似,你可以先自己试一下。
最大相同字符数—解决方案
这里写图片描述

图9-54
这个每个单元格的值的计算公式

这里写图片描述
图9-55
这是代码表示:

if word_a[i] == word_b[j]:
    cell[i][j] = cell[i-1][j-1] + 1
else:
    cell[i][j] = max(cell[i-1][j], cell[i][j-1])

你计算出来了,这是本书中最难的一章,这就是动态规划经常使用的场景?是
生物学家利用最长相同字符数来查找DNA序列,它们可以利用他来找出两种动物或两种疾病的相似度。最长相同子字符串还被用来多发性硬化的治疗。
你用过diff吗?(比如git中的diff),diff告诉我们两个文件有哪些不同。它们也是利用动态规划来做这些的
我们讨论了字符的相似性。编辑距离计算两个字符串的相似度,利用了动态规划,编辑距离被用来作为拼读检查和检查用户是否上传了版权数据。
你使用过一款文本编辑软件吗?比如微软的word?它是怎么保证每行长度都一样的呢?动态规划!

练习
9.3 找出blue和clue的最长的子字符串。
回顾
当你需要查找有限制的最优解时,动态规划是有效的;
当问题可以分解为互不相干的小问题时,动态规划是起作用的;
动态规划要用表格;
单元格中的值时我们需要的最优解;
每个单元格都是一个子问题,所以要好好想想怎样将问题分解为小问题;
对于动态规划的解决方案没有固定的公式。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
高动态范围 (High Dynamic Range,简称HDR) 视频是指能够显示更广泛亮度区域和更丰富细节的视频格式。为了在标准的显示设备上播放HDR视频,需要进行色调映射 (Tone Mapping) 处理,将HDR视频转换为标准动态范围 (Standard Dynamic Range,简称SDR) 视频。 《高动态范围视频的色调映射算法比较评价》是一篇综述性文章,对目前的色调映射算法进行了对比和评估。 首先,文章介绍了需要解决的问题,即如何保留HDR视频的丰富细节和对比度,同时适应不同的SDR显示设备,使得观众在任何显示设备上都能够获得良好的观看体验。 接下来,文章列举了几种主要的色调映射算法,并对它们进行了详细分析和比较。比如,全局映射算法主要通过压缩整个亮度范围来适应SDR设备,但可能会损失细节;局部映射算法则更加注重保留细节,但可能导致亮度不连续性;基于图像分割的算法可以在图像不同区域中应用不同的映射策略,但需要更多的计算资源。 在比较过程中,文章对每种算法的映射质量、计算复杂度和实时性等指标进行了评估。并举例说明了不同算法在真实HDR视频上的应用效果。 最后,文章总结了各种算法的优缺点,并提出了未来研究的方向。例如,如何在保留细节的同时提高计算效率,以适应高分辨率和高帧率的HDR视频。同时,如何结合人眼感知和动态映射策略,以提供更好的观看体验。 综上所述,《高动态范围视频的色调映射算法比较评价》通过详细分析和比较不同的色调映射算法,为高动态范围视频的后续研究和开发提供了重要参考和指导。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值