0

I'm modelling a university curriculum timetable with Answer Set Programming (Clingo). The requirements are that each lesson must be asssigned to a specific week , day and start /end hours until the total hours are reached.

In a day there are max 8 hours and each lesson is 2 hours minimum. Also the scheduled lessons are until the 10th week.

week(1..10). time(9,11;11,13;14,16;16,18).  

So first I generated each assigned lesson slot

TotalHours { assigned(Week,Day,Start,End,Course,Teacher) : day(Day), time(Start,End), week(Week) } TotalHours :-
lesson(Course,Teacher,TotalHours).

After that for other requirements and rules I needed to find the last course assigned in the timetable. I don't know if this is a good way but I was able to find a solution

MaxWeek =  #max {Week : assigned(Week,_,_,_,Course,_)},
MaxDay = #max {Day : assigned(MaxWeek,Day,_,_,Course,_)},
MaxStart= #max {Start : assigned(MaxWeek,MaxDay,Start,_,Course,_)},
assigned(_,_,_,_,Course,_).

I'm new to ASP and so far I couldn't find a good way to find the second last lesson of the course assigned in the timetable(Week,Day,Start,End) needed for other schedule requirements.

So given for example

assigned(1,Monday,9,11,History,John) , assigned(1,Tuesday,11,13,Math,Smith), assigned(4,Tuesday,16,18,History,John),assigned(5,Monday,11,13,History,John)

I want to find the second last lesson of History which is

assigned(4,Tuesday,16,18)

Any tips or solutions is really appreciated

  • Are you sure that TotalHours is the number of assigned/6 predicates and that you do not need something like End-Start ? – Max Ostrowski Apr 19 '21 at 11:51

1 Answers1

0

Consider having a second assigned predicate (with a different arity) to be something more absolute, like:

assigned((Week-1)*7*24+Day+Start,End,Course,Teacher) :- assigned(Week,Day,Start,End,Course,Teacher).

Now you just have one field that is completely ordered over all assignments, which is total hours since start of the year.

To find the last courses, the last aggregate performs very badly, and can be optimized using chaining constraints:

auxLastCourse(C,T) :- assigned(T,_,C,_).
auxLastCourse(C,T-1) :- auxLastCourse(C,T), T > 0.
lastCourse(C,T) :- auxLastCourse(C,T), not auxLastCourse(C,T+1).

Also note that in your example aren't any courses during the night, so this could be optimized further by not beeing so finegranular and explicitly representing every hour, but maybe only hours that actually occur in a possible schedule. THis would mean replacing the T-1 in the aux code with an explicit next relation over weeks and days and hours. Currently I'm just too lazy to add something like this.

For the second last course you can do exactly the same thing:

auxSecondLastCourse(C,T) :- assigned(T,_,C,_), not lastCourse(C,T).
auxSecondLastCourse(C,T-1) :- auxSecondLastCourse(C,T), T > 0.
secondLastCourse(C,T) :- auxSecondLastCourse(C,T), not auxSecondLastCourse(C,T+1).

PS: Note that I assume that your days are given as numbers 0..6, and not as words as in your example, I'm sure you will figure out how to translate them using another predicate.

PPS: I haven't tested the code, as you did'nt provide an MWE.

Max Ostrowski
  • 575
  • 1
  • 3
  • 15
  • Thank you kindly for the help ! Sorry for my mistake but I didn't explain it well in the question. The courses are beetween 9am and 18pm so there will not be courses during the night. Also there are no more than 10 weeks for scheduled lesson. I edited the question to clarify this aspect. Anyway unfortunately the code didn't work out well for me because I need to know when the week of the lesson is assigned for other constraints and find the second last lesson slot assigned for each course. I added some example in the question to clarify more. – John Hundred Apr 19 '21 at 17:14
  • Edited the code s.t. you can still use your old predicate with the week explicitly given, and added the course C to the last course predicate. – Max Ostrowski Apr 20 '21 at 06:46