I have a problem that could be boiled down to finding a way of mapping a triangular matrix to a vector skipping the diagonal.
Basically I need to translate this C++ code using the Gecode libraries
// 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);
Into this MiniZinc (functional) code
constraint
forall ( i in 1..m-1 , j in i+1..m )
( (differences[?]) >= (floor(int2float(( j-i )*( j-i+1 )) / int2float(2)) ));
And I need to figure out the index in differences[?]
.
MiniZinc is a functional/mathematical language with no proper for
loops.
So I have to map those indexes i
and j
that are touching all and only the cells of an upper triangular matrix, skipping its diagonal, to a k
that numbers those cells from 0 to whatever.
If this was a regular triangular matrix (it's not), a solution like this would do
index = x + (y+1)*y/2
The matrix I'm handling is a square n*n
matrix with indexes going from 0 to n-1, but it would be nice to provide a more general solution for an n*m
matrix.
Here's the full Minizinc code
% 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"];
Thanks.