算法分析:0-1背包问题给定n种物品和1个背包,物品i的重量是wi,其价值为vi,背包的容量为C。选择装入背包的物品,使得装入背包中物品的总价值最大。例如5个物品wi[] = { 5,2,3,6,3}

一、效果图

vi[]={5,5,6,9,8},背包的容量为10

 

 

 

 

二、源代码

#include <iostream>

#include <stdio.h>

//#include <conio.h>

using namespace std;

int n;//物品数量

double c;//背包容量

double v[100];//各个物品的价值 value

double w[100];//各个物品的重量 weight

double cw = 0.0;//当前背包重量 current weight

double cp = 0.0;//当前背包中物品总价值 current value

double bestp = 0.0;//当前最优价值best price

double perp[100];//单位物品价值(排序后) per price

int order[100];//物品编号

int put[100];//设置是否装入,为1的时候表示选择该组数据装入,为0的表示不选择该组数据

//按单位价值排序

//                    18101960   闫晓燕

void knapsack()

{

int i, j;

int temporder = 0;

double temp = 0.0;

for (i = 1; i <= n; i++)

perp[i] = v[i] / w[i]; //计算单位价值(单位重量的物品价值)

for (i = 1; i <= n - 1; i++)

{

for (j = i + 1; j <= n; j++)

if (perp[i] < perp[j])//冒泡排序perp[],order[],sortv[],sortw[]

{

temp = perp[i];  //冒泡对perp[]排序

perp[i] = perp[i];

perp[j] = temp;

temporder = order[i];//冒泡对order[]排序

order[i] = order[j];

order[j] = temporder;

temp = v[i];//冒泡对v[]排序

v[i] = v[j];

v[j] = temp;

temp = w[i];//冒泡对w[]排序

w[i] = w[j];

w[j] = temp;

}

}

}

//回溯函数

void backtrack(int i)

{   //i用来指示到达的层数(第几步,从0开始),同时也指示当前选择玩了几个物品

double bound(int i);

if (i > n) //递归结束的判定条件

{

bestp = cp;

return;

}

//如若左子节点可行,则直接搜索左子树;

//对于右子树,先计算上界函数,以判断是否将其减去

if (cw + w[i] <= c)//将物品i放入背包,搜索左子树

{

cw += w[i];//同步更新当前背包的重量

cp += v[i];//同步更新当前背包的总价值

put[i] = 1;

backtrack(i + 1);//深度搜索进入下一层

cw -= w[i];//回溯复原

cp -= v[i];//回溯复原

}

if (bound(i + 1) > bestp)//如若符合条件则搜索右子树

backtrack(i + 1);

}

//计算上界函数,功能为剪枝

double bound(int i)

{   //判断当前背包的总价值cp+剩余容量可容纳的最大价值<=当前最优价值

double leftw = c - cw;//剩余背包容量

double b = cp;//记录当前背包的总价值cp,最后求上界

//以物品单位重量价值递减次序装入物品

while (i <= n && w[i] <= leftw)

{

leftw -= w[i];

b += v[i];

i++;

}

//装满背包

if (i <= n)

b += v[i] / w[i] * leftw;

return b;//返回计算出的上界

}int main()

{

int i;

printf("请输入物品的数量和背包的容量:");

cin >> n;

cin >> c;

/*printf("请输入物品的重量和价值:\n");

for(i=1;i<=n;i++)

{

printf("第%d个物品的重量:",i);

scanf("%lf",&w[i]);

printf("第%d个物品的价值是:",i);

scanf("%lf",&v[i]);

order[i]=i;

}*/

printf("请依次输入%d个物品的重量:\n", n);

for (i = 1; i <= n; i++) {

cin >> w[i];

order[i] = i;

}

printf("请依次输入%d个物品的价值:\n", n);

for (i = 1; i <= n; i++) {

cin >> v[i];

}

    knapsack();

backtrack(1);

    printf("最优价值为:%lf\n", bestp);

return 0;

}

  • 6
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值