我在编写java中的以下问题时遇到问题,这是一个约束满足问题:
如果我有这样的约束:
x1
到x5
中的每一个都在域{0,1,2}
如何编写不同的组合,以便我将为每个约束设置一组元组:{(0,0,0), (0,0,1), (0,1,0),(0,1,1),(1,0,0), ......}
即临时约束1具有元组的域,例如{(0,0,0), (0,0,1), (0,1,0),(0,1,1),(1,0,0),(0,1,2),(2,0,1) ......}
我需要任何语言的回复,但最好是java。
答案 0 :(得分:1)
你可以通过使用google commons collect库中的一些帮助方法来实现这一点。它看起来像这样:
我假设元组(0,0,0)等是约束输入的元组,(x0,x1,x2)表示约束1,(x2,x4)表示约束2等。
因此,对于constraint1,首先我们填充一个包含所有可能组合的列表:
final List<int[]> allCombos = new ArrayList<int[]>();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
allCombos.add(new int[] {i, j, k});
}
}
}
for (final int[] i : allCombos) {
System.out.println(i[0] + ", " + i[1] + ", " + i[2]);
}
接下来,我们要过滤,这样我们就会得到constraint1允许的元组:
final List<int[]> constraint1 = ImmutableList.copyOf(Iterables.filter(allCombos, new Predicate<int[]>() {
@Override
public boolean apply(@Nullable final int[] input) {
return input[0] + input[1] > input[2];
}
}));
for (final int[] i : constraint1) {
System.out.println(i[0] + ", " + i[1] + ", " + i[2]);
}
这可能需要一点解释。
ImmutableList.copyOf是一种创建给定列表副本的方法。对于这个方法,我们传递Iterables.filter()的结果,它接受一个列表(要过滤的输入)和一个Predicate,它有一个重写的方法apply(),在那里你决定输入列表的哪个元素应该是结果列表的一部分。在这里,我们基本上只是对约束本身进行编码,而apply方法返回true的情况将是过滤列表的一部分。 (我选择将元组表示为数组,您可以将过滤策略与任何元组表示一起使用..)
上次打印输出(过滤后的列表)的结果将是:
0, 1, 0
0, 2, 0
0, 2, 1
1, 0, 0
1, 1, 0
1, 1, 1
1, 2, 0
1, 2, 1
1, 2, 2
2, 0, 0
2, 0, 1
2, 1, 0
2, 1, 1
2, 1, 2
2, 2, 0
2, 2, 1
2, 2, 2
我会让你为其他约束做同样的事情。