0/1背包问题之穷举解法

2023-05-16

[0-1背包问题]有一个背包,背包容量是M=150kg。有7个物品,物品不可以分割成任意大小。(这句很重要
要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。
物品 A B C D E F G
重量 35kg 30kg 6kg 50kg 40kg 10kg 25kg
价值 10 40 30 50 35 40 30

要想得到最优的结果,最容易想到的就是穷举法,那么首先用穷举法来处理这个问题。

首先就是要看穷举一共有多少种拿法, 27 种拿法,也就是说一共有128种方法,这里面一定有最优的,我们只要计算出128种拿法的价值,就一定能选出最优的拿法,当然要排除掉超过总容量的集合。

为了专业一点,首先要定义一个类Item来将问题转化为计算机能够理解的问题。

# item have three attribute: name,weight,value
class Item(object):
def __init__(self,n,v,w):
    self.name=n
    self.weight=float(w)
    self.value=float(v)

def getName(self):
    return self.name

def getValue(self):
    return self.value

def getWeight(self):
    return self.weight

def __str__(self):
    result = ' < '+self.name+' , '+str(self.value)+' , '+str(self.weight) + '>'
    return result

下面的这段算法提供了整个解空间,她的返回值就是整个 27 个集合

#get the binary representation of a num n
def getBinaryRep(n,numDigitals):
    result=''
    while n>0:
        result=str(n%2)+result
        n=n//2

    if len(result)>numDigitals:
        raise ValueError("not enough digits")

    for i in range(numDigitals - len(result)):
        result = '0'+result
    return result

def genPowerSet(L):
    powerset=[]
    for i in range(2**len(L)):
        binstr = getBinaryRep(i,len(L))
        subset = []
        for j in range(len(L)):
            if binstr[j]=='1':
               subset.append(L[j])
        powerset.append(subset)
    return powerset

这段代码需要详细的解释一下。
getBinaryRep 就是获取一个数的指定位数的二进制表示。不足的位数补0,运行这个函数的结果如下所示:

print getBinaryRep(7,7)
0000111

genPowerSet 这个函数可以获取指定输入集合的所有子集合的表示。
原理如下:

我们可以把输入集合当做一个元素的列表,任意一个子集合看成是一个只包含了0,1的字符串,0表示不包含指定元素,1表示包含指定元素,那么全0就表示空集,全1就表示包括所有元素的集合(输入集合)。因此0– 27 所有的数的2进制就代表了输入集合的所有子集,也就是找到了问题的全部子空间。

函数的运行结果示例:

L = ['A','B','C']
result = genPowerSet(L)
for i in range(len(result)):
    print result[i]

[]
['C']
['B']
['B', 'C']
['A']
['A', 'C']
['A', 'B']
['A', 'B', 'C']

准备工作做完了,下面来利用穷举法解决一下0/1背包问题

from Item import Item
import genPowerSet

def buildItem():
    names=['A','B','C','D','E','F','G']
    vals = [35,30,6,50,40,10,25]
    weights=[10,40,30,50,35,40,30]
    Items=[]
    for i in range(len(names)):
        Items.append(Item(names[i],vals[i],weights[i]))
    return Items

# Brute-force method
def chooseBest(pset,maxWeight,getVal,getWeight):
    bestVal = 0.0
    bestSet=None
    for items in pset:
        itemsVal=0.0
        itemsWeight=0.0
        for item in items:
            itemsVal +=getVal(item)
            itemsWeight +=getWeight(item)
            if itemsWeight <=maxWeight and itemsVal >bestVal:
                bestVal = itemsVal
                bestSet = items
    return (bestSet, bestVal)


def testBest(maxWeight=150):
    items = buildItem()
    pset = genPowerSet.genPowerSet(items)
    taken,val = chooseBest(pset,maxWeight,Item.getValue,Item.getWeight)
    print  'Total value of items taken = ',val
    for item in taken:
        print item
start1 = time.clock()
testBest()
end1=time.clock()
print "runing time is %f"  % (end1-start1)

Total value of items taken =  155.0
 < A , 35.0 , 10.0>
 < B , 30.0 , 40.0>
 < D , 50.0 , 50.0>
 < E , 40.0 , 35.0>
runing time is 0.001193

从实验结果上看,还是很快的,穷举法很完美啊。但是穷举的复杂度可是指数级的,当数据量比较大时就要歇了,举个例子,比如说集合的元素数目为20的时候,仅仅函数genPowerSet就要花费14.1231262126s,这就是指数的可怕,如果是26的话,就呵呵了(反正我是死机了)。

所以穷举法对于数据量小的情形是很好用的,但是数据量稍微大一些,就无路可走了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

0/1背包问题之穷举解法 的相关文章

随机推荐

  • openmediavault版本5.6.13 安装extra

    成功的安装经验 xff1a 要点1 修改 etc apt source list 添加如下内容 deb http deb debian org debian buster main contrib non free deb http deb
  • Windows系统删除隐藏U盘EFI分区的方法

    Windows系统删除隐藏U盘EFI分区的方法 如Windows系统上显示有容量为96M或256M的efi系统分区 xff0c 在磁盘管理中无法删除或隐藏 xff0c 可使用DiskPart工具删除误显示的盘符 使用DiskPart工具删除
  • Mysql数据库报错:Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DY

    1 问题描述 xff1a Row size too large gt 8126 Changing some columns to TEXT or BLOB or using ROW FORMAT 61 DYNAMIC or ROW FORM
  • AMD IOMMU与Linux (2) -- IVRS及AMD IOMMU硬件初始化

    介绍AMD IOMMU driver基于IVRS的硬件初始化情况 1 I O Virtualization ACPI table 2 drivers iommu amd init c 1 I O Virtualization ACPI ta
  • AMD IOMMU与Linux (3) -- DMA

    Linux中DMA会使用硬件IOMMU如AMD IOMMU INTEL VT D xff0c 也会使用软件的SWIOTLB 这篇梳理一下LINUX内核在有AMD IOMMU的情况下 xff0c 是如何做DMA的 xff0c 内容包括如下 1
  • AMD IOMMU与Linux (4) -- Domain, Group, Device

    1 domain的本质是一个页表 xff0c 1对1的关系 2 IOMMU DOMAIN UNMANAGED vs IOMMU DOMAIN DMA a IOMMU DOMAIN UNMANAGED DMA mappings managed
  • 第三篇:知其然,知其所以然-USB音频设备的开发过程

    最近 xff0c 有朋友正好在开发一个USB音频设备 xff0c 所以询问我一些USB音频设备开发方面的技术细节问题 xff1b 也和音响发烧友聊到USB音频设备的实现方式与其优缺点 xff1b 后来 xff0c 也和人谈到实现一个USB音
  • 第七篇:风起于青萍之末-电源管理请求案例分析(下)

    第五篇 风起于青萍之末 电源管理请求案例分析 上 http blog csdn net u013140088 article details 18180249 第六篇 风起于青萍之末 电源管理请求案例分析 中 http blog csdn
  • 回溯算法(BackTracking)--八皇后问题

    0 xff09 回溯算法 xff1a 回溯算法也算是遍历算法的一种 xff0c 回溯算法是对Brute Force算法的一种改进算法 xff0c 一个典型的应用是走迷宫问题 xff0c 当我们走一个迷宫时 xff0c 如果无路可走了 xff
  • 第十九篇:USB Audio/Video Class设备协议

    转发请注明出处 随着项目的不断进行 我想在网上查找了一下USB Audio Video的最新资料 看看有没有业内人士的更新 由于我们的项目一直在技术的最前延 而且这个USB IF官方发布的协议 也非常非常新 结果找了半天 都是我这篇文章的转
  • 第三十二篇:Windbg中USB2.0调试环境的搭建

    2011年的时候 xff0c 为了开发USB Mass storage UASP USB attached SCSI Protocol 的设备驱动程序 xff0c 从米国买了两个USB2 0的调试小设备 xff08 如下图 xff0c 每个
  • 理解SerDes 之一

    理解SerDes FPGA发展到今天 xff0c SerDes Serializer Deserializer 基本上是标配了 从PCI到PCI Express 从ATA到SATA xff0c 从并行ADC接口到JESD204 从RIO到S
  • 理解SerDes 之二

    理解SerDes 之二 2012 11 11 21 17 12 转载 标签 xff1a dfe serdes it 2 3 接收端均衡器 Rx Equalizer 2 3 1 线形均衡器 Linear Equalizer 接收端均衡器的目标
  • USB3.0的物理层测试探讨

    USB简介 USB Universal Serial Bus 即通用串行总线 xff0c 用于把键盘 鼠标 打印机 扫描仪 数码相机 MP3 U盘等外围设备连接到计算机 xff0c 它使计算机与周边设备的接口标准化 在USB1 1版本中支持
  • ARM SoC漫谈

    作者 xff1a 重走此间路 链接 xff1a https zhuanlan zhihu com p 24878742 来源 xff1a 知乎 著作权归作者所有 商业转载请联系作者获得授权 xff0c 非商业转载请注明出处 芯片厂商向客户介
  • linux下实现生产者消费者问题

    生产者 xff08 producer xff09 和消费者 xff08 consumer xff09 问题是并发处理中最常见的一类问题 xff0c 是一个多线程同步问题的经典案例 可以这样描述这个问题 xff0c 有一个或者多个生产者产生某
  • 解决Ubuntu下每隔几分钟自动锁屏,需要重新输入密码的问题

    看到这篇文章 xff0c 很实用 xff0c mark xff01 http www cnblogs com lanxuezaipiao p 3617436 html
  • Android NFC详解

    1 NFC概览 NFC xff0c 全称是Near Field Communication xff0c 中为近场通信 xff0c 也叫做近距离无线通信技术 使用了NFC技术的设备 xff08 例如移动电话 xff09 可以在彼此靠近的情况下
  • Microsoft VBScript 运行时错误 错误 '800a01a8' 缺少对象: ''

    Microsoft VBScript 运行时错误 错误 39 800a01a8 39 缺少对象 39 39 通常是这个对象已经关闭了 xff0c 你现在又关闭一次 xff01 xff01
  • 0/1背包问题之穷举解法

    0 1背包问题 有一个背包 xff0c 背包容量是M 61 150kg 有7个物品 xff0c 物品不可以分割成任意大小 xff08 这句很重要 xff09 要求尽可能让装入背包中的物品总价值最大 xff0c 但不能超过总容量 物品 A B