贪心法求解部分背包问题

一、求解部分背包问题
1、问题描述
在这里插入图片描述
在这里插入图片描述
2、贪心策略选取
(1)价值最大
①选择价值最大的物品,因为这可以尽可能快地增加背包的总价值。
②背包容量却可能消耗得太快,使得装入背包的物品个数减少,从而不能保证目标函数达到最大。
(2)重量最轻
①选择重量最轻的物品,因为这可以装入尽可能多的物品,从而增加背包的总价值。
②背包的价值却没能保证迅速增长,从而不能保证目标函数达到最大。
(3)单位重量价值最大
选择单位重量价值最大的物品,在背包价值增长和背包容量消耗两者之间寻找平衡。

贪心策略:选择单位重量价值最大的物品。
①每次从物品集合中选择单位重量价值最大的物品,如果其重量小于背包容量,就可以把它装入,并将背包容量减去该物品的重量;
②新的背包问题产生了,不同之处在于:物品集合中物品变少了,同时背包的容量也变小了。
3、算法设计
设背包容量为C,共有n个物品,物品重量存放在数组w[n]中,价值存放在数组v[n]中,问题的解存放在数组x[n]中。
在这里插入图片描述
4、举例在这里插入图片描述
在这里插入图片描述
5、算法设计
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
6、算法分析
排序的时间复杂性为O(nlog2n),while循环的时间为O(n),所以本算法的时间复杂度为O(nlog2n)
7、部分背包问题与0/1背包问题
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
部分背包问题是指,有一个背包容量为C,有n个物品,每个物品有一个重量wi和一个价值vi,可以取走物品的一部分,求背包所能装下的最大价值。 贪心法求解部分背包问题的思路是,按照每个物品的单位重量价值从大到小排序,然后依次装入物品,直到背包装满为止。如果当前物品无法完全装入背包,则将其部分装入,直到背包装满。 以下是部分背包问题的C语言代码实现: ```c #include <stdio.h> #include <stdlib.h> typedef struct { double weight; // 物品重量 double value; // 物品价值 double unit_value; // 物品单位重量价值 } Item; // 按照物品单位重量价值从大到小排序 int cmp(const void *a, const void *b) { Item *item1 = (Item *)a; Item *item2 = (Item *)b; return (item2->unit_value - item1->unit_value) > 0 ? 1 : -1; } int main() { int n = 5; // 物品数量 int C = 10; // 背包容量 Item items[n]; items[0] = (Item){2, 6, 0}; items[1] = (Item){2, 3, 0}; items[2] = (Item){6, 5, 0}; items[3] = (Item){5, 4, 0}; items[4] = (Item){4, 6, 0}; // 计算每个物品的单位重量价值 for (int i = 0; i < n; i++) { items[i].unit_value = items[i].value / items[i].weight; } // 按照物品单位重量价值从大到小排序 qsort(items, n, sizeof(Item), cmp); double value = 0; // 背包所能装下的最大价值 int i = 0; // 当前物品下标 while (C > 0 && i < n) { if (C >= items[i].weight) { value += items[i].value; C -= items[i].weight; } else { value += C * items[i].unit_value; C = 0; } i++; } printf("背包所能装下的最大价值为%f\n", value); return 0; } ``` 在实现中,首先定义了一个Item结构体来存储物品的重量、价值和单位重量价值。然后计算每个物品的单位重量价值,并按照从大到小的顺序排序。最后依次取出每个物品,如果能够完全装入背包,则将其全部装入;否则,将其部分装入,直到背包装满为止。最终输出背包所能装下的最大价值。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值