% % Global constraint change in MiniZinc. % % From Global Constraint Catalogue: % http://www.emn.fr/x-info/sdemasse/gccat/sec4.42.html % """ % NCHANGE is the number of times that constraint CTR holds on consecutive variables of the % collection VARIABLES. % % Example % (3, <4, 4, 3, 4, 1>, !=) % (1, <1, 2, 4, 3, 7>, > ) % % In the first example the changes are located between values 4 and 3, 3 and 4, 4 and 1. % Consequently, the corresponding change constraint holds since its first argument NCHANGE is % fixed to value 3. % % In the second example the unique change occurs between values 4 and 3. Consequently, the % corresponding change constraint holds since its first argument NCHANGE is fixed to 1. % """ % % Model created by Hakan Kjellerstrand, hakank@bonetmail.com % See also my MiniZinc page: http://www.hakank.org/minizinc % include "globals.mzn"; int: n = 5; array[1..n] of var 1..4: x; array[1..n] of var 1..7: y; var int: c_x; var int: c_y; % % Since MiniZinc don't handle function variables we use the following % hack where t is the type of comparison operator. % t: % - 2 : a < b % - 1 : a <= b % 0 : a = b % 1 : a >= b % 2 : a > b % else : a != b % predicate cmp(var int: a, var int: b, -2..2: t) = if t = -2 then a < b elseif t = -1 then a <= b elseif t = 0 then a = b elseif t = 1 then a >= b elseif t = 2 then a > b else a != b endif ; predicate change(var int: changes, array[int] of var int: x, int: op) = let { int: n = length(x) } in changes = sum(i in 2..n) ( bool2int(cmp(x[i-1], x[i], op))) ; solve satisfy; constraint x = [4, 4, 3, 4, 1] /\ y = [1, 2, 4, 3, 7] /\ change(c_x, x, 10) /\ change(c_y, y, 2) ;