【问题标题】:Struggling with recursive bin algorithm: Fixed amounts of bin?挣扎于递归 bin 算法:固定数量的 bin?
【发布时间】:2017-05-17 14:36:23
【问题描述】:

我正在努力解决这个问题:

给定一个由 N 个正整数组成的集合 S,任务是将它们分成 K 个子集,使得每个 K 个子集中的元素值之和相等。

我的方法是使用第一次拟合递减算法。我按大小对整数进行排序并填充它们:

public int getResult() {
    Collections.sort(in, Collections.reverseOrder()); // sort input by size (big to small)
    bins.add(new Bin(binSize)); // add first bin
    for (Integer currentItem : in) {
        // iterate over binlist and try to put the item into the first one it fits into
        boolean putItem = false; // did we put the item in a bin?
        int currentBin = 0;
        while (!putItem) {
            if (currentBin == bins.size()) {
                // item did not fit in last bin.
                // No clue what to do here
                putItem = true;
            } else if (bins.get(currentBin).put(currentItem)) {
                // item fit in bin
                putItem = true;
            } else {
                // try next bin
                currentBin++;
            }
        }
    }
    return bins.size();
}

不幸的是,如果所有箱子都没有装满,但最后一件物品已经放不下,我不知道如何处理这种情况。 我想此时我想重新组织项目并重试不同的分布。但是怎么做呢?

我一直在努力解决这个问题,如果有任何帮助,我会很高兴的!

【问题讨论】:

    标签: java bin-packing


    【解决方案1】:

    如果你面前有真正的垃圾箱,你会怎么做?如果某个号码不适合放入垃圾箱,您需要返回上一步,与您之前放入的号码进行交换。如果这不起作用,则需要返回、交换等。

    您帖子的标题表明您正在寻找递归解决方案。您的解决方案不是递归的。递归函数调用自身,可能会使用一组减少的参数,并且递归函数有一个“基本情况”,或者知道它已经尽其所能并且可以声明成功的方法。

    这是一个例子:

    public int fibonacci(int n)  {
        // Here are the base cases (Fibonacci happens to have two)
        if (n==0) {
          return 0;
        }
        else if (n==1) {
          return 1;
        }
    
        // Otherwise, call this function again, changing the parameters
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
    

    您将如何编写递归装箱函数?您可以从 S 中放置一个数字 X,然后在没有 X 的情况下使用 S 再次调用您的函数。您还应该传递垃圾箱。想想你的基本情况是什么;我认为当 S 为空且垃圾箱已满时,您会宣布成功。如果 S 不为空,请尝试拟合下一个 X。如果不合适,您将需要回溯,可能通过执行“return false”之类的操作......并且您的函数需要知道调用时该怎么做to 自身返回 false。

    祝你好运!

    【讨论】:

    • 非常感谢您的意见! “如果一个数字不适合一个垃圾箱,你需要回到你的最后一步,用你之前输入的数字交换”因为我正在使用排序降序列表,我很难掌握这一点正确。我知道在第一次运行中,我首先分配较大的,然后是较小的。但是如果我想回溯并创建一个不同的变体,我不是在扰乱这种模式吗?我将如何表达这一点 - 使用 list.get(1) 而不是 list.get(0) (第二大对象而不是第一个?)
    • 在这种情况下,您也许可以交换 bin 而不是数字。例如,N1 转到 B1。 N2 进入 B2。 N3 不适合 B3,因此尝试从 B2 中取出 N2 并将其放入 B3,然后将 N3 放入 B2。如果不合适,从 B1 中取出 N1,放入 B2,然后在 B1 中尝试 N3。或者,也许您不需要排序的降序列表。您在这里遇到的问题称为装箱问题。 en.wikipedia.org/wiki/Bin_packing_problem
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2014-08-30
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多