人不能贪婪,但程序可以!用通俗的方法读懂贪心算法核心思想
前言
问:怎么把无数个
不同重量且价值高低不等
的物品装入承重有限
的背包里才是最赚的?
答:哪个价值高先拿哪个!不够装就换第二价值高继续拿!直到背包装不下最小重量的物品为止!
以上问答环节的内容即贪心算法
的核心思维。
文章目录
一、通过经典题目理解
1、完全背包问题
有 N 种物品和一个容量为 V 的背包,每种物品都有无限件可用。第 i 种物品的体积是 c,价值是 w。
求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。
输入:
50
5
40 10 30 20 5
500 200 400 450 20
分析输入数据
- 输入第一行
50
即为背包最大容量V
- 第二行
5
即5种物品
- 最后两行分别为
第 i 种物品的体积 c 与价值 w
解决问题步骤分解
以上输入数据可以得出以下图示,图示是较好的表达程序运行过程的方法之一。
还是遵循前言问答的思想:哪个价值高先拿哪个!不够装就换第二价值高继续拿!直到背包装不下最小重量的物品为止!
所以下一步,应是挑选价值最大(红色)
的物品将其放入背包容器。
放入以后,背包容器的剩余体积只有10
了,第二高价值(蓝色)
的物品所需体积要20
,所以只能继续跳过,拿第三高价值(绿色)
的物品,所需体积要30
不足以装入背包容器,继续跳过,以此类推,直到拿到体积为10,价值为200(黄色)
的物品,将其放入。
到此背包已经没办法继续放入其他物品了,程序的贪婪模式结束,它认定自己最赚的拿法就是能拿到价值为700的物品。但是不难发现,此解并非最优解
!
并非最优解
我们仔细思考一下,确实最优解是最大能拿到价值为1100
的物品。
难道贪心算法
并不是对所有问题都能得到整体的最优解?还是说这只是一个特殊的巧合?我们继续往下看。
2、找零问题
有 i 种币值为 w 以及相应的数量 c ,用最少的数量凑齐一定的金额 t 。
输入:
172
7
1 2 5 10 20 50 100
3 3 2 1 1 3 3
分析输入数据
- 输入第一行
172
即为需要找回的零钱总数
- 第二行
7
即为7种纸币类型
- 第三行为7种纸币的
面值
- 第四行为对应7种纸币的
数量
解决问题步骤分解
以上输入数据可转化为以下图示。
我们还是遵循贪心算法的思想,要使得找回的钱币数量最少,直接从最大的拿不就完事儿了嘛。
先拿最大面值的100元纸币
放入槽中,剩余要找回的零钱数还剩下72
,由于72 < 100
,所以不能再拿100元纸币
放入,只能拿50元纸币
。
50元纸币
放入槽后,此时可以看到目前还需要找零的22元
,所以继续分别选取20元纸币
与2元纸币
各一张。
最终,找回零钱数为0,即已经完成找零。可以看到我们使用了四张纸币,完成了这一次找零。但是可以思考一下,这是最佳的找零方案了吗,如果是最佳方案,那还有别的情况会导致找零问题得不到最优解吗?答案当然是有的!
并非所有情况都能得到最优解
我们给定下面这组输入数据,尝试用贪心算法执行一遍。
输入:
10
3
1 5 7
3 2 1
现在有三种面值纸币,分别是1元纸币
、5元纸币
、7元纸币
,数量分别是3
、2
、1
。我们需要找零10元
给菜市场大妈,怎么才能使得找回纸币数量最小?
还是按照贪心算法得思路来,首先拿最大的7元纸币
放入槽中。
此时还需要找零3元
,所以我们以此把三张1元纸币
放入槽中。
此时使用了四张纸币,完成了这一次找零,但是问题来了,这并不是这次找零方案的最优解,因为我们知道,只需要使用两张5元纸币
足矣。贪心算法
真的确实不是对所有问题都能得到整体的最优解,到底是什么导致这种情况发生?
二、为什么贪心算法得不到最优解?
原因就在于贪心算法
的局部最优解
原则,它的决策手段即做出在当前看来是最好的选择
,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解,得出来的结果有可能是最优解
,也有可能得到是近似解
。
它的具体算法过程是采用自顶向下
,以迭代的方法做出相继的贪心选择,每做一次贪心选择,就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解
。但大家都知道,并非所有问题都能使用贪心算法求最优解
。
所以我们使用贪心算法时,一定要注意以下贪心算法的特点:
1、不能保证解是最佳的。因为贪心算法总是从局部出发,并没从整体考虑。
2、贪心算法一般用来解决求最大或最小解。
3、贪心算法只能确定某些问题的可行性范围。
三、总结一下
其实背包问题的最优解一般是使用动态规划
进行求解而并非贪心算法
,因为贪心算法
的局部最优解
原则,使得只能确定问题的可行性范围,也仅仅是一个范围。
使用贪心算法
解决背包问题与找零问题的python程序我随后会上传到gitee。有兴趣的小伙伴可以看看。
图文均为原创,如果你觉得文章对你帮助,记得点赞关注一下哦。