装箱(搜索四组答案)

Bin Packing(Searched quad groups for answers)

我正在写一个一维装箱程序。我只想要一个可能的垃圾箱。所以它不包括很多 bin 它只有一个。该程序仅搜索四边形组,如果四边形组不等于搜索数量,则爆炸。我想搜索每一个可能大于四边形的组。 在示例中,我们有 60 60 50 40 45 35 25 15,我们正在寻找等于 180 的总和,答案是 60 60 45 15 这很好,但如果我们搜索 250,它将不起作用。 你能帮助我吗? 那是程序 https://github.com/omerbguclu/BinPacking1D 的 link 这就是算法的代码 o array 是数字,array 是答案的位置

    public BinPacking() {

}

public void binpack(ArrayList<Integer> o, ArrayList<Integer> a, int wanted) {
    int sum = 0;
    if (wanted > 0) {
        control(o, a, wanted);
        if (is) {
            return;
        }
        for (int i = 0; i < o.size(); i++) {
            sum += o.get(i);
            summing(o, a, wanted - sum, i + 1);
            if (is) {
                a.add(i);
                return;
            }
            for (int j = i; j < o.size(); j++) {
                if (i != j) {
                    sum += o.get(j);
                    summing(o, a, wanted - sum, j + 1);
                    if (is) {
                        a.add(i);
                        a.add(j);
                        return;
                    }
                    sum -= o.get(j);
                }
            }
            sum -= o.get(i);
            // "/////////////*******************////////////////////");
        }
        if (wanted != sum) {
            System.out.println("There is not an answer with quad summing method");
        }
    }

}

public void summing(ArrayList<Integer> o, ArrayList<Integer> a, int wanted, int loop) {
    int sum = 0;
    if (loop < o.size() && wanted > 0) {
        for (int i = loop; i < o.size(); i++) {
            if (wanted == o.get(i)) {
                a.add(i);
                is = true;
                return;
            }
            for (int j = loop; j < o.size(); j++) {
                if (i != j) {
                    sum = o.get(i) + o.get(j);
                    if (wanted != sum) {
                        sum = 0;
                    } else {
                        a.add(i);
                        a.add(j);
                        is = true;
                        return;
                    }

                }
                // System.out.println("///////////////////////////////////");
            }
        }
        System.out.println("There is not an answer with binary summing method");
    }
}

public void control(ArrayList<Integer> o, ArrayList<Integer> a, int wanted) {
    for (int i = 0; i < o.size(); i++) {
        if (o.get(i) == wanted) {
            a.add(i);
            is = true;
            break;
        }

    }

}

有一个非常完善且有效的机制来获取一组对象的所有可能组合。本质上,您将组合的成员资格视为 BitSet,它表示集合中的每个成员是否都在组合中。然后访问每个组合就是访问每个 BitSet 组合。

以下是我倾向于如何实现它:

public class Combo<T> implements Iterable<List<T>> {

    private final List<T> set;

    public Combo(List<T> set) {
        this.set = set;
    }

    public Iterator<List<T>> iterator() {
        BitSet combo = new BitSet(set.size());
        return new Iterator<List<T>>() {
            public boolean hasNext() {
                return combo.cardinality() < set.size();
            }

            public List<T> next() {
                int i = 0;
                while (combo.get(i))
                    combo.clear(i++);
                combo.set(i);
                return combo.stream().mapToObj(set::get).collect(Collectors.toList());
            }
        };
    }
}

因此您的解决方案将变为:

for (List<Integer> combo: new Combo<>(...)) {
    if (combo.size >= 4 && combo.stream.reduce(0, Integer::sum) == total)
        ....
}

同一想法的黑客版本是:

for (long l = 0; l < 1 << (input.size() - 1); l++) {
    List<Integer> combo = BitSet.valueOf(new long[]{l}).stream()
            .mapToObj(input::get).collect(Collectors.toList());
    if (combo.stream().mapToInt(n -> n).sum() == total) {
        System.out.println(combo);
    }
}