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

老师好,我是刁同学
关于如何理解这个问题,我看了很多其他博主写的博客,但是大多数关于穷举法的(在我看来比较麻烦,思路上不太清晰),从问题的本源来说,这就是一个关于选择的问题。就像是传送带上的物品,而你只有一个有限的背包,对于你来说只是要不要眼前的序号为i的物品,从你开始选择开始,如果没有背包限额的规定,直到最后一个物品t的选择截止,你一共只有2^t种不同的选择(对每个单独的物品来说只有选或者不选)。明明晃晃的二叉树结构,而这种结构,被二进制的01字符串演绎的淋漓尽致,我们甚至都不需要做其他的改动。把十进制转化成二进制,就是我们所有的选择了。0代表不选,1代表选。在面对有限空间时,我们就要考虑每次选择之后的剩余空间了,这也不是太难的问题,只需简单统计即可。在每种选择背后,如果背包在你还没选完时就已经满了,就不需考虑这种取法了。在所有选择中一定有比他更合适的。最后,只需在符合条件的情况下,选择价值最大就行了,而他就是你要的答案。

import math
N=[]#确定组合数
V=[]#记录每件物品的价值
M=[]#记录每件物品重量
C=[]#记录总价
W=[]#记录总重量
max=0#记录最大取值
NUM=0#最大取值时的取法
t=int(input("请输入问题规模:"))
b=int(input("输入背包的最大容量:"))
for i in range(0,t):
   V.append(int(input("请输入第%d件物品的价值:"%i)))
   M.append(int(input("请输入第%d件物品的重量:"%i)))
for i in range(0,int(math.pow(2,t))):
    N.append (int('{0:b}'.format(i)))
    C.append(0)
    W.append(0)
for i in range(1,int(math.pow(2,t))):
    flag=True
    q=0
    while flag:
        if(N[i]/10>=1):
            W[i]+=(N[i]%10)*M[q]
            if(W[i]>b):
                break
            else:
                C[i]+=(N[i]%10)*V[q]
                N[i]=N[i]//10
                q+=1
        elif(N[i]==1):
            W[i]+=(N[i]%10)*M[q]
            if(W[i]>b):
                break
            else:
                C[i]+=(N[i]%10)*V[q]
                N[i]=N[i]//10
                q+=1
                flag=False
for i in range(1,int(math.pow(2,t))):
    if(C[i]>max):
        max=C[i]
        NUM=i
print("最大的价值是:%d"%max)
print("取法是(对应关系为最低位开始对应第0个物品.1为取.0为不取):'{0:b}'".format(NUM))

请输入问题规模:5
输入背包的最大容量:20
请输入第0件物品的价值:3
请输入第0件物品的重量:2
请输入第1件物品的价值:4
请输入第1件物品的重量:3
请输入第2件物品的价值:5
请输入第2件物品的重量:4
请输入第3件物品的价值:8
请输入第3件物品的重量:5
请输入第4件物品的价值:10
请输入第4件物品的重量:9
最大的价值是:26
取法是(对应关系为最低位开始对应第0个物品.1为取.0为不取):‘11101
PS:(结果解释)即取第4、3、2号物品;不取1号;取0号物品

你可能感兴趣的:(穷举法求解0/1背包问题)