git-subtree-dir: software/chuffed git-subtree-split: 2ed0c01558d2a5c49c1ce57e048d32c17adf92d3
54 lines
2.1 KiB
MiniZinc
54 lines
2.1 KiB
MiniZinc
include "globals.mzn";
|
|
include "flatzinc.mzn";
|
|
|
|
int: c; % number of customers
|
|
int: p; % number of products
|
|
|
|
set of int: Custs = 1..c;
|
|
set of int: Prods = 1..p;
|
|
|
|
array[Custs,Prods] of 0..1: orders; % which customer orders which product
|
|
|
|
array[1..c*c] of bool: graph = [
|
|
sum (j in Prods) (bool2int(orders[(i div c)+1, j] = 1 /\ orders[(i mod c)+1, j] = 1)) >= 1
|
|
| i in 0..c*c-1];
|
|
|
|
% graph describing which pairs of customers share at least one product
|
|
|
|
array[Custs] of var Custs: s; % customer start time
|
|
array[Custs] of var Custs: e :: is_output; % customer end time
|
|
var Custs: stacks :: is_output; % number of stacks required
|
|
|
|
array[Custs,Custs] of var bool: so; % whether customer started before certain time
|
|
array[Custs,Custs] of var bool: eo; % whether customer ended after certain time
|
|
array[Custs,Custs] of var bool: o; % whether customer was open at certain time
|
|
|
|
constraint all_different(e);
|
|
|
|
%constraint forall (i in Custs) (minimum(s[i], [e[j] | j in Custs where graph[(i-1)*c+j]]));
|
|
|
|
constraint forall (i, j in Custs where graph[(i-1)*c+j]) (s[i] <= e[j]);
|
|
|
|
constraint forall (i, t in Custs) (so[i,t] = (s[i] <= t));
|
|
constraint forall (i, t in Custs) (eo[i,t] = (e[i] >= t));
|
|
constraint forall (i, t in Custs) (o[i,t] = (so[i,t] /\ eo[i,t]));
|
|
|
|
|
|
constraint forall (t in Custs) (stacks >= sum (i in Custs) (bool2int(o[i,t])));
|
|
|
|
% Dominance breaking constraints
|
|
|
|
array[Custs,Custs] of var bool: r; % whether customer was ready to close at certain time
|
|
|
|
% if all customers sharing a product has already opened and we have not closed, we are ready to close now
|
|
constraint forall (i, t in Custs) (
|
|
r[i,t] = forall ([so[j,t] | j in Custs where graph[(i-1)*c+j]] ++ [eo[i,t]]));
|
|
|
|
% If none of the lex better customers are ready to close now but we are, we close now
|
|
constraint forall (i in Custs, t in 1..c-1) (
|
|
bool_clause([r[j,t] | j in 1..i-1], [r[i,t], eo[i,t+1]]));
|
|
% exists([r[j,t] | j in 1..i-1] ++ [r[i,t] != true, eo[i,t+1] != true]));
|
|
|
|
|
|
solve :: int_search(e, smallest, indomain_min, complete) minimize stacks;
|