【问题标题】:Knapsack 0-1 with fixed quanitity背包 0-1 数量固定
【发布时间】:2014-10-19 00:09:44
【问题描述】:

我正在编写具有多个约束的背包 0-1 的变体。除了重量限制外,我还有数量限制,但在这种情况下,我想解决背包问题,因为我的背包中需要正好有 n 件物品,重量小于或等于 W。我'目前我正在根据http://rosettacode.org/wiki/Knapsack_problem/0-1#Ruby 的 Rosetta Code 中的代码为简单的 0-1 案例实现动态编程 ruby​​ 解决方案。

实施固定数量限制的最佳方式是什么?

【问题讨论】:

    标签: algorithm dynamic-programming knapsack-problem


    【解决方案1】:

    您可以在表格中添加第三个维度:项目数。包含的每个项目都会在重量维度中添加重量,并在计数维度中添加计数。

    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
    

    要找到解决方案(选择哪些项目),您需要查看网格cost_matrix[num_items-1][j][k],查看jk 的所有值,并找到具有最大值的单元格。

    找到获胜单元后,您需要向后追溯至起点 (i = j = k = 0)。在您检查的每个单元格上,您需要确定是否使用项目 i 到达此处。

    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
    

    【讨论】:

    • 谢谢,这有帮助。但是现在我在概念化如何遍历 cost_matrix 以返回使用过的项目列表时遇到了麻烦。你知道如何修改二维案例吗?
    • 此解决方案实际上是否严格限制为 k 项目?也就是说,它只解决了最多k 个项目的约束。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    • 2013-01-03
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    相关资源
    最近更新 更多