Python 计算包含在分支和绑定背包中的项目
使用分支定界算法,我已经评估了给定项目集的最佳利润,但现在我想找出哪些项目包含在这个最佳解决方案中。我正在评估最佳背包的利润价值,如下所示(改编自):Python 计算包含在分支和绑定背包中的项目,python,tree,binary-tree,knapsack-problem,branch-and-bound,Python,Tree,Binary Tree,Knapsack Problem,Branch And Bound,使用分支定界算法,我已经评估了给定项目集的最佳利润,但现在我想找出哪些项目包含在这个最佳解决方案中。我正在评估最佳背包的利润价值,如下所示(改编自): 导入队列 类节点: 定义初始(自身、水平、利润、重量): self.level=level#树内的级别(深度) 自利=利润#总利润 自重=重量#总重量 背包(重量、利润、背包大小): numItems=len(重量) queue=queue.queue() 根=节点(-1,0,0) queue.put(根) 最大利润=0 界限=0 而不是queu
导入队列
类节点:
定义初始(自身、水平、利润、重量):
self.level=level#树内的级别(深度)
自利=利润#总利润
自重=重量#总重量
背包(重量、利润、背包大小):
numItems=len(重量)
queue=queue.queue()
根=节点(-1,0,0)
queue.put(根)
最大利润=0
界限=0
而不是queue.empty():
v=queue.get()#获取队列上的下一项
uLevel=v.level+1
u=节点(uLevel,v.profit+e[uLevel][1],v.weight+e[uLevel][0])
绑定=获取绑定(单位、单位、背包大小、重量、利润)
如果美国重量最大利润:
最大利润=最大利润
如果绑定>最大利润:
队列。放置(u)
u=节点(uLevel,v.利润,v.重量)
绑定=获取绑定(单位、单位、背包大小、重量、利润)
如果(绑定>最大利润):
队列。放置(u)
返回最大利润
#这本质上是分数背包的蛮力解
def getBound(单位、单位、背包大小、重量、利润):
如果u.weight>=背包大小:返回0
其他:
上限=美国利润
总重量=单位重量
j=u级+1
而j我使用您的代码作为起点来实现它。我将我的节点
类定义为:
class Node:
def __init__(self, level, profit, weight, bound, contains):
self.level = level # current level of our node
self.profit = profit
self.weight = weight
self.bound = bound # max (optimistic) value our node can take
self.contains = contains # list of items our node contains
然后,我同样启动了背包求解器,但初始化了root=Node(0,0,0,0.0,[])
。值root.bound
可以是浮点,这就是为什么我将其初始化为0.0
,而其他值(至少在我的问题中)都是整数。到目前为止,该节点未包含任何内容,因此我以一个空列表开始它。我遵循了与您的代码类似的大纲,只是我将绑定存储在每个节点中(不确定这是否必要),并使用以下方法更新了包含
列表:
u.contains = v.contains[:] # copies the items in the list, not the list location
# Initialize u as Node(uLevel, uProfit, uWeight, 0.0, uContains)
u.contains.append(uLevel) # add the current item index to the list
注意,我只更新了“获取项目”节点中的包含列表。这是主循环中的第一次初始化,位于第一条if-bound>maxProfit:
语句之前。在更新maxprint
的值时,我更新了在此之前if:
语句中的contains
列表:
if u.weight <= knapsackSize and u.value > maxProfit:
maxProfit = u.profit
bestList = u.contains
我的代码中还有其他一些不同之处,但这应该可以让您获得所选项目列表。我不确定这将最大限度地线性放松项目约束。这个“获取项目”分支到底在哪里?在我看来,“taking the item branch”是第一个运行if-bound>maxprint:
的if语句,但是没有返回正确的索引。至少在我尝试过的地方。另外,uContains
应该是u.contains
分支“taking The item”(我想节点是一个更好的词)是第一个if bound>maxprint:
语句前面的代码。在更新maxprint
值之前的语句中更新了contains列表。我更新了我的答案以反映这一点。我还纠正了u.contains
变量名的问题,并将值
更改为利润
,以便与OPs代码更加一致。这真是太糟糕了。我希望你的回答被接受。此外,我还编写了一个例程,该例程不涉及Node类中的绑定参数。简单地传递节点本身并提取节点的级别就足以让例程确定边界。
if u.weight <= knapsackSize and u.value > maxProfit:
maxProfit = u.profit
bestList = u.contains
taken = [0]*numItems
for item in bestList:
taken[item] = 1
print str(taken)