Algorithm 算法-箱包装,排列箱以包装n个对象

Algorithm 算法-箱包装,排列箱以包装n个对象,algorithm,data-structures,Algorithm,Data Structures,这是一本书的附加说明 在箱子包装问题中,我们得到n个金属物体,每个重量在0到1公斤之间。我们的目标是找到容纳n个对象的最小数量的箱子,每个箱子最多容纳1公斤 装箱的最佳启发式方法如下所示。考虑一下 对象的顺序对于每个对象,放置 将其放入部分填充的垃圾箱中,额外添加的垃圾量最小 插入对象后的房间。如果不存在此类bin,请启动新的bin 箱子设计一个实现最佳拟合启发式的算法 (将n个权重w1、w2、…、wn作为输入,并输出数字 在O(nlogn)时间内使用的存储箱数量 好的,这个练习似乎并不难。我最

这是一本书的附加说明

在箱子包装问题中,我们得到n个金属物体,每个重量在0到1公斤之间。我们的目标是找到容纳n个对象的最小数量的箱子,每个箱子最多容纳1公斤

装箱的最佳启发式方法如下所示。考虑一下 对象的顺序对于每个对象,放置 将其放入部分填充的垃圾箱中,额外添加的垃圾量最小 插入对象后的房间。如果不存在此类bin,请启动新的bin 箱子设计一个实现最佳拟合启发式的算法 (将n个权重w1、w2、…、wn作为输入,并输出数字 在O(nlogn)时间内使用的存储箱数量

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

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

然而,我注意到附加工作的粗体和斜体部分“对于每个对象,在插入对象后,将其放入部分填充的箱子中,并留出最小的额外空间”

因此,这意味着我不是在寻找一个可用空间最小的箱子,而是在寻找一个如果我放置当前对象,得到的可用空间(放置对象后)将是最小的箱子

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

我说得对吗?这句话的粗体部分真的和我想的一样吗?或者就像“找到一个空间最小的箱子,如果可以放置物体,那么放置;如果不能,那么创建一个新箱子”一样简单

谢谢

编辑:为我对粗体部分的新理解添加部分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);
      }
   }
}
public void arrangeBin(float[]w){
BST BST=新的BST();
bst.root=新节点();
int binCount=0;
对于(int i=0;i权重){
float diff=节点空间-权重;
if(minDiff>diff){
minDiff=diff;
minNode=节点;
node=node.left;
}
}
其他的
node=node.right;
}
if(minNode==null){
binCount++;
节点=新节点();
node.space-=权重;
bst.insert(节点);
}
否则{
minNode.space-=重量;
bst.delete(minNode);
bst.insert(minNode);
}
}
}

您需要保留一个按剩余空间排序的箱子排序数组(或者更确切地说是一个像红黑树一样的排序二叉树),对于每个新的权重,在O(log(n))中找到其中最适合的空白空间的箱子,并在O(log(n))中将其重新插入到树中。。你的观察似乎是正确的-你需要找到最适合你新体重的箱子。希望这能有所帮助。

这句粗体的话确实代表了你的想法


这样做的目的是找到当前对象所能容纳的最满的垃圾箱,从而最大限度地减少浪费的空间。如果对象不适合任何箱子,则需要创建一个新箱子

您的代码将遍历每个新重量的所有节点,这将导致运行时间为O(N2)。如果你想达到O(nlogn),你应该使用我在回答中建议的东西。“除此之外,它看起来是正确的。”WeaselFox,我有一个bst