1

I'm currently working on an answer set program to create a timetable for a school. The rule base I use looks similar to this:

teacher(a). teacher(b). teacher(c). teacher(d). teacher(e). teacher(f).teacher(g).teacher(h).teacher(i).teacher(j).teacher(k).teacher().teacher(m).teacher(n).teacher(o).teacher(p).teacher(q).teacher(r).teache(s).teacher(t).teacher(u).

teaches(a,info). teaches(a,math). teaches(b,bio). teaches(b,nawi). teaches(c,ge). teaches(c,gewi). teaches(d,ge). teaches(d,grw). teaches(e,de). teaches(e,mu). teaches(f,de). teaches(f,ku). teaches(g,geo). teaches(g,eth). teaches(h,reli). teaches(h,spo). teaches(i,reli). teaches(i,ku). teaches(j,math). teaces(j,chem). teaches(k,math). teaches(k,chem). teaches(l,deu). teaches(l,grw). teaches(m,eng). teaches(m,mu). teachs(n,math). teaches(n,geo). teaches(o,spo). teaches(o,fremd). teaches(p,eng). teaches(p,fremd). teaches(q,deu). teaches(q,fremd). teaches(r,deu). teaches(r,eng). teaches(s,eng). teaches(s,spo). teaches(t,te). teaches(t,eng). teaches(u,bio). teaches(u,phy).

subject(X) :- teaches(_,X).

class(5,a). class(5,b). class(6,a). class(6,b). class(7,a). class(7,b). class(8,a). class(8,b). class(9,a). class(9,b). class(10,a). class(10,b).

%classes per week (for class 5 only at the moment)
classperweek(5,de,5). classperweek(5,info,0). classperweek(5,eng,5). classpereek(5,fremd,0). classperweek(5,math,4). classperweek(5,bio,2). classperweek(5,chem,0). classperweek(5,phy,0). classperweek(5,ge,1). classperweek(5,grw,0). cassperweek(5,geo,2). classperweek(5,spo,3). classperweek(5,eth,2). classperwek(5,ku,2). classperweek(5,mu,2). classperweek(5,tec,0). classperweek(5,nawi,0) .classperweek(5,gewi,0). classperweek(5,reli,2).

room(1..21).

%for monday to friday
weekday(1..5). 

%for lesson 1 to 9 
slot(1..9). 

In order to creat a timetable I wanted to create every possible combination of all predicats I'm using and then filter all wrong answers. This is how I created a timetable:

{timetable(W,S,T,A,B,J,R):class(A,B),teacher(T),subject(J),room(R)} :- weekday(W), slot(S).

Up to this point everything works, except that this solution is probably relatively inefficient.

To filter that no class uses the same room at the same time I formulated the following constraint.

:- timetable(A,B,C,D,E,F,G), timetable(H,I,J,K,L,M,N), A=H, B=I, G=N, class(D,E)!=class(K,L).

It looks like this makes to problem so big that the grounding fails, because I get the following error message

clingo version 5.4.0
Reading from timetable.asp
Killed

Therefore, I was looking for a way to create different instances of timetable without getting too many "meaningless" answers created by the choiserule. One possibility I thought of is to use a negation cycle. So you could replace the choiserule {a;b} with a :- not b. b :- not a. and exclude all cases where rooms are occupied twice. Unfortunately I do not understand this kind of approach enough to apply it to my problem.

After a lot of trial and error (and online search), I have not found a solution to eliminate the choicerule and at the same time eliminate the duplication of rooms and teachers at the same time.

Therefore I wonder if I can use this approach for my problem or if there is another way to not create many pointless answersets at all.

edit: rule base will work now and updated the hours per lesson for class 5

Spiderwick
  • 13
  • 3
  • could you describe the constraints you need to face? Like for each class one room and teacher, per class 2x bio, 2xpe, ... The number of classes is missing too. Also your code does not run as is (besides the "killed error"), please update your code. – DuDa Dec 31 '20 at 21:56
  • The basic constraint I want to implement is that no room is occupied twice at the same time (so for same weekday and slot) and that no teacher has to teach two classes at the same time. There are other constraints like checking if the subject has to use a special room (like the gym) or that the classes have a maximum amount of hours per subject per week but those i already figured out myself. (I can also share these if needed) – Spiderwick Jan 01 '21 at 19:06

1 Answers1

0

I think you're looking for something like:

% For each teacher and each timeslot, pick at most one subject which they'll teach and a class and room for them.
{timetable(W,S,T,A,B,J,R):class(A,B),room(R),teaches(T,J)} <= 1 :- weekday(W);slot(S);teacher(T).

% Cardinality constraint enforcing that no room is occupied more than once in the same timeslot on the timetable.
:- #count{uses(T,A,B,J):timetable(W,S,T,A,B,J,R)} > 1; weekday(W); slot(S); room(R).

to replace your two rules.

Note that this way clingo won't generate spurious ground terms for teachers teaching a subject they don't know. Additionally by using a cardinality constraint as opposed to a binary clause, you get a big-O reduction in the grounded size (from O(n^2) in the number of rooms to O(n)).

Btw, you may be missing answers because of typos in the input. I would suggest phrasing it as:

teacher(a;b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u).
teaches(
    a,info;
    a,math;
    b,bio;
    b,nawi;
    c,ge;
    c,gewi;
    d,ge;
    d,grw;
    e,de;
    e,mu;
    f,de;
    f,ku;
    g,geo;
    g,eth;
    h,reli;
    h,spo;
    i,reli;
    i,ku;
    j,math;
    j,chem;
    k,math;
    k,chem;
    l,deu;
    l,grw;
    m,eng;
    m,mu;
    n,math;
    n,geo;
    o,spo;
    o,fremd;
    p,eng;
    p,fremd;
    q,deu;
    q,fremd;
    r,deu;
    r,eng;
    s,eng;
    s,spo;
    t,te;
    t,eng;
    u,bio;
    u,phy
).
subject(X) :- teaches(_,X).
class(
    5..10,a;
    5..10,b
).
%classes per week (for class 5 only at the moment)
classperweek(
    5,de,5;
    5,info,0;
    5,eng,5;
    5,fremd,0;
    5,math,4;
    5,bio,2;
    5,chem,0;
    5,phy,0;
    5,ge,1;
    5,grw,0;
    5,geo,2;
    5,spo,3;
    5,eth,2;
    5,ku,2;
    5,mu,2;
    5,tec,0;
    5,nawi,0;
    5,gewi,0;
    5,reli,2
).
room(1..21).
%for monday to friday
weekday(1..5).

%for lesson 1 to 9 
slot(1..9).
dspyz
  • 5,280
  • 2
  • 25
  • 63
  • Thank you very much, that helped a lot. The usage of a cardinality constraint is way better then to compare every timetable pair. Also thank you very much that you took the time to rewrite my input. I copied the rules from the existing file and apparently created typos rearranging everything. I didn't know that you also can use ";" to make everything more readable. – Spiderwick Jan 02 '21 at 21:08