/*********************************************************** furniture.pi from Constraint Solving and Planning with Picat, Springer by Neng-Fa Zhou, Hakan Kjellerstrand, and Jonathan Fruhman ***********************************************************/ import cp, util. main => data(1,Data,MaxPeople,MaxTime,Precedences), schedule(Data,MaxPeople,MaxTime,Precedences). schedule(Data,MaxPeople,MaxTime,Precedences) => N = Data.length, [_Names,PeopleNeeded,Duration] = Data.transpose(), NameIxMap = new_map([Data[I,1]=I : I in 1..N]), % decision variables Start = new_list(N), Start :: 0..MaxTime, % end time of the tasks End = new_list(N), End :: 0..MaxTime, % number of people needed NumPeople :: 0..MaxPeople, % constraints cumulative(Start, Duration, PeopleNeeded, NumPeople), % connect start and end time for each task foreach (Task in 1..N) End[Task] #= Start[Task] + Duration[Task] end, MaxEnd #= max(End), % maximum End time % precedences: task P1 must be finished before task P2 starts foreach ([P1,P2] in Precedences) End[NameIxMap.get(P1)] #< Start[NameIxMap.get(P2)] end, % search Vars = End ++ Start ++ [NumPeople], solve(\$[ff,split,min(MaxEnd)],Vars), nl, println(numPeople=NumPeople), println(maxEnd=MaxEnd), println(start=Start), println(end=End). data(1,Data,MaxPeople,MaxTime,Precedences) => % name, people, time (in minutes) Data = [ [piano , 3, 30], [chair1, 1, 10], % chairs [chair2, 1, 10], [chair3, 1, 10], [chair4, 1, 10], [bed , 3, 20], [table , 2, 15], [shelf1, 2, 15], % shelves [shelf2, 2, 15], [tv , 2, 15] ], MaxPeople = 4, MaxTime = sum([T : [_,_,T] in Data]), Precedences = [ [shelf1,bed], [shelf2,table], [bed,piano], [tv,table] ].