求类似背包问题的算法

wanjunxiao 2011-11-11 03:42:57
将m种物品(体积分别为v1,v2...vm)放进容量为V的背包里,每种物品可放多件,求所放物品体积最多且件数最少的算法,请高手赐教!
...全文
277 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
keeya0416 2011-11-17
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 wanjunxiao 的回复:]
这个确实是一个完全背包的问题,只是我不太理解完全背包的求解过程,就请高手给段完全背包的伪代码吧,主要是想最后能输出装入哪些体积物品,在网上找到的代码最后都只是输出一个装入的总体积
[/Quote]
又想了想
可以不用另外记录的
最后可以通过F[i][v]判断出哪些物品是选择了的
如F[i][v] = F[i-1][v]说明当前物品未使用
如F[i][v] = F[i-1][v-V[i]] + W[i]说明当前物品有被使用
keeya0416 2011-11-17
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 wanjunxiao 的回复:]
keeya0416:
非常感谢你耐心赐教!麻烦你再次给段完整的代码,帮我输出最后放入了哪些物品
[/Quote]
for i=1..N
for v=0..V
f[v]=max{f[v],f[v-c[i]]+w[i]};
这个是解决完全背包的伪代码
你这个题目得修改下,当f[v]=f[v-c[i]]+w[i]时使用物品数少的那种方案。
最后再遍历的时候可以按我上边说的方法判断下
wanjunxiao 2011-11-17
  • 打赏
  • 举报
回复
keeya0416:
非常感谢你耐心赐教!麻烦你再次给段完整的代码,帮我输出最后放入了哪些物品
tswwz 2011-11-16
  • 打赏
  • 举报
回复
本质上还是背包问题啊,只是需要多次求背包结果。

先尝试只放一件物品,最大体积v_MAX1 ,如果v_MAX1 = V显然问题有解了。
然后算2件物品的,3件物品的 ,
keeya0416 2011-11-16
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 wanjunxiao 的回复:]
这个确实是一个完全背包的问题,只是我不太理解完全背包的求解过程,就请高手给段完全背包的伪代码吧,主要是想最后能输出装入哪些体积物品,在网上找到的代码最后都只是输出一个装入的总体积
[/Quote]
你可以另外申明个空间记录选择的物品呀
比如
F[v] = F[v-V[i]] + W[i];时说明当前物品被使用
那么就可以把F[v-V[i]]对应的记录再加上当前物品作为F[v]的选择物品
wanjunxiao 2011-11-16
  • 打赏
  • 举报
回复
这个确实是一个完全背包的问题,只是我不太理解完全背包的求解过程,就请高手给段完全背包的伪代码吧,主要是想最后能输出装入哪些体积物品,在网上找到的代码最后都只是输出一个装入的总体积
南山道人 2011-11-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 goldbeef 的回复:]

感觉怪怪的
(1)要求体积最多:应该用动态规划
(2)要求件数最少:则应该用贪心算法。


(3)如果既要要求体积最多,又要要求件数最少,则分别用(1)(2)两种算法求出两种方案,如果两种方案一样,则存在方案;否则,就不存在方案
[/Quote]
up一下,假设
a:V=6,N=3;
b:V=5,N=2;
那到底孰优孰劣啊?
wanjunxiao 2011-11-14
  • 打赏
  • 举报
回复
楼上的好像只考虑了体积为整数的情况吧?
keeya0416 2011-11-14
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wanjunxiao 的回复:]
楼上的好像只考虑了体积为整数的情况吧?
[/Quote]
实数是可以转化成整数的嘛
wanjunxiao 2011-11-14
  • 打赏
  • 举报
回复
这个解决0/1背包的算法,大家看看怎么修改一下能实现完全背包的解法
--------------------------------------------------------------
#include "stdafx.h"
#define N 10 //物品总种数
int n;//物品总种数
double limitW;//限制的总重量
double totV;//全部物品的总价值
double maxv;//解的总价值
int option[N];//解的选择
int cop[N];//当前解的选择
struct {//物品结构
double weight;
double value;
}a[N];
//参数为物品i,当前选择已经达到的重量和tw,本方案可能达到的总价值
void find(int i,double tw,double tv)
{
int k;
//物品i包含在当前方案的可能性
if(tw+a[i].weight <= limitW)
{
cop[i]=1;
if(i<n-1)find(i+1,tw+a[i].weight,tv);
else
{
for(k=0;k<n;++k)
option[k]=cop[k];
maxv=tv;
}
}
cop[i]=0;
//物品i不包含在当前方案的可能性
if(tv-a[i].value>maxv)
{
if(i<n-1)find(i+1,tw,tv-a[i].value);
else
{
for(k=0;k<n;++k)
option[k]=cop[k];
maxv=tv-a[i].value;
}
}
}

int _tmain(int argc, _TCHAR* argv[])
{
int k;
double w,v;
printf("输入物品种数:");
scanf("%d",&n);
printf("输入各物品的重量和价值:");
for(totV=0.0,k=0;k<n;++k){
scanf("%lf %lf",&w,&v);
a[k].weight = w;a[k].value = v;
totV += v;
}
printf("输入限制重量:");
scanf("%lf",&limitW);
maxv=0.0;
for(k=0;k<n;++k)cop[k]=0;
find(0,0.0,totV);
for(k=0;k<n;++k)
if(option[k])printf("%4d",k+1);
printf("总价值为: %2f",maxv);
return 0;
}
keeya0416 2011-11-11
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 keeya0416 的回复:]

int[] total = new int[V]; //背包
int[] count = new int[V]; //记录件数
for(int i = 0; i < total.length; i++){
for(int j = 0; j < m.length; j++){
if(v[j] + total[i - v[j]] > total[i]
|| ……
[/Quote]
果然写错了
for(int i = 0; i < total.length; i++)
for(int j = 0; j < m.length; j++)
这两个换个位置
另外体积是从1开始的,所以这里用到total[i - v[j]]之类的得换成total[i - v[j] + 1]
其他还有些细节
楼主自己琢磨下
keeya0416 2011-11-11
  • 打赏
  • 举报
回复
int[] total = new int[V]; //背包
int[] count = new int[V]; //记录件数
for(int i = 0; i < total.length; i++){
for(int j = 0; j < m.length; j++){
if(v[j] + total[i - v[j]] > total[i]
|| (v[j] + total[i - v[j]] == total[i] && count[i - v[j]] + 1 < count[i] )){
total[i] = v[j] + total[i - v[j]];
count[i] = count[i - v[j]] + 1;
}
}
}

不知道写错没, 思路大概就是这个样子的;这里只记录了件数,需要的话可以记录是哪些物件
keeya0416 2011-11-11
  • 打赏
  • 举报
回复
还是一个完全背包的问题
额外记录下物品数量
在发现某空间下有多组解的时候将数量少的那个解覆盖进去
wanjunxiao 2011-11-11
  • 打赏
  • 举报
回复
楼上,能否给段伪代码说明一下算法过程?最好能将最优方案的物品体积输出到一个数组
npuhuxl 2011-11-11
  • 打赏
  • 举报
回复
件数 f(V) = min{f(V-vi) + 1, i = 1..m and V - vi >= 0}
f(V) = 0 , V < min(vi)
这样行不行?
goldbeef 2011-11-11
  • 打赏
  • 举报
回复
感觉怪怪的
(1)要求体积最多:应该用动态规划
(2)要求件数最少:则应该用贪心算法。


(3)如果既要要求体积最多,又要要求件数最少,则分别用(1)(2)两种算法求出两种方案,如果两种方案一样,则存在方案;否则,就不存在方案

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧