可拆分揹包問題-貪心算法 解釋與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;
}

運行結果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章