Knapsack 0-1 with fixed quanitity

别来无恙 提交于 2020-02-24 05:45:08

问题


I'm writing a variation of knapsack 0-1 with multiple constraints. In addition to a weight constraint I also have a quantity constraint, but in this case I want to solve the knapsack problem given that I'm required to have exactly n items in my knapsack, with a weight less than or equal to W. I'm currently implementing a dynamic programming ruby solution for the simple 0-1 case based off of the code at Rosetta Code at http://rosettacode.org/wiki/Knapsack_problem/0-1#Ruby.

What's the best way to implement the fixed quantity constraint?


回答1:


You could add a third dimension to the table: Number of items. Each item included adds both weight in the weight-dimension, and count in the count-dimension.

def dynamic_programming_knapsack(problem)
  num_items = problem.items.size
  items = problem.items
  max_cost = problem.max_cost
  count = problem.count
  cost_matrix = zeros(num_items, max_cost+1, count+1)

  num_items.times do |i|
    (max_cost + 1).times do |j|
      (count + 1).times do |k|
        if (items[i].cost > j) or (1 > k)
          cost_matrix[i][j][k] = cost_matrix[i-1][j][k]
        else
          cost_matrix[i][j][k] = [
              cost_matrix[i-1][j][k],
              items[i].value + cost_matrix[i-1][j-items[i].cost][k-1]
            ].max
        end
      end
    end
  end
  cost_matrix
end

To find the solution (which items to pick), you need to look at the grid cost_matrix[num_items-1][j][k], for all values of j and k, and find the cell with maximum value.

Once you find the winning cell, you need to trace backwards towards the start (i = j = k = 0). On each cell you examine, you need to determine if item i was used to get here or not.

def get_used_items(problem, cost_matrix)
  itemIndex = problem.items.size - 1
  currentCost = -1
  currentCount = -1
  marked = Array.new(cost_matrix.size, 0) 

  # Locate the cell with the maximum value
  bestValue = -1
  (problem.max_cost + 1).times do |j|
    (problem.count + 1).times do |k|
      value = cost_matrix[itemIndex][j][k]
      if (bestValue == -1) or (value > bestValue)
        currentCost = j
        currentCount = k
        bestValue = value
      end
    end
  end

  # Trace path back to the start
  while(itemIndex >= 0 && currentCost >= 0 && currentCount >= 0)
    if (itemIndex == 0 && cost_matrix[itemIndex][currentCost][currentCount] > 0) or
        (cost_matrix[itemIndex][currentCost][currentCount] != cost_matrix[itemIndex-1][currentCost][currentCount])
      marked[itemIndex] = 1
      currentCost -= problem.items[itemIndex].cost
      currentCount -= 1
    end
    itemIndex -= 1
  end
  marked
end


来源:https://stackoverflow.com/questions/26445874/knapsack-0-1-with-fixed-quanitity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!