我有一个问题可以归结为找到一种将三角矩阵映射到跳过对角线的向量的方法。
基本上我需要使用 Gecode 库翻译这个 C++ 代码
// implied constraints
for (int k=0, i=0; i<n-1; i++)
for (int j=i+1; j<n; j++, k++)
rel(*this, d[k], IRT_GQ, (j-i)*(j-i+1)/2);
进入这个 MiniZinc(功能)代码
constraint
forall ( i in 1..m-1 , j in i+1..m )
( (differences[?]) >= (floor(int2float(( j-i )*( j-i+1 )) / int2float(2)) ));
我需要找出differences[?]
.
MiniZinc 是一种没有适当 for 循环的函数/数学语言。所以我必须映射那些索引 i 和 j ,它们接触上三角矩阵的所有且仅接触上三角矩阵的单元格,跳过其对角线,将这些单元格从 0 编号到任何值。
如果这是一个规则的三角矩阵(不是),这样的解决方案就可以了
index = x + (y+1)*y/2
我正在处理的矩阵是一个n*n
索引从 0 到 n-1 的方阵,但是为矩阵提供更通用的解决方案会很好n*m
。
这是完整的 Minizinc 代码
% modified version of the file found at https://github.com/MiniZinc/minizinc-benchmarks/blob/master/golomb/golomb.mzn
include "alldifferent.mzn";
int: m;
int: n = m*m;
array[1..m] of var 0..n: mark;
array[int] of var 0..n: differences = [mark[j] - mark[i] | i in 1..m, j in i+1..m];
constraint mark[1] = 0;
constraint forall ( i in 1..m-1 ) ( mark[i] < mark[i+1] );
% this version of the constraint works
constraint forall ( i in 1..m-1 , j in i+1..m )
( (mark[j] - mark[i]) >= (floor(int2float(( j-i )*( j-i+1 )) / int2float(2))) );
%this version does not
%constraint forall ( i in 1..m-1, j in i+1..m )
% ( (differences[(i-1) + ((j-2)*(j-1)) div 2]) >= (floor(int2float(( j-i )*( j-i+1 )) / int2float(2))) );
constraint alldifferent(differences);
constraint differences[1] < differences[(m*(m-1)) div 2];
solve :: int_search(mark, input_order, indomain, complete) minimize mark[m];
output ["golomb ", show(mark), "\n"];
谢谢。