【问题标题】:Variation of the backpack ... in python背包的变化......蟒蛇
【发布时间】:2015-07-20 21:44:54
【问题描述】:

我有一个概念问题,我有几个包,每个包里面都包含许多元素。元素的类型为AB。我想以这样一种方式将包分配在有限数量的箱中,使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% 和 B 的 38.75%

期望的结果:

一组最小化的批次,其中每个批次最多包含 3 个箱(长度 A 类型在 52 到 60 之间,B 类型在 32 到 40 之间(总和不超过 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

这也是我被卡住的地方,目前这并没有尝试最小化垃圾箱的数量,也没有检查比率。此外,我有一个挥之不去的想法,即我尝试这样做的方式与解决此类问题的智能方式相去甚远。

【问题讨论】:

  • 问题到底是什么?
  • 下次你写完 你发表之前怎么样?
  • 对此我深表歉意,我试图让聊天中的参与者在编辑时阅读它以使其更清晰。
  • @BasJansen 我认为这仍然是空间搜索问题。这意味着,根据我的经验,您应该从 BFS 实现开始,然后添加启发式优化器,也许还有一些状态修剪。如果您想要一个最佳解决方案,我认为您将不得不检查每一种可能性:贪婪算法不会很快找到最佳答案,甚至是一个答案。
  • 我认为,问题陈述需要更多的工作。 “一个包只能使用一次”是什么意思? (当我们需要决定如何分发时,我们知道所有的包?离线与在线问题)每个包都需要完全在一个批次内?多个包裹可以一起打包吗? 5% 的偏差率是固定常数还是目标函数的一部分? (后者:多目标优化 -> 哪个目标有多重要?)性能有多重要?如果没有好的实例生成器,评估将很困难(大多数实例太容易;有些很难)

标签: python algorithm bin-packing


【解决方案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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 2010-10-27
    • 2010-10-21
    • 2016-05-28
    • 2014-08-01
    相关资源
    最近更新 更多