代码实现流程:
- 排序:首先调用
qsort
对物品进行排序,使得单位重量价值高的物品排在前面。 - 贪心算法:调用
knapsackGreedy
函数,按照排序后的顺序依次选择物品。- 如果当前物品的重量小于或等于剩余容量,完全放入背包并更新剩余容量。
- 如果当前物品的重量超过剩余容量,则放入部分物品(根据剩余容量),并结束选择。
- 输出结果:最后通过
printf
输出背包所能获得的最大价值。
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int value;
int weight;
double valuePerWeight;
} Item;
/*
通常用于排序算法中,特别是 qsort(C标准库提供的快速排序函数)
函数的作用是比较两个 Item 类型的元素,按照 valuePerWeight(单位重量价值)进行排序
*/
int comp(const void* a, const void* b)
{
Item* itemA = (Item*)a;
Item* itemB = (Item*)b;
return (itemB->valuePerWeight > itemA->valuePerWeight) - (itemA->valuePerWeight - itemB->valuePerWeight);
}
/*
capacity:背包的总容量。
items:指向 Item 类型数组的指针,表示所有待选择的物品。
每个 Item 应该包含至少两个成员变量:value(物品的价值)和 weight(物品的重量)。
numItems:物品的数量。
*/
int knapsackGreedy(int capacity, Item* items, int numItems)
{
int totalValue = 0;
int remainingCapacity = capacity;
for (int i = 0; i < numItems; i++)
{
// printf("item[%d] ", items[i].value);
// 如果当前物品的重量 小于 背包可剩余装的容量,可以继续装入背包
if (items[i].weight <= remainingCapacity)
{
totalValue += items[i].value;
remainingCapacity -= items[i].weight;
printf("物品%d - 价值: %d, 重量: %d\n", i + 1, items[i].value, items[i].weight);
}
}
return totalValue;
}
int main()
{
Item items[] = {
{60,10,6.0},
{70,10,7.0},
{40,8,5.0},
{66,6,11.0}
};
// 背包总容量 38
int capacity = 38;
//sizeof(items) / sizeof(items[0]) 就等于数组中元素的个数,即物品的数量
int numItems = sizeof(items) / sizeof(items[0]);
printf("numItems = %d\n", numItems);
/*
qsort 是 C 标准库中的一个函数,用于对数组进行排序
items:待排序的数组。
numItems:数组的元素个数,即物品的数量。
sizeof(Item):每个元素(Item 类型)的大小,用于告诉 qsort 如何在内存中正确地移动元素。
comp:一个比较函数,用于定义排序的规则。
*/
qsort(items, numItems, sizeof(Item), comp);
/*
使用 qsort 排序后,物品按单位重量价值顺序变为:
{66, 6, 11.0}(单位重量价值11.0)
{70, 10, 7.0}(单位重量价值7.0)
{60, 10, 6.0}(单位重量价值6.0)
{40, 8, 5.0} (单位重量价值5.0)
通过贪心算法选择物品:
第一个物品 {66, 6, 11.0} 可以完全放入背包,剩余容量 32,背包价值增加 66。
第二个物品 {70, 10, 7.0} 可以完全放入背包,剩余容量 22,背包价值增加 70。
第三个物品 {60, 10, 6.0} 可以完全放入背包,剩余容量 12,背包价值增加 60。
第四个物品 {40, 8, 5.0} 可以完全放入背包,剩余容量 4,背包价值增加 40。
最终背包的最大价值为:66 + 70 + 60 + 40 = 236。
*/
int maxValue = knapsackGreedy(capacity, items, numItems);
printf("\n");
printf("最大价值为:%d \n", maxValue);
}
最后输出结果:
背包存放物品如下:
物品1 - 价值: 66, 重量: 6
物品2 - 价值: 70, 重量: 10
物品3 - 价值: 60, 重量: 10
物品4 - 价值: 40, 重量: 8
最大价值为:236