-1

Problem: Given a set of obligatory and optional courses each being available only in certain time slots (there are 7 time slots) generate all possible timetables.

Example:

For obligatory courses:

  • MAT101 - 1, 2, 5
  • HIS102 - 2, 4, 6
  • ENG105 - 3, 6, 7

And optional courses:

  • LIT103 - 3, 4, 6
  • CHE101 - 7, 1, 2
  • BIO101 - 5, 4, 7
  • MAT201 - 6, 5, 1
  • ANT201 - 1

(not every optional course must be included in a timetable)

One of the possible solutions would be:

  1. MAT101 [obligatory]
  2. HIS102 [obligatory]
  3. LIT103
  4. BIO101
  5. MAT201
  6. ENG105 [obligatory]
  7. CHE101

What's the most efficient way to write it in PHP?

I'm currently trying to develop a brute-force solution, but it's a very tedious task and I'm looking for more efficient ways to do it. I figured out it's a NP-complete problem and searched for PHP classes helpful in solving such a problems, but I'm afraid there is no such a class available at the moment.

glithc
  • 135
  • 4
  • It sounds like what you really need is an efficient algorithm for this type of problem (regardless of language). Have you tried looking at other languages, or outside of a specific language altogether for a solution? Once you have a solution (an algorithm), you will most likely be able to port it to PHP code. – Bryan Nov 06 '11 at 20:44
  • Yes, for quite some time. Java has Drools planner - a framework that specializes in solving NP problems, but althought it's open source I don't think I have the skill nor the time to port such a huge and complicated framework by myself. There is also constraint programming that's very helpful in solving such a problems,but I couldn't find any constraint programming libraries for PHP. – glithc Nov 06 '11 at 21:18

2 Answers2

0

First of all I agree with Bryan you first need to have a full understanding of the problem, then as for the algorithm the internet has tones of them.

You said that not every optional course must be included, this means that this pattern is the only one accepted:

obc x x x x x x

where obc is an obligatory lesson and x is obligatory or optinal. Order does not matter of course.

If you have N obligatory and M optional courses (obviosuly N+M>7 or N+M=7) then you can only have N accepted patterns of the above kind.

Then you have to find all different timetables of this kind:

X X X X X X (6 courses)

here the order does not matter and repetiotion is not allowed, so you need combinations of 6 out of (N+M) which will make:

(N+M)!/[6!(N+M-6)!] = K different such timetables.

Then all different timetables of 7 courses would be:

K+K+...+K (N times) = N*K

(Check carefully if this is correct, really tired today, otherwise would suggest some code).

I hope this can be of some help.

Melsi
  • 1,462
  • 1
  • 15
  • 21
0

The problem:

Problem: Given a set of obligatory and optional courses each being available only in certain time slots (there are 7 time slots) generate all possible timetables.

The key here is generate all possible timetables. doing this is simple, but takes exponential time any way you slice it, because you are essentially listing the entire search space (possibilities).

The would be recursive and take a list of pairs, the first of the pair being a time slot and the second element of the pair being a list of possible classes that could populate time slot. The data structure would look like this:

For obligatory courses:

  • 1 - MAT101, CHE101, MAT201, ANT201
  • 2 - MAT101, HIS102, CHE101
  • 3 - ENG105, LIT103

etc. where bolded courses are required. It would also take a list of courses which have already been picked by previous recursive calls of the method.

The function would

  • check to see if the list of possibilities (above described) contain, together with the list of courses already picked, contain all the required courses. If not, return.
  • pick the first available time slot (call it myPick), and then
  • for each possible class that would fill that time slot (call it currentClass),
    • If this method was only given 1 time slot in its first argument,
      • print the list of classes already picked (given as an argument).
      • print "$currentClass $myPick\n",
      • print an extra newline to separate the lists. return.
    • else recursively call the method, where you feed it the list of time slots that you haven't picked yet (the list of time slots given as an argument minus the one you just picked in step 2), except that each possibility list for the time slots has the class that you printed removed from it. the second argument of the recursive call should be the list of already picked classes given to this call instance with (<currentClass,myPick>) added to the list.

This should get you started.

djhaskin987
  • 9,741
  • 4
  • 50
  • 86