问题描述:01背包是在N件物品取出若干件放在空间为V的背包里,每件物品的体积为V1,V2……Vn,与之相对应的价值为P1,P2……Pn(所有的体积值均为整数)。
环境工具:win7 python2.7
解决过程:考虑用动态规划的方法来解决
阶段 【在前N件物品中,选取若干件物品放入背包中】
状态 【在前N件物品中,选取若干件物品放入所剩空间为W的背包中的所能获得的最大价值】
决策 【第N件物品放或者不放】
可以写出动态转移方程
用f[i,j]表示在前 i 件物品中选择若干件放在所剩空间为 j 的背包里所能获得的最大价值
f[i,j]=max{f[i-1,j-Wi]+Pi (j>=Wi), f[i-1,j]}
基本上所有跟背包相关的问题的方程都是由它衍生出来的。
演变解释@考虑在V的空间下,放入N件物品能获得最大价值(前N-1物品是最大价值的,第N件产品可以放进去)
=》考虑在V - Vn的空间下,放入N-1件物品能获得最大价值(前N-2物品是最大价值的,第N-1件物品可以放进去)
=》考虑在V - Vn-1 - Vn的空间下,放入N-2件物品能获得最大价值(前N-3物品是最大价值的,第N-2件物品可以放进去)
......
=》考虑在V - V3 - V4... - Vn的空间下,放入2件物品能获得最大价值(前1物品是最大价值的,第2件物品可以放进去)
=》考虑在V - V2 - V3 - V4... - Vn的空间下,放入1件物品能获得最大价值(前0物品的价值是0,第1件物品可以放进去)
源代码如下
#! C:\\Python27\\python.exe
# -*- coding:utf-8 -*-
import copy
class DynamicBag:
def __init__(self, limitVolume, itemsVolume, itemsValue):
self.limitVolume = limitVolume #最大体积上限,容积
self.itemsVolume = itemsVolume #所有项的每项的体积
self.itemsValue = itemsValue #所有项的每项的价值
self.resultSumVolume = 0 #最大价值的占用体积
self.resultSumValue = 0 #最大价值
self.resultItemsVolume = [] #最大价值的每项体积
self.resultItemsValue = [] #最大价值的每项价值
def dynamicSuitResult(self):
itemsCount = len(self.itemsVolume)
if itemsCount == len(self.itemsValue):
allItems = [] #所有项的下标
self.itemsVolume.append(0) #添加0项,方便计算
self.itemsValue.append(0)
itemsCount = itemsCount + 1
for k in range(itemsCount):
allItems.append(k)
(self.resultSumVolume, self.resultSumValue, resulItems) = self.dynamic01Bag(allItems[itemsCount-1], limitVolume, allItems)#获得最大价值的占用体积,最大价值,组成项的索引
del resulItems[resulItems.index(itemsCount-1)]#去除0项索引
for k in resulItems:
self.resultItemsVolume.append(self.itemsVolume[k])#根据最大价值的组成项的索引获得项
self.resultItemsValue.append(self.itemsValue[k])
else:
print("args error!")
return (self.resultSumVolume, self.resultSumValue, self.resultItemsVolume, self.resultItemsValue)#返回 最大价值的占用体积,最大价值,最大价值的每项体积,最大价值的每项价值
def dynamic01Bag(self, oneItem, limitVolume, allItems):
suitSumVolume = 0 #当前项的最大价值占用体积
suitSumValue = 0 #当前项的当前最大价值
suitItems = [] #当前项的当前最大价值的组成项的索引
partItems = copy.copy(allItems)
del partItems[partItems.index(oneItem)]#去掉当前项
if len(partItems)==1:#前一项只有一项
if limitVolume < self.itemsVolume[partItems[0]]:#容积小于前一项
return (suitSumVolume, suitSumValue, suitItems)
elif limitVolume >= (self.itemsVolume[partItems[0]] + self.itemsVolume[oneItem]):#容积大于等于前一项+当前项
suitSumVolume = self.itemsVolume[partItems[0]] + self.itemsVolume[oneItem]
suitSumValue = self.itemsValue[partItems[0]] + self.itemsValue[oneItem]
suitItems.append(oneItem)
suitItems.append(partItems[0])
return (suitSumVolume, suitSumValue, suitItems)
else:#容积大于等于前一项,小于前一项+当前项
suitSumVolume = self.itemsVolume[partItems[0]]
suitSumValue = self.itemsValue[partItems[0]]
suitItems.append(partItems[0])
return (suitSumVolume, suitSumValue, suitItems)
else:#前一项有多项
suitVolume1 = 0
suitValue1 = 0
suitVolume2 = 0
suitValue2 = 0
suitIndex1 = 0
suitIndex2 = 0
result = []
for k in range(len(partItems)):
(aSumVolume, bSumValue, cItems)=self.dynamic01Bag(partItems[k], limitVolume - self.itemsVolume[oneItem], partItems)#对多个前一项的每项求最大值
result.append((aSumVolume, bSumValue, cItems))
if (aSumVolume + self.itemsVolume[oneItem]) <= limitVolume:#存在容积大于等于前一项+当前项的情况,获取最大的前一项+当前项
if (bSumValue + self.itemsValue[oneItem]) > suitValue1:#对多个前一项的最大值,求最优
suitVolume1 = aSumVolume + self.itemsVolume[oneItem]
suitValue1 = bSumValue + self.itemsValue[oneItem]
suitIndex1 = k
if bSumValue > suitValue2:#容积小于所有的前一项+当前项情况下使用,获取最大的前一项
suitVolume2 = aSumVolume
suitValue2 = bSumValue
suitIndex2 = k
if suitValue1 > 0:#存在容积大于等于前一项+当前项的情况,获取最大的前一项+当前项
suitSumVolume = suitVolume1
suitSumValue = suitValue1
suitItems.append(oneItem)
suitItems.extend(result[suitIndex1][2])
return (suitSumVolume, suitSumValue, suitItems)
else:#容积小于所有的前一项+当前项情况下使用,获取最大的前一项
suitSumVolume = suitVolume2
suitSumValue = suitValue2
suitItems.extend(result[suitIndex2][2])
return (suitSumVolume, suitSumValue, suitItems)
#算法验证
if __name__ == '__main__':
limitVolume = 20#体积上限
itemsVolume = [1,2,5,7,9]#单个总体积
itemsValue = [1,1,1,2,2]#单个总价值
hk01bag = DynamicBag(limitVolume, itemsVolume, itemsValue)
(resultSumVolume, resultSumValue, resultItemsVolume, resultItemsValue) = hk01bag.dynamicSuitResult()
print '最大价值:'+str(resultSumValue)
print '最大价值的单个价值:'
print resultItemsValue
print '最大价值的总体积:'+str(resultSumVolume)
print '最大价值的单个总体积:'
print resultItemsVolume
相关推荐
本项目使用Python实现的PSO算法解决了01背包问题,并提供了可视化功能,这有助于理解和调试算法的运行过程。以下是一些主要的知识点: 1. **Python基础知识**:包括数据结构(如列表、元组、字典)、控制流(for...
在Python中实现0-1背包问题的遗传算法,你需要导入必要的库,如`numpy`用于处理数组和随机操作,`random`用于生成随机数。编写适应度函数、选择、交叉和变异的函数,并在主程序中调用这些函数进行迭代。 在提供的...
01背包问题是一种经典的组合优化问题,它在计算机科学、运筹学以及人工智能等领域有着广泛的应用。在这个问题中,我们有n个物品,每个物品都有一个重量w_i和价值v_i,目标是选择一部分物品放入容量为W的背包中,使得...
动态规划算法不仅在解决01背包问题上有其独特优势,而且在处理其他组合优化问题,如完全背包问题、多重背包问题等方面也有广泛的应用。此外,动态规划的思想在图论、最短路径问题、最长公共子序列等问题中也非常有用...
总结来说,Python中的递归可以优雅地解决背包问题,虽然在大规模数据面前可能效率不高,但它展现了递归在解决复杂问题时的简洁性和直观性。理解递归是学习算法和数据结构的重要部分,它有助于培养解决问题的能力。在...
总的来说,基于Python和粒子群优化算法解决01背包问题,不仅能够提供一种直观的求解思路,还能通过编程实践加深对优化算法和组合优化问题的理解。此外,这种组合也为我们提供了灵活的平台,可以进一步研究和改进优化...
01背包问题是一种经典的计算机算法问题,主要应用于资源分配、任务调度等领域。在这个问题中,我们有一个容量为W的背包,以及n件物品,每件物品都有一个重量w[i]和一个价值v[i]。目标是选取不超过背包容量的物品,...
总的来说,这个项目结合了Python编程、粒子群优化算法和数据可视化,为解决01背包问题提供了一个创新的视角。通过这个过程,我们可以更好地理解组合优化问题的求解策略,以及如何利用进化计算方法处理复杂问题。同时...
本文将探讨如何使用Python语言来解决01背包问题,通过递归和动态规划两种方法,并对比它们的运行速度。 首先,我们来看递归解决方案。递归方法基于问题的子结构,即每次尝试将一个物品放入背包或不放入背包,然后对...
在处理背包问题时,Python提供了丰富的数据结构和内置函数,使得编写动态规划解决方案变得相对容易。然而,由于Python的解释性,其运行效率可能不如编译型语言如C++或Java。在处理大规模问题时,可能需要考虑优化...
动态规划法则更适合处理中等规模的问题,但需要较大的内存空间;回溯法和分支限界法则通过剪枝策略有效减少了搜索空间,提高了效率,尤其是分支限界法,更加侧重于找到最优解,因此在实际应用中有着广泛的应用前景。...
在压缩包中的代码,很可能是用某种编程语言(如C++、Python或Java)实现的01背包问题的动态规划解法。代码通常会包含初始化dp数组、遍历物品并根据状态转移方程更新dp数组的过程,以及最后返回dp[n][W]作为结果。 ...
背包问题是中国及世界各地常见的优化问题,不仅在学术研究中占据重要地位,还在物流、资源分配等多个领域有着广泛的应用。其核心在于如何在有限的资源约束下实现最大化收益或效率。问题通常有两种表述方式:一种是...
4. **时间复杂度与空间复杂度**:Python代码会涉及计算时间复杂度和空间复杂度,一般来说,0-1背包问题的时间复杂度为O(nW),其中`n`是物品数量,`W`是背包容量;空间复杂度同样为O(nW)。 5. **数据结构**:Python...
Python中的背包问题动态规划求解主要涉及到数据结构与算法领域,是解决一类经典优化问题的方法。背包问题通常出现在资源有限的情况下,如何选择物品以获得最大价值。动态规划是一种通过将复杂问题分解为子问题来求解...
在Python中,通过巧妙地设计和实现,可以有效地解决N皇后、01背包、旅行售货员和图的m着色等复杂问题。理解并掌握回溯算法的思想和技巧,对于提升编程能力,尤其是处理复杂问题的分析和解决能力,具有重要意义。
在处理"3-增量背包问题四类实例"时,首先需要理解每个实例的具体规则和约束。然后,可以通过编程实现这些算法,对各种实例进行求解。分析和比较不同实例的解决方案,可以帮助我们理解各种策略在不同情况下的性能和...
01背包问题是一种经典的组合优化问题,它在计算机科学,特别是算法设计与分析领域中有着广泛的应用。这个问题的设定是这样的:我们有一组物品,每件物品都有一个重量和一个价值,我们需要选择其中的一些物品放入一个...
背包问题是一种经典的优化问题,在计算机科学和运筹学中有着广泛的应用。它的核心目标是给定一组物品,每种物品都有一定的重量和价值,求解如何在不超过背包总承重限制的情况下,选择物品以使总价值最大化。在这个...
背包问题是一种经典的优化问题,在计算机科学和运筹学中有着广泛的应用。它通常用来模拟资源有限的情况下,如何选择物品以获得最大价值或最小成本。在这个主题中,我们将深入探讨背包问题的各种解法,并通过程序实现...