% % Global constraint weighted_sum in MiniZinc. % % Note: This constraint is not in the Global Constraint Catalogue. % % The predicate weighted_sum will calculate the weighted sum of % two arrays % coeffs * x % where the sum is constrained with a limit and an comparision operator % (coded as -3..3) % % E.g. % coeffs = [1, 2, -3] and x = [4, 4, 0] % will give the weighted sum of 12 % % % % This MiniZinc model was created by Hakan Kjellerstrand, hakank@bonetmail.com % See also my MiniZinc page: http://www.hakank.org/minizinc % % include "globals.mzn"; int: n = 3; array[1..n] of var -3..2: coeffs; array[1..n] of var 0..5: x; var int: s; % % 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 ; % % weighted_sum(sum, coeffs, x, limit, operation) % predicate weigthed_sum(var int: s, array[int] of var int: coeffs, array[int] of var int: x, var int: limit, int: op) = s = sum(i in index_set(x)) ( coeffs[i]*x[i] ) /\ cmp(s, limit, op) ; % solve satisfy; solve :: int_search(x ++ coeffs, "first_fail", "indomain", "complete") satisfy; constraint coeffs = [1,2,-3] /\ % weigthed_sum(coeffs, x, 12, 2) weigthed_sum(s, coeffs, x, 12, 2) ;