约束满足在java中

时间:2012-09-16 12:44:04

标签: java constraint-programming

我在编写java中的以下问题时遇到问题,这是一个约束满足问题:

如果我有这样的约束:

  1. x1 + x2> X3
  2. x2 - x4 = 2
  3. x1 + x4< X5
  4. x1x5中的每一个都在域{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。

1 个答案:

答案 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

我会让你为其他约束做同样的事情。