Bin Packing(搜索四组寻求答案)

时间:2018-05-23 23:36:49

标签: java bin-packing

我正在一维编写垃圾箱包装程序。我只想要一个可能的箱子。所以它不包括很多只有它的bin。此程序仅搜索四组并在四组不等于搜索编号时爆炸。我想搜索每个可能比四边形更大的组。 例如,我们有60 60 50 40 45 35 25 15,我们正在寻找等于180的求和,答案是60 60 45 15,这很好,但是如果我们搜索250它将无法正常工作。 你能帮助我吗? 这是程序https://github.com/omerbguclu/BinPacking1D的链接 这就是算法o数组的代码是数字,数组是答案的位置

    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;
        }

    }

}

1 个答案:

答案 0 :(得分:1)

有一个非常完善和有效的机制,可以获得一组对象的每种可能的组合。基本上,您将组合的成员资格视为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)
        ....
}

相同想法的hackier版本将是:

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);
    }
}