vlambda博客
学习文章列表

贪心算法求解0-1背包问题


贪心算法(又称贪婪算法)是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。

贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择。

No.贪心算法的思路

贪心算法一般按如下步骤进行:

①建立数学模型来描述问题。

②把求解的问题分成若干个子问题。

③对每个子问题求解,得到子问题的局部最优解。

④把子问题的解局部最优解合成原来解问题的一个解。

贪心算法是一种对某些求最优解问题的更简单、更迅速的设计技术。贪心算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,省去了为找最优解要穷尽所有可能而必须耗费的大量时间。贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择,就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解。虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪心算法不要回溯。


背包问题是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。

No.2 背包问题的定义

我们有n种物品,物品j的重量为wj,价格为pj

我们假定所有物品的重量和价格都是非负的。背包所能承受的最大重量为W

如果限定每种物品只能选择0个或1个,则问题称为0-1背包问题。

可以用公式表示为:

贪心算法求解0-1背包问题

受限于:

贪心算法求解0-1背包问题

如果限定物品j最多只能选择bj个,则问题称为有界背包问题。

可以用公式表示为:

贪心算法求解0-1背包问题

受限于:

贪心算法求解0-1背包问题

如果不限定每种物品的数量,则问题称为无界背包问题。

各类复杂的背包问题总可以变换为简单的0-1背包问题进行求解。

No.3 背包问题的案例

有旅行者要从n种物品中选取不超过b公斤的物品放入背包,要求总价值最大,设第i种物品的重量为ai,价值为ci(i=1,2,....,n)。定义向量[x1,x2,....,xn]当选第i种物品往背包放时去xi=1,否则取xi=0

于是所有选取的物品的总价值为:

贪心算法求解0-1背包问题

总的重量为:

贪心算法求解0-1背包问题

问题可描述为:

贪心算法求解0-1背包问题

约束条件为:

贪心算法求解0-1背包问题

贪心算法意为见到好的就抓住不放,用贪心算法求解问题,一般可以获得比较好的求解速度。本问题的具体做法为:先计算物品的价值密度,并把物品按价值密度从大到小的顺序排列:

当选择第ki件物品时,先判断背包是否超载,如果不超载,则放入背包,否则考虑下一件ki+1。按照这种方式考虑所有物品,即能得到背包问题的一个近似最优解。

附录

MATLAB贪心算法解决0-1背包问题

function  [sch,tolval,tolwei]=backpack(maxwei,weight,value)

n=size(weight,2);

sch=zeros(1,n);

p=value./weight;

[a,b]=sort(p);%从小到大排序后的向量,b是对应元素原始下标

b=b(n:-1:1);

tw=0;%已装入背包的物品重量

for i=1:n

     if(tw+weight(b(i)))<=maxwei

         tw=tw+weight(b(i));

         sch(b(i))=1;

    end

end

tolwei=tw;

tolval=sum(value(find(sch)));

>> [s,v,t]=backpack(110,[1  10 20 40 45 22 30 55],[10 20 30 50 55 32 40 60])

 

s =

 

     1      1     1     0      0     1     1     0

 

 

v =

 

   132

 

 

t =

 

    83