算法 - Bin-packing,排列bin以包装n个对象

时间:2012-03-27 15:02:09

标签: algorithm data-structures

以下是“Algorithm Design Manual”一书中的消息。

  

在装箱问题中,我们给出了n个金属物体,每个物体的重量在0到1千克之间。我们的目标是找到容纳n个物体的最小数量的垃圾箱,每个垃圾箱最多可容纳1公斤。

     

bin装的最佳拟合启发式如下。考虑一下   对象按给定顺序排列。 对于每个对象,放置   它进入部分填充的垃圾箱,额外的最小量   插入对象后 。如果不存在此类bin,请启动新的bin   完事。设计一种实现最佳拟合启发式算法   (将n个权重w1,w2,...,wn作为输入并输出该数字   在O(nlogn)时间内使用的箱子。

好的,这个消费税似乎并不难。我最初的理解是,对于最合适的启发式方法,我只是每次寻找具有最小可用空间的bin并尝试将对象放入。如果对象不适合具有最小空间的bin,我创建一个新的箱中。

我可以构建一个BST来存储垃圾箱,每次将对象放入垃圾箱时,我都可以从树中删除该垃圾箱,更新垃圾箱的可用空间并将垃圾箱重新插入树中。这将为每个对象放置提供O(logN)。

然而,我注意到消费税的粗体和斜体部分“对于每个物体,在插入物体后,将其放入部分填充的箱子中,最小的额外空间”。

所以这意味着我不是在寻找一个具有最小可用空间的bin,相反,我正在寻找一个如果我将当前对象放入其中,结果可用空间(放置对象之后)将是最小的。

例如,如果bin1的当前空间为0.5,则bin2为0.7。所以目前,bin1是最小的一个。但是如果当前对象是0.6,那么对象不能放入bin1,而不是创建一个新的bin,我必须找到bin2将对象放入bin2 - object = 0.7 - 0.5 = 0.2,这是最小的。

我是对的吗?声明的大胆部分是否真的像我想的那样?或者它就像“找到一个空间最小的bin,如果可以放置对象,然后放置;如果不能,那么创建一个新的bin”这么简单吗?

由于

编辑:添加部分java代码,以便我对粗体部分有所了解。

public void arrangeBin(float[] w) {
   BST bst = new BST();
   bst.root = new Node();

   int binCount = 0;
   for (int i = 0;i < w.length;i++) {
      float weight = w[i];
      Node node = bst.root;
      float minDiff = 1;
      Node minNode = null;
      while(node!=null) {
         if (node.space > weight) {
             float diff = node.space - weight;
             if (minDiff > diff) {
                 minDiff = diff;
                 minNode = node;
                 node = node.left;
             }
         }
         else 
             node = node.right;
      }
      if (minNode == null) {
         binCount++;
         Node node = new Node();
         node.space -= weight;
         bst.insert(node);
      }
      else {
         minNode.space -= weight;
         bst.delete(minNode);
         bst.insert(minNode);
      }
   }
}

2 个答案:

答案 0 :(得分:5)

您需要保留一个按剩余空间排序的已排序数组(或者更像是红黑树的排序二进制树),并且对于每个新权重,找到最适合空白空间的bin < strong> O(log(n)),并在 O(log(n))中将其重新插入树中。您的观察结果似乎是正确的 - 您需要找到最适合您新体重的垃圾箱。希望这会有所帮助。

答案 1 :(得分:1)

大胆的陈述确实意味着你的想法。

我们的想法是找到当前物体适合的最大垃圾箱,从而最大限度地减少浪费的空间。如果对象不适合任何箱子,则需要创建新箱子