您的位置:首页 > 其它

背包问题解析

2013-01-02 00:33 148 查看
今天看到算法:C语言实现这本书 第五章递归与树 中 背包问题,想到对这个问题理解不够透彻. 希望利用第一篇技术博客好好的吃透它.

背包问题是什么?

设有i类不同大小和价值的物品,背包的可用容积为cap,进行合理的物品选择使得所装入的物品价值最大.

背包问题解法?

设定:背包大小为cap,对应第i项物品记为item[i],

定义结构体:

typedef struct

  { int size;

int val;

}item;

思路:利用递归解法,每次我们选择一个项,我们都假设可以递归的找到打包剩余背包的最优方式. 对于大小为cap的背包,对于可用类型中任何一项i,我们可以把i放入背包的同时,使得其他项有最优打包,来得到一种最优解.简单地说最优打包的方式就是已经找到(或将要找到)大小为capp-item[i].size的更小背包.这种解法利用了最优决策原理.

递归实现 大量的重复计算

int knap(int cap)

{ int i,space,max,t;

for(i=0,max=0;i<N;i++)

if((space = cap - items[i].size)>=0)

if((t = knap(space) + items[i].val) > max)

max = t;

return max;

}

代码分析:蓝色标记的是程序的关键,对于背包问题,进行如上所说思路递归,对于空间和时间的双重把控是关键。递归遍历每一种存在的可能,再一次和max比较,众所周知 会有大量重复的出现,一般程序设计中不考虑。

动态规划实现 递归升级版 检索已保存的值 使用一个观察哨来表达未知值而不是进行递归调用.

int knap(int M)

{int i,space,max,maxi,t;

if(maxknown[M] != unknown) return maxknown[M];

for(i=0,max=0;i<N;i++)

if((t = knap(space) + items[i].val) > max)

{ max = t ; maxi = i;}

maxKnown[M] = max; itemKnown[M] = items[maxi];

return max;

}

代码分析:存储项的索引,以便能够在计算之后重建背包的内容,如果希望itemKnown[M]在背包中,那么余下的内容就跟大小为M-itemKnown[M].size的最优背包内容一致,因此,itemKnown[M-item[M].szie]在背包里,以此类推。

动态规划继续思考中...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: