背包的变化......在python中

时间:2015-07-20 21:44:54

标签: python algorithm bin-packing

我有一个概念性的问题,我有几个包,每个包里面都包含许多元素。元素属于A或类型B。我希望在有限数量的箱中分发包,使AB之间的分布在箱之间没有差别。

这个问题非常复杂,因此我将尝试用严格的约束和一个概念性的例子来解释它。

约束

A package can only be used once
A package must be used entirely
The bins should have relatively equal distributions between `A` and `B` (max 5% deviation from the original ratio)
A package can be spread across all the bins in the given batch
I want to end up with as little as batches (size <= 3 bins) as possible

示例(概念)

Plate 1: 92 * `A`
Plate 2: 92 * `A`
Plate 3: 64 * `A`
Plate 4: 42 * `A`, 50 * `B`
Plate 5: 12 * `A`, 49 * `B`
Plate 6: 92 * `B`

总分布为302 * A和191 * B共计493个样本,结果比率为A的61.25%和{{1}的38.75% }

期望的结果:

最小化的批次集合,其中每个批次包含最多3个箱子(长度<= 92),其中说出类型为B的52到60之间以及类型之间的32到40之间{每箱的{1}}(合计总数不超过92)。

问题

建议采用什么算法或方法来解决这个问题,一个简单的建议方案会做(考虑到我到目前为止所尝试的内容(见下文)并没有走得太远)

到目前为止我的尝试背后的想法

A

这也是我被卡住的地方,目前这并不是要尽量减少垃圾箱的数量,也不会检查比率。另外,我有一个唠叨的想法,即我试图做到这一点的方式并不是解决这个问题的聪明方法。

1 个答案:

答案 0 :(得分:1)

#quick generator to rotate bin numbers
def getBin(maxBin):
    number = -1
    while True:
        number +=1 
        if number >= maxBin:
            number = 0
        yield number

batches = []
data = ....

#calculate the minimum number of bins we need
numberOfBins = (len(data))/ 92 + 1 

aBinPlacement = getBin(numberOfBins)
bBinPlacement = getBin(numberOfBins)

bins = numberOfBins * [[]]

#the ratio will be maintained because we rotate bins by type
for datum in data:
    if datum[0] == 'A':
        bins[aBinPlacement.next()].append(datum)
    else:
        bins[bBinPlacement.next()].append(datum)

batches.extend(bins)