`

Python处理01背包问题

阅读更多

问题描述: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使用粒子群优化算法来解决01背包问题的可视化代码

    本项目使用Python实现的PSO算法解决了01背包问题,并提供了可视化功能,这有助于理解和调试算法的运行过程。以下是一些主要的知识点: 1. **Python基础知识**:包括数据结构(如列表、元组、字典)、控制流(for...

    使用遗传算法 在Python中解决 0-1 背包问题的简单方法_python_代码_下载

    在Python中实现0-1背包问题的遗传算法,你需要导入必要的库,如`numpy`用于处理数组和随机操作,`random`用于生成随机数。编写适应度函数、选择、交叉和变异的函数,并在主程序中调用这些函数进行迭代。 在提供的...

    蚁群算法解决01背包问题

    01背包问题是一种经典的组合优化问题,它在计算机科学、运筹学以及人工智能等领域有着广泛的应用。在这个问题中,我们有n个物品,每个物品都有一个重量w_i和价值v_i,目标是选择一部分物品放入容量为W的背包中,使得...

    Python基于动态规划算法解决01背包问题实例

    了解01背包问题及其动态规划解决方案,有助于提升处理类似组合优化问题的能力,例如完全背包问题、多重背包问题等。此外,动态规划的思想也广泛应用于其他领域,如图论中的最短路径问题、最长公共子序列等。掌握这一...

    python基于递归解决背包问题详解

    总结来说,Python中的递归可以优雅地解决背包问题,虽然在大规模数据面前可能效率不高,但它展现了递归在解决复杂问题时的简洁性和直观性。理解递归是学习算法和数据结构的重要部分,它有助于培养解决问题的能力。在...

    基于Python+粒子群优化算法来解决01背包问题.zip

    总的来说,基于Python和粒子群优化算法解决01背包问题,不仅能够提供一种直观的求解思路,还能通过编程实践加深对优化算法和组合优化问题的理解。此外,这种组合也为我们提供了灵活的平台,可以进一步研究和改进优化...

    01背包问题动态规划python案例.rar

    01背包问题是一种经典的计算机算法问题,主要应用于资源分配、任务调度等领域。在这个问题中,我们有一个容量为W的背包,以及n件物品,每件物品都有一个重量w[i]和一个价值v[i]。目标是选取不超过背包容量的物品,...

    基于Python和粒子群算法解决01背包问题并进行可视化.zip

    总的来说,这个项目结合了Python编程、粒子群优化算法和数据可视化,为解决01背包问题提供了一个创新的视角。通过这个过程,我们可以更好地理解组合优化问题的求解策略,以及如何利用进化计算方法处理复杂问题。同时...

    python语言解决背包问题,使用递归和动态规划两种思路并比较运行速度

    本文将探讨如何使用Python语言来解决01背包问题,通过递归和动态规划两种方法,并对比它们的运行速度。 首先,我们来看递归解决方案。递归方法基于问题的子结构,即每次尝试将一个物品放入背包或不放入背包,然后对...

    背包问题算法python实现.rar

    在处理背包问题时,Python提供了丰富的数据结构和内置函数,使得编写动态规划解决方案变得相对容易。然而,由于Python的解释性,其运行效率可能不如编译型语言如C++或Java。在处理大规模问题时,可能需要考虑优化...

    0/1背包问题(蛮力、动态规划、回溯、分支限界法)

    动态规划法则更适合处理中等规模的问题,但需要较大的内存空间;回溯法和分支限界法则通过剪枝策略有效减少了搜索空间,提高了效率,尤其是分支限界法,更加侧重于找到最优解,因此在实际应用中有着广泛的应用前景。...

    动态规划 01背包问题 程序和代码

    在压缩包中的代码,很可能是用某种编程语言(如C++、Python或Java)实现的01背包问题的动态规划解法。代码通常会包含初始化dp数组、遍历物品并根据状态转移方程更新dp数组的过程,以及最后返回dp[n][W]作为结果。 ...

    用python语言来实现了背包问题.zip

    4. **时间复杂度与空间复杂度**:Python代码会涉及计算时间复杂度和空间复杂度,一般来说,0-1背包问题的时间复杂度为O(nW),其中`n`是物品数量,`W`是背包容量;空间复杂度同样为O(nW)。 5. **数据结构**:Python...

    背包问题祥解.doc

    【背包问题】是一种经典的优化问题,广泛应用于计算机科学和运筹学中,主要涉及如何在有限的资源约束下实现最大化收益或效率。该问题在中国通常有两种表述:一是寻找最佳物品组合以达到最大利润,二是确定能否选取...

    Python背包问题动态规划求解(一维和二维数组).zip

    Python中的背包问题动态规划求解主要涉及到数据结构与算法领域,是解决一类经典优化问题的方法。背包问题通常出现在资源有限的情况下,如何选择物品以获得最大价值。动态规划是一种通过将复杂问题分解为子问题来求解...

    backtracking_N皇后_01背包_回溯算法_售货员问题_图的m着色_

    在Python中,通过巧妙地设计和实现,可以有效地解决N皇后、01背包、旅行售货员和图的m着色等复杂问题。理解并掌握回溯算法的思想和技巧,对于提升编程能力,尤其是处理复杂问题的分析和解决能力,具有重要意义。

    3-增量背包问题四类实例

    在处理"3-增量背包问题四类实例"时,首先需要理解每个实例的具体规则和约束。然后,可以通过编程实现这些算法,对各种实例进行求解。分析和比较不同实例的解决方案,可以帮助我们理解各种策略在不同情况下的性能和...

    01背包问题的回溯求法1

    01背包问题是一种经典的组合优化问题,它在计算机科学,特别是算法设计与分析领域中有着广泛的应用。这个问题的设定是这样的:我们有一组物品,每件物品都有一个重量和一个价值,我们需要选择其中的一些物品放入一个...

    背包问题(最大收益分枝定界法)

    背包问题是一种经典的优化问题,在计算机科学和运筹学中有着广泛的应用。它的核心目标是给定一组物品,每种物品都有一定的重量和价值,求解如何在不超过背包总承重限制的情况下,选择物品以使总价值最大化。在这个...

    背包问题所有解算法及程序实现

    背包问题是一种经典的优化问题,在计算机科学和运筹学中有着广泛的应用。它通常用来模拟资源有限的情况下,如何选择物品以获得最大价值或最小成本。在这个主题中,我们将深入探讨背包问题的各种解法,并通过程序实现...

Global site tag (gtag.js) - Google Analytics