问题描述:
假定背包的最大容量为W(千克),有N件物品,每件物品都有自己的价值和重量,将哪些物品放入背包中可使得背包内物品的总价值最大。
假设:
W = 10; N = 4;
物品重量数组:weights[4] = {5, 4, 6, 3};
物品价值数组:values[4] = {10, 40, 30, 50}
可参考网址:http://www.importnew.com/13072.html
解决这个问题可以使用动态规划法,即先解决部分,再利用已解决的内容,解决后面的问题。
具体方法是设置了一个二维表,行代表物品数量,从0个物品到N个物品一共N+1行,列代表背包剩余可容纳重量同理有W+1列。每一个元素都是代表背包剩余重量为w时,有n个物品时,背包可容纳的最大物品价值。
第0(i-1=0)行代表0个物品的时候,显然背包没物品可装,最大价值均为0;
第0列(w=0)代表背包剩余重量为0时,显然,最大价值也都为0.
第1(i-1 = 1)行第一列开始,代表有一个物品时,背包剩余重量从1到W时,背包可容纳最大物品价值,显然从W>=weights[i-1]开始,最大价值都未物品1的价值。
第2行第一列开始,代表有物品1,2时,背包剩余重量从1到W时,背包可容纳最大物品价值。那么,此时如果背包剩余重量>=物品2重量时,是否应该将物品2放入背包呢,这里就是重点了。
两种方案。
方案一:如果把物品2装进去,这时背包剩余重量 = W - weights[i - 1],去查一下第一行,的剩余重量处,背包可容纳最大物品价值,将这个价值 + 物品2价值,就是背包将物品2装入以后的价值。
方案二:不装物品2,那么去查询一下背包剩余重量W时,第一行的那个最大价值。
比较方案一,方案二的两个价值,哪个大,取哪个。
理解一下:就是说我装了物品2,物品2的价值加上剩余的空间的最大价值(之前计算出来了的)是不是比不装物品2时背包剩余空间的最大价值(也是上一行已经计算出来的)大,大的话,就装进去,否则就不装,最大价值还取剩余重量W时第一行的值。
算法描述完了,可能不太好理解,建议看看那个网址里面的图文。
如果还无法理解,看看下面的C代码吧,这段C代码我在电脑上编译并运行过的,是正确的代码。C代码看了以后,反复阅读方案一、方案二这两行,相信你会懂的。
结果的二维表先贴出来,看着二维表,或许更好理解。
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
0 | 0 | 0 | 0 | 0 | 10 | 10 | 10 | 10 | 10 | 10 | |
0 | 0 | 0 | 0 | 40 | 40 | 40 | 40 | 40 | 50 | 50 | |
0 | 0 | 0 | 0 | 40 | 40 | 40 | 40 | 40 | 50 | 70 | |
0 | 0 | 0 | 50 | 50 | 50 | 50 | 90 | 90 | 90 | 90 |
add objects: [4][2]
weight:7
比如最后一行最后一列数据90举例,这一行最后一个数据的判断:物品4重量为3,背包剩余重量W为10,如果把物品4装入背包,那么背包剩余重量W - 3 = 10 - 3 = 7,查询一下上一行中W = 7,即第0~10列中的第7列(注意从0开始数),最大价值为40 + 物品4的价值50 = 90;
如果不把物品4,放入背包,剩余重量W = 10,查询上一行,W = 10,即最后一列,第10列的最大价值为70。
90 > 70,所以物品4应该放入背包。
这里所有计算都是基于上一行已经计算出的最大价值。
背包可容纳物品最大价值就等于表中所有数据中的最大值。
那么哪些物品被放入背包了呢,从最后一个数据开始看,即90,假设这个值的位置是values[i][w],那么当values[i-1][w] != values[i][w]时,物品i-1,即物品4肯定是被放入背包了。因为如果物品4不应该放入背包的话,那么上一行的值和这个值应该相等(因为包不包含物品4,都不应该影响背包可容纳最大价值)。这里满足了,上一行是70,所以物品4放入背包。背包剩余重量 = 10 - 3 = 7。
再看剩余重量为7,上一行数据,即40,它是否满足values[i-1][w] != values[i][w],它不满足,所以物品3没放入。此时W = 7不变。
继续看剩余重量为7的上一行数据,即10,不等于40,所以物品2放入背包。剩余重量7 - 4 = 3.
再看上一行W = 3时,为0,这一行是否等于再上一行呢,相等,所以物品1也没有放入背包,到这里,判断就结束了。这就是代码showWhichAdd实现的功能。
#include <stdio.h> #include <stdlib.h> #include <string.h> int **getMaxWeightValuesTable(int *weights, int *values, int num, int maxWeight) { int **maxValues = (int **)malloc((num+1) * sizeof(int*)); memset(maxValues, 0, (num+1) * sizeof(int*)); int i,weight; for (i=0; i<=num; i++) { maxValues[i] = (int*)malloc((maxWeight+1) * sizeof(int)); memset(maxValues[i], 0, (maxWeight+1) * sizeof(int)); } for (i=1; i<=num; i++) { for (weight=1; weight<=maxWeight; weight++) { if (weight >= weights[i-1]) { // 背包剩余载重还能装这个物品 if (values[i-1] + maxValues[i-1][weight-weights[i-1]] > maxValues[i-1][weight]) { maxValues[i][weight] = values[i-1] + maxValues[i-1][weight-weights[i-1]]; } else { maxValues[i][weight] = maxValues[i-1][weight]; } } else { maxValues[i][weight] = maxValues[i-1][weight]; } } } return maxValues; } void showWhichAdd(int **maxValues, int *weights, int num, int maxWeight) { int i; int weight = maxWeight; printf("add objects: "); for (i=num; i>=1; i--) { if (maxValues[i][weight] != maxValues[i-1][weight]) { printf("[%d]", i); weight -= weights[i-1]; } } printf("\nweight:%d\n", maxWeight - weight); } int main(int argc, char **argv) { int weights[] = {5, 4, 6, 3}; int values[] = {10, 40, 30, 50}; int num = 4; int maxWeight = 10; int **maxValues = getMaxWeightValuesTable(weights, values, num, maxWeight); int i, weight; for (i=0; i <= num; i++) { for (weight=0; weight <= maxWeight; weight++) { printf("%d\t", maxValues[i][weight]); } printf("\n"); } showWhichAdd(maxValues, weights, num, maxWeight); for(i=0; i<=num; i++) { free(maxValues[i]); } free(maxValues); maxValues = NULL; return 0; }
相关推荐
- 如果j(i),V(i, j) = V(i-1, j),背包装不下第i个物品,所以价值不变。 - 如果j>=w(i),V(i, j) = max{V(i-1, j), V(i-1, j-w(i)) + v(i)},在装和不装第i个物品之间选择价值更大的方案。 接下来,通过填充这个...
可以通过归纳法证明动态规划表格中的C[i][j]总是给出前i个物品中选择部分或不选,使得总重量不超过j的最大价值。基本步骤是先证明基础情况(i=0或j=0)成立,然后通过状态转移方程递归地推导出所有其他情况。 5. *...
3. **背包填充**:`beibao`函数实现了贪心策略,从后往前遍历物品,尽可能地将物品装入背包,直到背包装不下更多物品为止。 4. **主函数逻辑**:在`main`函数中,先生成物品,然后让用户输入背包的容量,调用`...
- **0/1背包问题**:每个物品只能被完全取或不取,寻求最大价值的装载方案。 - **矩阵连乘积问题**:在计算多个矩阵相乘时,寻找最佳顺序以最小化计算量。 - **凸多边形最优三角剖分**:在几何优化中,找到分割...
三维装箱问题是一类典型的组合优化问题,核心在于如何将一系列长方体物品以一种方式装入到更大的容器中,以便最大化使用容器的空间或最大化装入的物品数量。在实际应用中,装箱问题具有广泛的意义,涉及计算机任务...
6. **除法的应用**:经常涉及物品的平均分配问题,如平均每次运输的数量、平均每人所需资源等。 7. **乘法与倍数**:解决涉及倍数的问题,例如每两人一张课桌,需要计算多少张课桌。 8. **估算与近似值**:在一些...
- **供应链管理的概念**:是指对整个供应链的协调管理,旨在最大化整个供应链的价值创造能力。 - **供应链的结构模式**主要包括:直线型、网状型等不同形式,具体取决于供应链中各节点企业的相互作用关系。 - **供应...
1. **集装化/集合包装**:通过将多个小件物品组合成一个大件进行运输和存储。 2. **TEU**:Twenty-foot Equivalent Unit,即标准箱单位,用于衡量集装箱的大小。 #### 重点问题 1. **集装化的经济意义**:提高运输...
周转材料是指可以多次使用并在使用过程中物质形态不变的物品,如模具、包装物等;生产性生物资产收获的农产品指企业为了生产农产品而培育的生物资产,如农作物等。明确存货范围是进行合理税务处理的基础。 其次,...
- A类物品价值最高,占总价值的70%-80%,但种类最少;B类物品居中;C类物品种类最多,但价值最低。 - 根据分类结果制定不同的管理策略。 #### 2. 第四方物流的理解 第四方物流(Fourth-Party Logistics, 4PL)是指...
然而,库存也存在不合理性,可能会产生搬运和防护等浪费工序,增加资金占用、利息及管理费用,导致物品价值降低和仓库空间的占用。 常见的库存策略包括EOQ(经济订货量)模型、定期订货模型(T,S)和定量订货模型...
- **综合评价法**:采用层次分析法(AHP)、模糊综合评价等方法,对物流系统的多个指标进行综合考量。 #### 3. 成本优化策略 - **运输路径优化**:利用算法(如遗传算法、蚁群算法)寻找最短路径或最低成本路径,...
- 库存管理中的ABC分析法有助于确定重点管理的商品,A类为高价值或重要商品,B类为中等,C类为低价值或次要商品。 - 远程仓库的选择与跨国公司的全球战略密切相关,有利有弊,如降低成本、响应速度,但也可能增加...
1. 重新设计仓库布局:根据物品的出库频率和体积,采用ABC分析法,将高频率、高价值的商品放置在易于拣选的位置。 2. 动态路径规划:运用物流学原理,规划最优拣选路径,减少拣选时间和提高工作效率。 三、拣选系统...
18. 80/20原则:采购工作应重点关注价值高但数量少的物品,优化资源配置。 19. 危险货物要素:危险货物具有特殊性质,需要特殊防护措施,但不包括运送时间紧迫。 20. 旧物资处理:这部分可能涉及到废旧物资的回收...
1. **物流定义与功能**:物流是指物品从生产地到消费地的实体流动过程,它包括运输、仓储、装卸搬运、包装、流通加工、配送、信息处理等基本功能。理解这些功能是深入学习物流管理的基础。 2. **供应链管理**:物流...
1. **物流**:物流是物品从供应地到接收地的实体流动过程,涉及运输、储存、装卸、包装、流通加工、配送、信息处理等活动。 2. **信息资源**:信息资源是信息、数据、知识及其处理过程的集合,是支持决策和组织运行...
作为销售包装材料,透明度好、表面光泽、造型美观等特点能够提升商品的价值和吸引力,这是**A、附加价值性能** 的体现。良好的包装不仅可以保护商品,还可以增强其市场竞争力。 #### 集装箱的适航条件 集装箱应...
库存管理中的ABC分类法是通过区分重要性来优化库存,MRP(物料需求计划)帮助预测和规划物料需求,而JIT(准时制生产)则旨在降低库存,减少等待时间,实现零库存的理想状态。 总的来说,仓库管理员培训内容全面...