动态规划

与贪心算法求局部最优解相比,动态规划求的是全局最优解(但不是每个问题都有最优解,比如NP完全问题就没有最优解)

例:背包问题之动态规划解决
问题描述:
现在有一个背包可以装4磅物品,现在要从商城里拿尽可能价值高的物品装进包里。
商城物品情况如下

商品名 吉他 笔记本 音箱
价值 1500 2000 3000
重量 1 3 4

每个动态规划都从一个网格(如下)开始
现在一行一行地填充该网格。

物品\物品重量 1 2 3 4
吉他
音箱
笔记本

每个格子的计算公式:


image.png

填充吉他行 目前最大价值1500(吉他)

物品\物品重量 1 2 3 4
吉他 1500 1500 1500 1500
音箱
笔记本

填充音箱:目前最大价值3000(音箱)

物品\物品重量 1 2 3 4
吉他 1500 1500 1500 1500
音箱 1500 1500 1500 3000
笔记本

填充笔记本:目前最大价值3500(吉他+笔记本)

物品\物品重量 1 2 3 4
吉他 1500 1500 1500 1500
音箱 1500 1500 1500 3000
笔记本 1500 1500 2000 3500

动态规划的原则就是将大问题拆解成多个小问题,先把小问题的最优解求出,再在考虑小问题最优解的前提下,得出最终问题的最优解
本例的背包问题中,先求出只有吉他一种物品时的最优解,再逐步添加物品,最终求出最优解


image.png

关于网格计算公式的补充:
整个动态规划求解过程中,是从小问题层逐步求解到大问题,自然每个格子要考虑的第一点就是前一格子的最大值,又,新的一层添加了新物品,所有也要考虑新物品的价值+剩余可用磅数的最大价值(上一层求得)

背包问题补充:
若再添加一个物品——项链{‘价值’:1000$,‘重量’:0.5磅}
此时如果沿用之前的网格

image.png

则会出现考虑不周的情况(0.5磅重量无法考察)
因此,当新加入的物品重量小于当前物品重量最小划分时,需要重新划分网格。
划分规则:最大重量//最小重量 即为区间数。
加入0.5磅的项链之后,新的网格为:

物品\物品重量 0.5 1 1.5 2 2.5 3 3.5 4
吉他
音箱
笔记本
项链

如果要装的物品为燕麦,木豆,大米这种可以一部分一部分取出的物品
动态规划则解决不了这种情形,贪心可以。

旅游行程问题

景点名(伦敦) 威斯敏特 双球剧场 英国美术馆
价值 7 6 9
花费时间 0.5 0.5 1

当然我们可以用动态规划的网格法来得到一条最有价值的旅游路线

如果加入以下景点

景点名(巴黎) 埃菲尔铁塔 卢浮宫 巴黎圣母院
价值 8 9 7
花费时间 1.5 1.5 1.5

在去巴黎的景点所花费的时间中,有0.5天是从伦敦前往巴黎的时间。
因此如果先去了埃菲尔铁塔,则去巴黎的剩下两个景点的花费时间也要减少2个小时

这种情况就不能使用之前的动态规划算法。

动态算法处理的每个子问题都是离散的

再来看一个案例
假如你要经营一个网站,网站主要任务是:英文单词翻译。即用户输入英文单词,你给出相应的翻译。 例用户输入fish,网站输出鱼
如果用户输入的hish,但词典中并没有该单词,此时应给出相似词。
怎么样才算是相似词呢?判断最大子串长度?
利用动态规划求出两字符串(fish和hish)的最大字串长度
动态规划解决问题总是要先知道网格中的各个元素:
两个坐标轴是什么?网格中的值是什么(通常为要优化的指标
1,分解问题:要求fish和hish的最大子串,可以先求其字串的最大公共子串(如先求fis和his)。考虑两个坐标轴为两个单词,则网格中的值为最大子串的长度。

f i s h
h
i
s
h

接下来填充该网格。不断验证得到单元格公式:


image.png

单元格公式解释:
1)两字母相同,则局部最大字串要延长,即斜上方(cell[i][j])的值加一(这里指标值在斜方向上累加)
2)若是不同,则局部最大字串为0

* h i s h
f 0 0 0 0
i 0 1 0 0
s 0 0 2 0
h 0 0 0 3

两字符串的最大字串长度即为网格中的最大值3。

如果用户输入fosh,那么要返回fish还是fort呢?
如果判断依据为最大子串,则会返回fort,但实际上fish和fosh更像!
因此我们考虑判断依据为两字符串的最大公共子序列长度(即两字符串公共字符的个数)
求最大公共子序列的单元格公式为:

image.png

* f o s h
f 1 0 0 0
o 1 2 2 2
r 1 2 2 2
t 1 2 2 2

fosh和fort的最大公共子序列长度为2

* f o s h
f 1 0 0 0
i 1 1 1 1
s 1 1 2 2
h 1 1 2 3

fosh和fish的最大公共子序列长度为3
此时就可以返回正确结果fish而非fort。

小结

1,动态规划通常用于解决在给定约束条件下优化某个指标值
2,动态规划的原则就是:将大问题分解成小问题,在解决了小问题的条件下,逐步求解大问题。(一个分解问题的方法就是,将条件逐渐减少,从最简单的情况开始分析)
3,动态规划使用的一个必要条件为:分解出来的每个小问题都是离散的
4,每种动态规划方案都设计网格
4.1,网格的每个格子都是一个小问题
4.2,网格的每个格子的值都是指标的值
4.3,单元格计算公式需要具体问题具体分析

你可能感兴趣的:(动态规划)