贪心算法 - 背包问题

来源:互联网 发布:js 扫描枪录入 编辑:程序博客网 时间:2024/03/29 13:14

当一个问题具有最优子结构性质时,可以用动态规划算法来求最优解。

但有时候,有更便捷的方法。毕竟动态规划算法需要计算出所有的子问题后,才能根据子问题算出中个问题的最优解。

以背包问题为例。

先赘述下 0-1背包问题:

有一个背包,容量为c。

有n个物体X0,X1,X2,...,Xn-1,重量分别为W0,W1,W2,...,Wn-1,价值分别为V0,V1,V2,...,Vn-1。

将这n个物体中的任意几个放入背包,使得在不超过背包容量的情况下,背包中的物体总价值最大。

数学描述:

c>0

Wi>0, Vi>0, 0<=i<=n-1

求:[X0,X1,X2,...,Xn-1],其中Xi=0或1,使得X0*V0+X1*V1+...+Xn-1*Vn-1最大

约束条件:X0*W0+X1*W1+...+Xn-1*Wn-1 <= c


背包问题:

有一个背包,容量为c。

有n种物体X0,X1,X2,...,Xn-1,重量分别为W0,W1,W2,...,Wn-1,价值分别为V0,V1,V2,...,Vn-1。

将这n种物体中的任意几种的几个放入背包,使得在不超过背包容量的情况下,背包中的物体总价值最大。

数学描述:

c>0

Wi>0, Vi>0, 0<=i<=n-1

求:[X0,X1,X2,...,Xn-1],其中0<=Xi<=Wi,使得X0*V0+X1*V1+...+Xn-1*Vn-1最大

约束条件:X0*W0+X1*W1+...+Xn-1*Wn-1 <= c


这两个问题的主要区别在于:

0-1背包问题中n个物体,其中的任意一个都只有放入背包和不放入背包两种选择,不能分割出一部分放入,另一部分不放入。

背包问题中是n种物体,其中的任意一种都可以放入背包和不放入背包,还可以放入一部分,另一部分不放入


这两个问题都具有最优子结构性质。

背包问题可以用贪心算法求解,而0-1背包问题不能使用贪心算法。

背包问题可以每次将尽可能多的最贵的物品放入背包,即单位重量价值最高的物品,至超过容量c为止。

所以先按物品贵贱排序,然后依次从贵到贱放入背包。

代码略。

算法复杂度:排序为O(nl0gn),放入为O(n),总共为O(nlogn+n)


贪心算法的基本要素

(1)最优子结构性质

整个问题的最优解的子集,也是对应子问题的最优解。

(2)贪心选择性质

整个问题的最优解,可以通过 一步一步的局部最优的选择 来达到,即贪心选择。

在动态规划中,每一步选择都需要依赖子问题的最优解,因此只有子问题算出后,才可以做出选择。

在贪心算法中,每一步选择都只需要依赖当前状态,只选取当前情况下最优的选择,不依赖子问题。

因此,在动态规划中,需要先自底向上先解决各个子问题;在贪心算法中,自顶向下的,每一次都做出最优的选择,将问题化简后继续下一次迭代。