装箱/背包优化问题设计

时间:2019-01-17 07:01:13

标签: multidimensional-array knapsack-problem bin-packing or-tools

我有一个场景,需要一些帮助来制定问题,以便我可以正确地实现优化方法。我希望有人能对我有所帮助,表面上看起来很简单,但是我在弄清楚如何正确编码变量,约束等方面遇到困难。

情况是这样的:

  • 需要将多个物品放入垃圾箱/背包
  • 每个物品在包装时都必须考虑两个因素
  • 我有几种可用于包装的垃圾桶/背包
  • 垃圾箱/背包的供应量无限
  • 每个垃圾箱/背包对物品中的每个值都有约束,因此物品的值以累积方式累加,但不能超过垃圾箱/背包中的任何一个约束
  • 每个垃圾桶/背包有不同的使用成本(价格)
  • 无论箱子中有什么物品,都可以放入垃圾箱/背包的数量上限

示例:

包含两个值的项目向量:

项目= [[7,6],[14,2],[27,23],[5,15]]

第一个值是上限的箱/背包矢量,它可以用于项目的第一个值。第二个值相同,但适用于垃圾箱/背包中每个项目的第二个值。第三个值是垃圾箱/背包可容纳的最大物品数。最后一个值是垃圾箱/背包的价格/成本。

BinOptions = [[64000,1450,350,22000],[8000,450,64,8000]]

目标是以最有效的方式包装所有物品,以提供最低的成本(使用垃圾箱/背包的价格)。

我正在研究可以解决问题的两种方法:

  • 采用MILP方法的OR-工具
  • 带背包解算器的OR-工具

我并不一定要坚持使用OR-Tools,这只是我一直在玩的东西,并且根据我所看到的报告,它似乎可以在不同语言之间很好地工作。能够对此建模并随后选择一种语言会很好。

可能不明显的一件事是可用垃圾箱数量的变化。有时我会选择两个或三个,有时会更多,甚至可能多达一百个。包装的进来物品的数量也会根据日期而变化。

如果有人可以提供一些解决方案的指导,我将非常感激。

欢呼

青蛙

2 个答案:

答案 0 :(得分:0)

背包求​​解器不能解决您的问题,因为它是一个纯粹的1-背包求解器。

您可以使用MILP求解器或CP-SAT。

答案 1 :(得分:0)

我建议使用bin packing示例作为此问题的模板。它使用SCIP求解器。

 solver = pywraplp.Solver.CreateSolver('SCIP')

在该示例中,目标是最小化用于包装所有物品的垃圾箱数量。我认为这适用于您的情况,尤其是在垃圾箱数量未知的情况下。显然,对于n个项目,所需的最大垃圾箱数为n,因为最大的垃圾箱数会导致一项放置在其自己的垃圾箱中。

#> Constraints:
## Each item must be packed once
for i in data['items']:
    solver.Add(sum(x[i, j] for j in data['bins']) == 1)

## The sum of each weight type cannot exceed the capacity for that bin
## You have two weight types, k.
for k in range(2):
    for j in data['bins']:
        solver.Add(
            sum(x[(i, j)] * data['weights'][k][i] for i in data['items']) <= y[j] *
            data['bin_capacity'][k])

## The number of items cannot exceed the numerical capacity of each bin
## Let's assume this capacity is element 2 of data['bin_capacities']
for j in data['bins']:
    solver.Add(
        sum(x[(i, j)] for i in data['items']) <= y[j] * data['bin_capacity'][2])

#> Objective:
## The original objective function used in the example.
solver.Minimize(solver.Sum([y[j] for j in data['bins']]))

## With the addition of a variable cost for a bin, you may need the following.
solver.Minimize(solver.Sum([y[j] * data['bin_cost'] for j in data['bins']]))