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.

107 lines
2.4 KiB
MiniZinc

% wolfgoatetc.mzn
% ft=zinc ts=4 sw=4 et
%
% RUNS ON mzn20_fd
% RUNS ON mzn-fzn_fd
% RUNS ON mzn20_mip
%
% XXX why is lazyfd so slow with this?
%
% The wolf, goat, and cabbage problem.
%
% A farmer has to transport his wolf, goat, and cabbage from his farm, across
% the river in his rowboat, to the market on the far bank. He can carry only
% one item at a time in his boat. He cannot leave the wolf alone with the
% goat or the goat alone with the cabbage.
set of int: loc = 1..3;
loc: farm = 1;
loc: boat = 2;
loc: market = 3;
set of int: obj = 0..3;
obj: F = 0;
obj: W = 1;
obj: G = 2;
obj: C = 3;
int: max_steps = 15;
set of int: step = 1..max_steps;
array [step, obj] of var loc: L;
% Initial conditions.
%
constraint L[1, W] = farm;
constraint L[1, G] = farm;
constraint L[1, C] = farm;
constraint L[1, F] = farm;
% The goal: move the wolf, goat, and cabbage to the market.
%
var step: solved;
constraint
L[solved, W] = market
/\ L[solved, G] = market
/\ L[solved, C] = market;
% We can't leave the wolf alone with the goat
% or the goat alone with the cabbage.
%
constraint
forall (s in step) (
L[s, F] = L[s, G]
\/ ( L[s, G] != L[s, C]
/\ L[s, G] != L[s, W]
)
);
% The actions. At every step the farmer moves from one bank to the other;
% he may take something with him.
%
constraint
forall (s in step diff {max_steps - 1, max_steps} where s mod 2 = 1) (
exists (x in {W, G, C, F}, a, b in {farm, market} where a != b) (
move(s, x, a, b)
)
);
% Each move goes via the boat. Any object not moving stays where it is.
%
predicate move(step: s, obj: x, loc: from, loc: to) =
L[s, F] = from
/\ L[s, x] = from
/\ L[s + 1, F] = boat
/\ L[s + 1, x] = boat
/\ L[s + 2, F] = to
/\ L[s + 2, x] = to
/\ forall (y in {W, G, C} diff {x}) (
L[s + 1, y] = L[s, y]
/\ L[s + 2, y] = L[s, y]
);
% The plan is the move (other than the farmer) at each step.
%
array [step] of var obj: A =
[ bool2int(s < solved) *
( W * bool2int(L[s, W] != L[s + 1, W])
+ G * bool2int(L[s, G] != L[s + 1, G])
+ C * bool2int(L[s, C] != L[s + 1, C])
)
| s in step diff {max_steps}
] ++ [0];
solve
:: int_search(
[L[s, x] | s in step, x in obj],
input_order, indomain_min, complete
)
minimize solved;
output [
"A = ", show(A), ";\n",
"solved = ", show(solved), ";"
];