128 lines
3.6 KiB
MiniZinc
128 lines
3.6 KiB
MiniZinc
%------------------------------------------------------------------------------
|
|
% Parameters
|
|
|
|
int: f;
|
|
int: g;
|
|
int: c;
|
|
int: k;
|
|
set of int: Cap = 0..k;
|
|
int: t;
|
|
set of int: Trips = 1..t;
|
|
set of int: Trips0 = 0..t;
|
|
int: pf;
|
|
int: pg;
|
|
int: pc;
|
|
int: maxp = f*pf + g*pg + c*pc;
|
|
|
|
%------------------------------------------------------------------------------
|
|
% Variables
|
|
|
|
array[Trips] of var Cap: fox;
|
|
array[Trips] of var Cap: geese;
|
|
array[Trips] of var Cap: corn;
|
|
var 0..t: trips;
|
|
|
|
array[Trips0] of var 0..f: efox;
|
|
array[Trips0] of var 0..g: egeese;
|
|
array[Trips0] of var 0..c: ecorn;
|
|
|
|
array[Trips0] of var 0..f: wfox;
|
|
array[Trips0] of var 0..g: wgeese;
|
|
array[Trips0] of var 0..c: wcorn;
|
|
|
|
var 0..maxp: objective;
|
|
|
|
%------------------------------------------------------------------------------
|
|
% Predicates
|
|
|
|
predicate alone(
|
|
var 0..f: fox0, var 0..f: fox1,
|
|
var 0..g: geese0, var 0..g: geese1,
|
|
var 0..c: corn0, var 0..c: corn1
|
|
) =
|
|
let { var 1..4: c; % the cases we consider
|
|
% 1: only one type of goods
|
|
% 2: no fox, geese and corn
|
|
% 3: fox and corn, no geese
|
|
% 4: fox and geese (corn or not)
|
|
} in (
|
|
c = [1,1,1,2,1,3,4,4][1 + 4*(fox0 > 0) + 2*(geese0 > 0) + (corn0 > 0)]
|
|
/\ fox1 = fox0 + [0,0,-1,if fox0 > geese0 then -1 else 0 endif][c]
|
|
/\ geese1 = geese0 + [0,if geese0 > corn0 then -1 else 0 endif, 0, if fox0 > geese0 then 0 else -fox0 endif][c]
|
|
/\ corn1 = corn0 + [0,if geese0 > corn0 then -1 else -geese0 endif, -1, 0][c]
|
|
);
|
|
|
|
%------------------------------------------------------------------------------
|
|
% Constraints
|
|
|
|
constraint efox[0] = 0 /\ egeese[0] = 0 /\ ecorn[0] = 0;
|
|
constraint wfox[0] = f /\ wgeese[0] = g /\ wcorn[0] = c;
|
|
|
|
constraint forall(i in 1..t)(
|
|
i <= trips ->
|
|
if i mod 2 == 1 then
|
|
alone(
|
|
wfox[i-1] - fox[i], wfox[i],
|
|
wgeese[i-1] - geese[i], wgeese[i],
|
|
wcorn[i-1] - corn[i], wcorn[i]
|
|
)
|
|
/\ efox[i] = efox[i-1] + fox[i]
|
|
/\ egeese[i] = egeese[i-1] + geese[i]
|
|
/\ ecorn[i] = ecorn[i-1] + corn[i]
|
|
else
|
|
alone(
|
|
efox[i-1] - fox[i], efox[i],
|
|
egeese[i-1] - geese[i], egeese[i],
|
|
ecorn[i-1] - corn[i], ecorn[i]
|
|
)
|
|
/\ wfox[i] = wfox[i-1] + fox[i]
|
|
/\ wgeese[i] = wgeese[i-1] + geese[i]
|
|
/\ wcorn[i] = wcorn[i-1] + corn[i]
|
|
endif
|
|
);
|
|
|
|
constraint forall(i in 1..t)(fox[i] + geese[i] + corn[i] <= k);
|
|
|
|
constraint forall(i in 1..t)(i > trips -> fox[i] = 0 /\ geese[i] = 0 /\ corn[i] = 0);
|
|
|
|
constraint objective = efox[trips] * pf + egeese[trips] * pg + ecorn[trips] * pc;
|
|
|
|
%------------------------------------------------------------------------------
|
|
% Solve item
|
|
|
|
solve
|
|
:: seq_search([
|
|
int_search([trips], input_order, indomain_min, complete),
|
|
int_search(
|
|
[ if j= 1 then fox[i] elseif j = 2 then geese[i] else corn[i] endif
|
|
| i in Trips, j in 1..3],
|
|
input_order,indomain_max, complete
|
|
)
|
|
])
|
|
maximize objective;
|
|
|
|
|
|
%------------------------------------------------------------------------------
|
|
% Redundant constraints
|
|
|
|
constraint redundant_constraint(
|
|
forall(i in 1..t)(
|
|
wfox[i-1] + efox[i-1] >= wfox[i] + efox[i]
|
|
/\ wgeese[i-1] + egeese[i-1] >= wgeese[i] + egeese[i]
|
|
/\ wcorn[i-1] + ecorn[i-1] >= wcorn[i] + ecorn[i]
|
|
)
|
|
);
|
|
|
|
|
|
%------------------------------------------------------------------------------
|
|
% Output item
|
|
|
|
output [
|
|
"fox = \(fox);\n",
|
|
"geese = \(geese);\n",
|
|
"corn = \(corn);\n",
|
|
"trips = \(trips);\n",
|
|
"objective = \(objective);\n"
|
|
];
|
|
|