Python Knapsack Branch and Bound -


i have spent week working on branch , bound code knapsack problem, , have looked @ numerous articles , books on subject. however, when running code don't result expect. input received text file, such this:

12 4 1 1 1 3 2 2 3 

where first line capacity, , each subsequent line value/weight pairs. result using file '8' instead of '10' (unless mistaken , items won't fit in knapsack). here code:

#!/usr/bin/python # -*- coding: utf-8 -*-  import queue collections import namedtuple item = namedtuple("item", ['index', 'value', 'weight', 'level', 'bound', 'contains'])  class node:     def __init__(self, level, value, weight, bound, contains):          self.level = level          self.value = value          self.weight = weight          self.bound = bound          self.contains = contains  def upper_bound(u, k, n, v, w):     if u.weight > k:         return 0      else:         bound = u.value         wt = u.weight         j = u.level + 1          while j < n , wt + w[j] <= k:             bound += v[j]             wt += w[j]             j += 1      # fill knapsack fraction of remaining item             if j < n:                 bound += (k - wt) * (v[j] / w[j])              return bound  def knapsack(items, capacity):     item_count = len(items)     v = [0]*item_count     w = [0]*item_count  # sort items value weight ratio     items = sorted(items, key=lambda k: k.value/k.weight, reverse = true)      i,item in enumerate(items, 0):         v[i] = int(item.value)         w[i] = int(item.weight)      q = queue.queue()      root = node(0, 0, 0, 0.0, [])     root.bound = upper_bound(root, capacity, item_count, v, w)     q.put(root)      value = 0     taken = [0]*item_count     best = set()      while not q.empty():         c = q.get()          if c.bound > value:             level = c.level+1      # check 'left' node (if item added knapsack)         left = node(c.value + v[level], c.weight + w[level], level, 0.0, c.contains[:])         left.contains.append(level)          if left.weight <= capacity , left.value > value:             value = left.value             best |= set(left.contains)          left.bound = upper_bound(left, capacity, item_count, v, w)          if left.bound > value:             q.put(left)          # check 'right' node (if items not added knapsack)         right = node(c.value, c.weight, level, 0.0, c.contains[:])         right.contains.append(level)         right.bound = upper_bound(right, capacity, item_count, v, w)          if right.bound > value:             q.put(right)      b in best:         taken[b] = 1      value = sum([i*j (i,j) in zip(v,taken)])      return str(value) 

are indices off? not traversing tree or calculating bounds correctly?

i think want calculate bound if you're not taking item. if take item, means bound still attainable. if don't, have readjust expectations.


Comments

Popular posts from this blog

php - SPIP: From Tag directly to an article -

jquery - isAjaxRequest always return false -

ruby on rails - In a controller spec, how to find a specific tag in the generated view? -