预测解决方案

时间:2014-07-24 19:17:27

标签: constraints constraint-programming minizinc

是否有可能告诉MiniZinc在变量集的子集上投射解决方案?或者是否有任何其他方法可以枚举所有与评估某些变量子集无关的解决方案?

我曾尝试在MiniZinc中直接使用FlatZinc注释,但它不起作用,因为展平过程会添加更多的define_var注释,我的注释会被忽略。

2 个答案:

答案 0 :(得分:3)

我在MiniZinc 2.0(https://www.minizinc.org/2.0/index.html)中尝试了以下模型,这似乎可以按预期工作,即在结果中只投影(打印)x1和x2。

int: n = 3;
var 1..n: x1;
var 1..n: x2;
var 1..n: x3;

solve satisfy;
constraint
  x3 > 1
;

output [  show([x1,x2])];

结果是:

[1, 1]
----------
[2, 1]
----------
[3, 1]
----------
[1, 2]
----------
[2, 2]
----------
[3, 2]
----------
[1, 3]
----------
[2, 3]
----------
[3, 3]
----------
==========

在MiniZinc v中,每个x3值重复打印1.6 x1和x2。

更新

但是,如果x3涉及任何约束(以任何有趣的方式),它似乎与版本1.6中的行为相同。这可能不是你想要的......

UPDATE2:

我问Gecode的一位开发人员,他回答说:

  

关于投影语义,这实际上取决于求解器。例如,Gecode不应该生成重复的解决方案(基于输出语句中提到的内容),而g12fd则生成AFAIK。所以答案是投影由输出项定义,但只有一些求解器保证唯一性。

当我们对此进行测试时,我们发现Gecode中的一个错误并不符合答案。现在已经修复了(在SVN版本中)。

以下模型如何为x1和x2提供不同的答案(使用固定的Gecode版本):

int: n = 5;

var 1..n: x1;
var 1..n: x2;
var 1..n: x3;

solve satisfy;

constraint
   x2 + x1 < 5 /\
   x2 +x3 > x1
;

output [  "x:", show([x1,x2])];

给出的解决方案(使用固定的Gecode解算器)现在是:

x:[1,1]


x:[2,1]


x:[3,1]


x:[1,2]


x:[2,2]


x:[1,3]


==========

这适用于MiniZinc 1.6和MiniZinc 2.0。

答案 1 :(得分:0)

该解决方案直接使用FlatZinc。假设我们添加约束x3 = x1 + x2

var 1..3: x1 :: output_var;
var 1..3: x2 :: output_var;
var 1..3: x3 :: is_defined_var :: var_is_introduced;

constraint int_plus(x1, x2, x3) :: defines_var(x3);
constraint int_le_reif(1, x3, true);

solve satisfy;

flatzinc -a的输出返回了正确的值组合:

x1 = 1;
x2 = 1;
----------
x1 = 2;
x2 = 1;
----------
x1 = 1;
x2 = 2;
----------
==========

我的观察是辅助变量必须是:

  1. 使用注释is_defined_varvar_is_introduced
  2. 进行声明
  3. 必须在某个约束defines_var
  4. 中定义

    变量声明的注释完全没有效果。求解器将这样的变量视为通常的决策变量。