include "partition_set.mzn";
int: weeks; set of int: WEEK = 1..weeks;
int: groups; set of int: GROUP = 1..groups;
int: size; set of int: SIZE = 1..size;
int: ngolfers = groups*size;
set of int: GOLFER = 1..ngolfers;
array[WEEK,GROUP] of var set of GOLFER: Sched;
% constraints
constraint
forall (i in 1..weeks-1) (
Sched[i,1] < Sched[i+1,1]
) /\
forall (i in WEEK, j in GROUP) (
card(Sched[i,j]) = size
/\ forall (k in j+1..groups) (
% Sched[i,j] < Sched[i,k]
% /\
Sched[i,j] intersect Sched[i,k] = {}
)
) /\
forall (i in WEEK) (
partition_set([Sched[i,j] | j in GROUP], GOLFER)
% /\ forall (j in 1..groups-1) (
% Sched[i,j] < Sched[i,j+1]
% )
) /\
forall (i in 1..weeks-1, j in i+1..weeks) (
forall (x,y in GROUP) (
card(Sched[i,x] intersect Sched[j,y]) <= 1
)
);
% symmetry
constraint
% Fix the first week %
forall (i in GROUP, j in SIZE) (
((i-1)*size + j) in Sched[1,i]
) /\
% Fix first group of second week %
forall (i in SIZE) (
((i-1)*size + 1) in Sched[2,1]
) /\
% Fix first 'size' players
forall (w in 2..weeks, p in SIZE) (
p in Sched[w,p]
);
solve satisfy;
output [ show(Sched[i,j]) ++ " " ++
if j == groups then "\n" else "" endif |
i in WEEK, j in GROUP ];