enum label {M,J,E,K,R}; range boolean 0..1; int+ nbDays = 7; int+ nbWeeks = 10; int DailyShift = nbWeeks/nbDays; range Day 1..nbDays; range Week 1..nbWeeks; int+ number[label, Day] = [ [0,0,0,0,0,0,0] [2,1,3,2,2,4,2] [2,2,2,2,2,0,3] [3,3,3,3,3,3,3] [3,4,2,3,3,3,2] ]; int nbR = sum(i in Day) number[R,i]; int MinNbR = min(i in Day) number[R,i]; Day MinCol = 3; var label x[Week, Day]; var boolean y[Week, Day]; var boolean z[Week, Day]; minimize sum(i in Week, j in Day ) (z[i,j]+y[i,j]) subject to { forall(i in Week,j in Day) { y[i,j]=((x[i,j]=E) & (x[1+(i-1+j/nbDays) mod nbWeeks,1+j mod nbDays]=M)); z[1+(i-1+j/nbDays) mod nbWeeks,1+j mod nbDays]=((x[i,j]<>R) & (x[1+(i-1+j/nbDays) mod nbWeeks,1+j mod nbDays]=R) & (x[1+(i-1+(j+1)/nbDays) mod nbWeeks,1+(j+1) mod nbDays]<>R) ); sum(k in 0..nbDays-1) (x[1+(i-1+(j+k-1)/nbDays) mod nbWeeks,1+(j+k-1) mod nbDays]<>R)<=6 ; sum(k in 0..3) (x[1+(i+(j+k-1)/nbDays-1) mod nbWeeks,1+(j+k-1) mod nbDays]=R)<=3; }; forall (j in Day, e in label) sum (i in Week) (x[i,j] = e) = number [e,j] ; }; search { forall(j in 0..nbDays-1) when number[R,1+(MinCol+j-1) mod nbDays]>0 do forall(i in 1..number[R,1+(MinCol+j-1) mod nbDays]) try x[1+(i-1+j*DailyShift) mod nbWeeks,1+(MinCol+j-1) mod nbDays]=R | x[1+(i-1+j*DailyShift) mod nbWeeks,1+(MinCol+j-1) mod nbDays]<>R endtry; generate(x); };