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.
Jip J. Dekker f2a1c4e389 Squashed 'software/mza/' content from commit f970a59b17
git-subtree-dir: software/mza
git-subtree-split: f970a59b177c13ca3dd8aaef8cc6681d83b7e813
2021-07-11 16:34:30 +10:00

116 lines
3.3 KiB
MiniZinc

% RUNS ON mzn20_fd
% RUNS ON mzn-fzn_fd
% RUNS ON mzn20_fd_linear
% RUNS ON mzn20_mip
%------------------------------------------------------------------------------%
% 2DPacking.mzn
% Jakob Puchinger
% October 29 2007
% vim: ft=zinc ts=4 sw=4 et tw=0
%------------------------------------------------------------------------------%
% Two-dimensional Bin Packing
%
% n rectangular items with given height and width have to be packed into
% rectangular bins of size W x H
% It is assumed that the items are sorted according to non-increasing height.
%
%------------------------------------------------------------------------------%
% Upper Bound on the number of Bins used
int: K;
% Width of the Bin
int: W;
% Height of the Bin
int: H;
% Number of items to be packed
int: N;
% Widths of the items
array[1..N] of int: ItemWidth;
% Heights of the items
array[1..N] of int: ItemHeight;
% Variable indicating if bin k is used.
array[1..K] of var 0..1: bin;
% Variable indicating if item i is in bin k.
array[1..K, 1..N] of var 0..1: item;
% The total number of bins has to be minimized
solve minimize
sum( k in 1..K ) ( bin[k] ) ;
% Each item has to be packed.
constraint
forall( j in 1..N ) (
sum( k in 1..K ) ( item[k, j] ) = 1
);
% subproblem constraints
constraint
forall( k in 1..K ) (
is_feasible_packing(bin[k], [ item[k, j] | j in 1..N ])
);
% This predicate defines a feasible packing
% as a 2-stage guillotine pattern (level pattern).
% A Bin consists of one or several levels
% and each level consist of one or several items.
% The height of a level is given by its highest (first) item.
% Variable x[i, j] indicates if item i is put in level j
% x[j, j] also indicate that level j is used.
%
% Note, k is locally fixed, so this is the pattern for the k'th bin.
%
predicate is_feasible_packing(var 0..1: s_bin,
array[1..N] of var 0..1: s_item) = (
let {array[1..N, 1..N] of var 0..1: x} in (
forall ( i in 1..N ) (
% Width of items on level can not exceed W
sum( j in i..N ) ( ItemWidth[j] * x[i, j] ) <= W * x[i, i]
/\
% first item in level is highest
% XXX do not need to generate those variables (use default)
forall( j in 1..i-1 ) ( x[i, j] = 0 )
)
/\
% Height of levels on bin can not exceed H
sum( i in 1..N ) ( ItemHeight[i] * x[i, i] ) <= s_bin * H
/\
% for all items associate item on bin with item on level.
forall(j in 1..N) (
s_item[j] = sum( i in 1..j ) ( x[i, j] )
)
)
);
% required for showing the objective function
var int: obj;
constraint
obj = sum( k in 1..K )( bin[k] );
output
[ "Number of used bins = ", show( obj ), "\n"] ++
[ "Items in bins = \n\t"] ++
[ show(item[k, j]) ++ if j = N then "\n\t" else " " endif |
k in 1..K, j in 1..N ] ++
[ "\n" ];
%------------------------------------------------------------------------------%
%
% Test data (Not in separate file, so that mzn2lp can handle it).
%
N = 4;
W = 5;
H = 10;
K = 2;
ItemWidth = [ 1, 1, 2, 3 ];
ItemHeight = [ 4, 4, 4, 3 ];
%N = 6;
%W = 5;
%H = 10;
%K = N;
%ItemWidth = [ 4, 4, 1, 1, 2, 3 ];
%ItemHeight = [ 6, 5, 4, 4, 4, 3 ];