可拆分背包问题-贪心算法 解释与C语言实现

算法思路

贪心算法
  • 贪心算法求解当下的最优解,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。

问题描述

给定5种物品和容量为10的背包
物品的重量是w={2,2,6,5,4},
其价值为v={6,3,5,4,6},
用贪心思想编程实现求解使得装入背包中物品的总价值最大的装包方案以及最终的最大价值。

代码思路

1. 定义及初始化相关变量

#define BAG_SIZE 10 //背包容量
#define THING_NUMBER 5 //物品数量

struct thing  //结构体(单个物品)
{
	int value;			//此物品的价值
	int weight;			//此物品的重量
	double b = 1.0 * value / weight;//此物品的重量价值比
}T[THING_NUMBER], temp;	//一个完整物品包T,一个临时变量

int c_w = 0;			//当前的总重量,初始为0
double max_value = 0;	//最大价值,初始为0

//初始化题目物品
T[0] = { 6,2 };
T[1] = { 3,2 };
T[2] = { 5,6 };
T[3] = { 4,5 };
T[4] = { 6,4 };

2. 按照重量价值比排序

for (int i = 0; i < THING_NUMBER; i++)
		for (int j = 0; j < THING_NUMBER; j++)
			if (T[i].b > T[j].b) {
				temp = T[i];
				T[i] = T[j];
				T[j] = temp;
			}

3. 装物品

  • 装物品分为装整件和装散件
    • 整件:只要下一物品质量装入后小于背包容量,即可装入
    • 散件:当下一物品质量装入后大于背包容量,则装散件。
      • 装入质量:背包容量 - 当前背包容量
      • 新增价值:当前价值 + 新增价值
        • =当前价值 + 下一物品价值 / 装入的重量比
        • =当前价值 + 下一物品价值 / (下一物品质量 / (背包容量 - 当前背包容量))
for(int i = 0;i< THING_NUMBER;i++)
		if (c_w + T[i].weight < BAG_SIZE) {//装完整物品
			c_w += T[i].weight; 
			max_value += T[i].value;
			printf("选择重量为:%d 价值为:%d 的物品\n", T[i].weight, T[i].value);
		}else{								//装散件
			max_value += T[i].value / (T[i].weight / (BAG_SIZE - c_w) * 1.0);
			printf("选择重量为:%d  价值为:%d 拆分成重量为:%d,价值为:%f的物品\n\n",
			T[i].weight, T[i].value,(BAG_SIZE - c_w), 
			T[i].value / (T[i].weight / (BAG_SIZE - c_w) * 1.0));
			
			printf("最大价值为:%f\n", max_value);
			break;
		}

总结

将物品按 (质量价值比) 排序→装完整物品→装散件

完整代码

C语言代码

#include<stdio.h>
#define BAG_SIZE 10 //背包容量
#define THING_NUMBER 5

struct thing
{
	int value;
	int weight;
	double b = 1.0 * value / weight;
}T[THING_NUMBER], temp;
int main() {
	int c_w = 0;
	double max_value = 0;	

	T[0] = { 6,2 };
	T[1] = { 3,2 };
	T[2] = { 5,6 };
	T[3] = { 4,5 };
	T[4] = { 6,4 };

	printf("最佳的装包方案是:\n");
	for (int i = 0; i < THING_NUMBER; i++)
		for (int j = 0; j < THING_NUMBER; j++)
			if (T[i].b > T[j].b) {
				temp = T[i];
				T[i] = T[j];
				T[j] = temp;
			}
			;
	for(int i = 0;i< THING_NUMBER;i++)
		if (c_w + T[i].weight < BAG_SIZE) {
			c_w += T[i].weight;
			max_value += T[i].value;
			printf("选择重量为:%d价值为:%d 的物品\n", T[i].weight, T[i].value);
		}
		else {
			max_value += T[i].value / (T[i].weight / (BAG_SIZE - c_w) * 1.0);
			printf("选择重量为:%d,价值为:%d 拆分成重量为:%d,价值为:%f 的物品\n", 
			T[i].weight, T[i].value,(BAG_SIZE - c_w), 
			T[i].value / (T[i].weight / (BAG_SIZE - c_w) * 1.0));

			printf("最大价值为:%f\n", max_value);
			break;
		}
	return 0;
}

运行结果

在这里插入图片描述

原创文章 3 获赞 2 访问量 144

猜你喜欢

转载自blog.csdn.net/qq_39500052/article/details/105875840