1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.

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"
];