我正在一维编写垃圾箱包装程序。我只想要一个可能的箱子。所以它不包括很多只有它的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;
}
}
}
答案 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);
}
}