0

我试图在 Minizinc 中解决这个问题,取自Gardner 的 Puzzle

十个编号为 0,...,9 的单元格记录一个 10 位数字,这样每个单元格(例如 i)表示数字 i 在此数字中出现的总次数。找到这个号码。答案是 6210001000。

我解决了它,代码在 Gecode 上运行良好:

int: n=9;
set of int: N=0..n;
array[N] of var N: cell;

include "globals.mzn";
constraint global_cardinality(cell, N, cell);
solve satisfy;

output [show(cell), "\n", show(index_set(cell)), " -- ", show(index_set(N))];

Gecode的输出:

[6, 2, 1, 0, 0, 0, 1, 0, 0, 0]
0..9 -- 1..10
----------
==========

但是,G12 求解器抱怨 global_cardinality 中的断言失败:

在调用“断言”断言失败:global_cardinality:覆盖和计数必须具有相同的索引集

没错,正如 Gecode 的输出所示,N 为 1..10,cell 为 0..9。所以我的问题是:

  • 为什么 Gecode 有效?不同的实现或我的程序有问题但我很幸运?
  • 如何修复程序以与 G12 一起使用或使其健壮/正确?
4

2 回答 2

2

问题是您从 0 开始阵列。虽然这样做在技术上是正确的,但最好并建议从 1 开始阵列(MiniZinc 中的标准)。如您所见,仍有一些求解器不完全支持不从 1 开始的数组。还有一些与使用不从 0 开始的数组有关的错误。

我在 g12cpx 上遇到与您相同的错误,但将数组修改为

array[1..10] of var N: cell;

给了我正确的结果。

于 2016-02-19T14:05:15.240 回答
1

您可以通过添加 array1d() 来解决此问题:

 global_cardinality(cell,array1d(0..n,[i | i in N]), cell);

Gecode 工作但 G12/fd 不工作的原因是 Gecode 有自己的 MiniZinc 约束定义,不包括基数检查。

于 2016-02-19T18:09:34.560 回答