我有一个概念问题,我有几个包,每个包里面都包含许多元素。元素是 typeA
或 type B
。我想以这样一种方式将包分配在有限数量的箱中,以便箱之间的分布A
和B
箱之间的分布差异不大。
这个问题非常复杂,因此我将尝试用硬约束和概念示例来解释它。
约束
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 个样本,得到的比率是 61.25%A
和 38.75%B
期望的结果:
一组最小化的批次,其中每个批次最多包含 3 个箱(长度 <= 92),假设每个箱的类型在 52 到 60 之间,类型A
在 32 到 40 之间B
(总和不超过 92)。
问题
建议使用什么算法或方法来解决这个问题,一个简单的建议方案就可以了(考虑到我到目前为止一直在尝试的东西(见下文)并没有走得太远)
迄今为止我的尝试背后的想法
data = ... # This is a list containg all values in a tuple format of `(unit, [(type, location)])` format
while len(data) > 0:
batch = []
counter1 = 0
counter2 = 0
for i in data:
for j in i[1]:
if j[0] == 'A':
counter1 += 1
else:
counter2 += 1
ratio1 = counter1/(counter1+counter2)
ratio2 = counter2/(counter1+counter2)
# Now we know the maximum number of A and B per batch
counter3 = 0 # This keeps track of howmany type `A` we have in current batch
counter4 = 0 # This keeps track of howmany type `B` we have in current batch
while counter3 < ratio1:
for i in data:
for j in i[1]:
if Counter(elem[0] for elem in j)['A'] < (ratio1 - counter3) and Counter(elem[0] for elem in j)['B'] < (ratio2 - counter4):
# Add this unit (from data) to the batch
batch.append(i)
counter3 += Counter(elem[0] for elem in j)['A']
counter4 += Counter(elem[0] for elem in j)['B']
# Remove the used unit from data
这也是我被卡住的地方,目前这并没有尝试最小化垃圾箱的数量,也没有检查比率。此外,我有一个挥之不去的想法,即我尝试这样做的方式与解决此类问题的智能方式相去甚远。