Algorithm for assigning people based on multiple criteria - algorithm

I have a list of users which need to be sorted into committees. The users can rank committees based on their particular preference, but must choose at least one to join. When they have all made their selections, the algorithm should sort them as evenly as possible taking into account their committee preference, gender, age, time zone and country (for now). I have looked at this question and its answer would seem like a good choice, but it is unclear to me how to add the various constraints to the algorithm for it to work.
Would anyone point me in the right direction on how to do this, please?

Looking for "clustering" will get you nowhere, because this is not a clustering type if task.
Instead, this is an assignment problem.
For further informarion, see:
Knapsack Problem
Generalized Assignment Problem
Usually, these are NP-hard to solve. Thus, one will usually choose a greedy optimization heuristic to find a reasonably good solution faster.
Think about how to best assign one person at a time.
Then, process the data as follows:
assign everybody that can only be assigned in a single way
find an unassigned person that is hard to assign, stop if everybody is assigned
assign the best possible way
remove preferences that are no longer admissible, and go to 1 again (there may be new person with only a single choice left)
For bonus points, add a source of randomness, and an overall quality measure. Then run the algorothm 10 times, and keep only the best result.
For further bonus, add an postprocessing optimization: when can you transfer one person to another group or swap to persons to improve the overall quality? Iterate over all persons to find such small improvements until you cannot find any.

Related

Algorithm to match a group's preferences to a single result?

I am trying to build a small app so that my friends and I can more easily make decisions about where we want to eat. The idea is that, given a list of restaurants, each person puts down a score from 0-100 indicating how much they like that restaurant. I want to figure out a good way to combine those scores to output an ordered list of recommendations. For discussion's sake, we can assume that everyone scores restaurants normally across the scale (i.e. let's assume the individual preference scores are valid/normalized/etc.).
As of now, I was thinking of just sorting by the average score of each restaurant while enforcing a minimum score from each person so that no one is very unhappy. In other words, the goal is to maximize happiness with the constraint that no one should be extremely unhappy.
Does anyone have any suggestions on a clever algorithm or better way to achieve this? Is there any research on matching problems that could be relevant to this, or am I just over-thinking it?
Your can first compute for each restaurant:
- the mean value
- the minimum value
Then you can easily sort by mean with any constraint you need.
Other intersting methods exist. You can for instance use minimax. It means you sort by maximum among the restaurant minimums. It guarantees that noone would hate this restaurant.
This looks like the Weighted voting system, check wikipedia or other Internet resources.
Note that this system can easily be manipulated if voters or not honnest, you probably want another system.

Algorithm for creating a school timetable

I've been wondering if there are known solutions for algorithm of creating a school timetable. Basically, it's about optimizing "hour-dispersion" (both in teachers and classes case) for given class-subject-teacher associations. We can assume that we have sets of classes, lesson subjects and teachers associated with each other at the input and that timetable should fit between 8AM and 4PM.
I guess that there is probably no accurate algorithm for that, but maybe someone knows a good approximation or hints for developing it.
This problem is NP-Complete!
In a nutshell one needs to explore all possible combinations to find the list of acceptable solutions. Because of the variations in the circumstances in which the problem appears at various schools (for example: Are there constraints with regards to classrooms?, Are some of the classes split in sub-groups some of the time?, Is this a weekly schedule? etc.) there isn't a well known problem class which corresponds to all the scheduling problems. Maybe, the Knapsack problem has many elements of similarity with these problems at large.
A confirmation that this is both a hard problem and one for which people perennially seek a solution, is to check this (long) list of (mostly commercial) software scheduling tools
Because of the big number of variables involved, the biggest source of which are, typically, the faculty member's desires ;-)..., it is typically impractical to consider enumerating all possible combinations. Instead we need to choose an approach which visits a subset of the problem/solution spaces.
- Genetic Algorithms, cited in another answer is (or, IMHO, seems) well equipped to perform this kind of semi-guided search (The problem being to find a good evaluation function for the candidates to be kept for the next generation)
- Graph Rewriting approaches are also of use with this type of combinatorial optimization problems.
Rather than focusing on particular implementations of an automatic schedule generator program, I'd like to suggest a few strategies which can be applied, at the level of the definition of the problem.
The general rationale is that in most real world scheduling problems, some compromises will be required, not all constraints, expressed and implied: will be satisfied fully. Therefore we help ourselves by:
Defining and ranking all known constraints
Reducing the problem space, by manually, providing a set of additional constraints.This may seem counter-intuitive but for example by providing an initial, partially filled schedule (say roughly 30% of the time-slots), in a way that fully satisfies all constraints, and by considering this partial schedule immutable, we significantly reduce the time/space needed to produce candidate solutions. Another way additional constraints help is for example "artificially" adding a constraint which prevent teaching some subjects on some days of the week (if this is a weekly schedule...); this type of constraints results in reducing the problem/solution spaces, without, typically, excluding a significant number of good candidates.
Ensuring that some of the constraints of the problem can be quickly computed. This is often associated with the choice of data model used to represent the problem; the idea is to be able to quickly opt-for (or prune-out) some of the options.
Redefining the problem and allowing some of the constraints to be broken, a few times, (typically towards the end nodes of the graph). The idea here is to either remove some of constraints for filling-in the last few slots in the schedule, or to have the automatic schedule generator program stop shy of completing the whole schedule, instead providing us with a list of a dozen or so plausible candidates. A human is often in a better position to complete the puzzle, as indicated, possibly breaking a few of the contraints, using information which is not typically shared with the automated logic (eg "No mathematics in the afternoon" rule can be broken on occasion for the "advanced math and physics" class; or "It is better to break one of Mr Jones requirements than one of Ms Smith ... ;-) )
In proof-reading this answer , I realize it is quite shy of providing a definite response, but it none the less full of practical suggestions. I hope this help, with what is, after all, a "hard problem".
It's a mess. a royal mess. To add to the answers, already very complete, I want to point out my family experience. My mother was a teacher and used to be involved in the process.
Turns out that having a computer to do so is not only difficult to code per-se, it is also difficult because there are conditions that are difficult to specify to a pre-baked computer program. Examples:
a teacher teaches both at your school and at another institute. Clearly, if he ends the lesson there at 10.30, he cannot start at your premises at 10.30, because he needs some time to commute between the institutes.
two teachers are married. In general, it's considered good practice not to have two married teachers on the same class. These two teachers must therefore have two different classes
two teachers are married, and their child attends the same school. Again, you have to prevent the two teachers to teach in the specific class where their child is.
the school has separate facilities, like one day the class is in one institute, and another day the class is in another.
the school has shared laboratories, but these laboratories are available only on certain weekdays (for security reasons, for example, where additional personnel is required).
some teachers have preferences for the free day: some prefer on Monday, some on Friday, some on Wednesday. Some prefer to come early in the morning, some prefer to come later.
you should not have situations where you have a lesson of say, history at the first hour, then three hours of math, then another hour of history. It does not make sense for the students, nor for the teacher.
you should spread the arguments evenly. It does not make sense to have the first days in the week only math, and then the rest of the week only literature.
you should give some teachers two consecutive hours to do evaluation tests.
As you can see, the problem is not NP-complete, it's NP-insane.
So what they do is that they have a large table with small plastic insets, and they move the insets around until a satisfying result is obtained. They never start from scratch: they normally start from the previous year timetable and make adjustments.
The International Timetabling Competition 2007 had a lesson scheduling track and exam scheduling track. Many researchers participated in that competition. Lots of heuristics and metaheuristics were tried, but in the end the local search metaheuristics (such as Tabu Search and Simulated Annealing) clearly beat other algorithms (such as genetic algorithms).
Take a look at the 2 open source frameworks used by some of the finalists:
JBoss OptaPlanner (Java, open source)
Unitime (Java, open source) - more for universities
One of my half-term assignments was an genetic-algorithm school table generation.
Whole table is one "organism". There were some changes and caveats to the generic genetic algorithms approach:
Rules were made for "illegal tables": two classes in the same classroom, one teacher teaching two groups at the same time etc. These mutations were deemed lethal immediately and a new "organism" was sprouted in place of the "deceased" immediately. The initial one was generated by a series of random tries to get a legal (if senseless) one. Lethal mutation wasn't counted towards count of mutations in iteration.
"Exchange" mutations were much more common than "Modify" mutations. Changes were only between parts of the gene that made sense - no substituting a teacher with a classroom.
Small bonuses were assigned for bundling certain 2 hours together, for assigning same generic classroom in sequence for the same group, for keeping teacher's work hours and class' load continuous. Moderate bonuses were assigned for giving correct classrooms for given subject, keeping class hours within bonds (morning or afternoon), and such. Big bonuses were for assigning correct number of given subject, given workload for a teacher etc.
Teachers could create their workload schedules of "want to work then", "okay to work then", "doesn't like to work then", "can't work then", with proper weights assigned. Whole 24h were legal work hours except night time was very undesired.
The weight function... oh yeah. The weight function was huge, monstrous product (as in multiplication) of weights assigned to selected features and properties. It was extremely steep, one property easily able to change it by an order of magnitude up or down - and there were hundreds or thousands of properties in one organism. This resulted in absolutely HUGE numbers as the weights, and as a direct result, need to use a bignum library (gmp) to perform the calculations. For a small testcase of some 10 groups, 10 teachers and 10 classrooms, the initial set started with note of 10^-200something and finished with 10^+300something. It was totally inefficient when it was more flat. Also, the values grew a lot wider distance with bigger "schools".
Computation time wise, there was little difference between a small population (100) over a long time and a big population (10k+) over less generations. The computation over the same time produced about the same quality.
The calculation (on some 1GHz CPU) would take some 1h to stabilize near 10^+300, generating schedules that looked quite nice, for said 10x10x10 test case.
The problem is easily paralellizable by providing networking facility that would exchange best specimens between computers running the computation.
The resulting program never saw daylight outside getting me a good grade for the semester. It showed some promise but I never got enough motivation to add any GUI and make it usable to general public.
This problem is tougher than it seems.
As others have alluded to, this is a NP-complete problem, but let's analyse what that means.
Basically, it means you have to look at all possible combinations.
But "look at" doesn't tell you much what you need to do.
Generating all possible combinations is easy. It might produce a huge amount of data, but you shouldn't have much problems understanding the concepts of this part of the problem.
The second problem is the one of judging whether a given possible combination is good, bad, or better than the previous "good" solution.
For this you need more than just "is it a possible solution".
For instance, is the same teacher working 5 days a week for X weeks straight? Even if that is a working solution, it might not be a better solution than alternating between two people so that each teacher does one week each. Oh, you didn't think about that? Remember, this is people you're dealing with, not just a resource allocation problem.
Even if one teacher could work full-time for 16 weeks straight, that might be a sub-optimal solution compared to a solution where you try to alternate between teachers, and this kind of balancing is very hard to build into software.
To summarize, producing a good solution to this problem will be worth a lot, to many many people. Hence, it's not an easy problem to break down and solve. Be prepared to stake out some goals that aren't 100% and calling them "good enough".
My timetabling algorithm, implemented in FET (Free Timetabling Software, http://lalescu.ro/liviu/fet/ , a successful application):
The algorithm is heuristic. I named it "recursive swapping".
Input: a set of activities A_1...A_n and the constraints.
Output: a set of times TA_1...TA_n (the time slot of each activity. Rooms are excluded here, for simplicity). The algorithm must put each activity at a time slot, respecting constraints. Each TA_i is between 0 (T_1) and max_time_slots-1 (T_m).
Constraints:
C1) Basic: a list of pairs of activities which cannot be simultaneous (for instance, A_1 and A_2, because they have the same teacher or the same students);
C2) Lots of other constraints (excluded here, for simplicity).
The timetabling algorithm (which I named "recursive swapping"):
Sort activities, most difficult first. Not critical step, but speeds up the algorithm maybe 10 times or more.
Try to place each activity (A_i) in an allowed time slot, following the above order, one at a time. Search for an available slot (T_j) for A_i, in which this activity can be placed respecting the constraints. If more slots are available, choose a random one. If none is available, do recursive swapping:
a. For each time slot T_j, consider what happens if you put A_i into T_j. There will be a list of other activities which don't agree with this move (for instance, activity A_k is on the same slot T_j and has the same teacher or same students as A_i). Keep a list of conflicting activities for each time slot T_j.
b. Choose a slot (T_j) with lowest number of conflicting activities. Say the list of activities in this slot contains 3 activities: A_p, A_q, A_r.
c. Place A_i at T_j and make A_p, A_q, A_r unallocated.
d. Recursively try to place A_p, A_q, A_r (if the level of recursion is not too large, say 14, and if the total number of recursive calls counted since step 2) on A_i began is not too large, say 2*n), as in step 2).
e. If successfully placed A_p, A_q, A_r, return with success, otherwise try other time slots (go to step 2 b) and choose the next best time slot).
f. If all (or a reasonable number of) time slots were tried unsuccessfully, return without success.
g. If we are at level 0, and we had no success in placing A_i, place it like in steps 2 b) and 2 c), but without recursion. We have now 3 - 1 = 2 more activities to place. Go to step 2) (some methods to avoid cycling are used here).
UPDATE: from comments ... should have heuristics too!
I'd go with Prolog ... then use Ruby or Perl or something to cleanup your solution into a prettier form.
teaches(Jill,math).
teaches(Joe,history).
involves(MA101,math).
involves(SS104,history).
myHeuristic(D,A,B) :- [test_case]->D='<';D='>'.
createSchedule :- findall(Class,involves(Class,Subject),Classes),
predsort(myHeuristic,Classes,ClassesNew),
createSchedule(ClassesNew,[]).
createSchedule(Classes,Scheduled) :- [the actual recursive algorithm].
I am (still) in the process of doing something similar to this problem but using the same path as I just mentioned. Prolog (as a functional language) really makes solving NP-Hard problems easier.
Genetic algorithms are often used for such scheduling.
Found this example (Making Class Schedule Using Genetic Algorithm) which matches your requirement pretty well.
Here are a few links I found:
School timetable - Lists some problems involved
A Hybrid Genetic Algorithm for School Timetabling
Scheduling Utilities and Tools
This paper describes the school timetable problem and their approach to the algorithm pretty well: "The Development of SYLLABUS—An Interactive, Constraint-Based Scheduler for Schools and Colleges."[PDF]
The author informs me the SYLLABUS software is still being used/developed here: http://www.scientia.com/uk/
I work on a widely-used scheduling engine which does exactly this. Yes, it is NP-Complete; the best approaches seek to approximate an optimal solution. And, of course there are a lot of different ways to say which one is the "best" solution - is it more important that your teachers are happy with their schedules, or that students get into all their classes, for instance?
The absolute most important question you need to resolve early on is what makes one way of scheduling this system better than another? That is, if I have a schedule with Mrs Jones teaching Math at 8 and Mr Smith teaching Math at 9, is that better or worse than one with both of them teaching Math at 10? Is it better or worse than one with Mrs Jones teaching at 8 and Mr Jones teaching at 2? Why?
The main advice I'd give here is to divide the problem up as much as possible - maybe course by course, maybe teacher by teacher, maybe room by room - and work on solving the sub-problem first. There you should end up with multiple solutions to choose from, and need to pick one as the most likely optimal. Then, work on making the "earlier" sub-problems take into account the needs of later sub-problems in scoring their potential solutions. Then, maybe work on how to get yourself out of painted-into-the-corner situations (assuming you can't anticipate those situations in earlier sub-problems) when you get to a "no valid solutions" state.
A local-search optimization pass is often used to "polish" the end answer for better results.
Note that typically we are dealing with highly resource-constrained systems in school scheduling. Schools don't go through the year with a lot of empty rooms or teachers sitting in the lounge 75% of the day. Approaches which work best in solution-rich environments aren't necessarily applicable in school scheduling.
Generally, constraint programming is a good approach to this type of scheduling problem. A search on "constraint programming" and scheduling or "constraint based scheduling" both within stack overflow and on Google will generate some good references. It's not impossible - it's just a little hard to think about when using traditional optimization methods like linear or integer optimization. One output would be - does a schedule exist that satisfies all the requirements? That, in itself, is obviously helpful.
Good luck !
I have designed commercial algorithms for both class timetabling and examination timetabling. For the first I used integer programming; for the second a heuristic based on maximizing an objective function by choosing slot swaps, very similar to the original manual process that had been evolved. They main things in getting such solutions accepted are the ability to represent all the real-world constraints; and for human timetablers to not be able to see ways to improve the solution. In the end the algorithmic part was quite straightforward and easy to implement compared with the preparation of the databases, the user interface, ability to report on statistics like room utilization, user education and so on.
You can takle it with genetic algorithms, yes. But you shouldn't :). It can be too slow and parameter tuning can be too timeconsuming etc.
There are successful other approaches. All implemented in open source projects:
Constraint based approach
Implemented in UniTime (not really for schools)
You could also go further and use Integer programming. Successfully done at Udine university and also at University Bayreuth (I was involved there) using the commercial software (ILOG CPLEX)
Rule based approach with heuristisc - See Drools planner
Different heuristics - FET and my own
See here for a timetabling software list
I think you should use genetic algorithm because:
It is best suited for large problem instances.
It yields reduced time complexity on the price of inaccurate answer(Not the ultimate best)
You can specify constraints & preferences easily by adjusting fitness punishments for not met ones.
You can specify time limit for program execution.
The quality of solution depends on how much time you intend to spend solving the program..
Genetic Algorithms Definition
Genetic Algorithms Tutorial
Class scheduling project with GA
Also take a look at :a similar question and another one
This problem is MASSIVE where I work - imagine 1800 subjects/modules, and 350 000 students, each doing 5 to 10 modules, and you want to build an exam in 10 weeks, where papers are 1 hour to 3 days long... one plus point - all exams are online, but bad again, cannot exceed the system's load of max 5k concurrent. So yes we are doing this now in cloud on scaling servers.
The "solution" we used was simply to order modules on how many other modules they "clash" with descending (where a student does both), and to "backpack" them, allowing for these long papers to actually overlap, else it simply cannot be done.
So when things get too large, I found this "heuristic" to be practical... at least.
I don't know any one will agree with this code but i developed this code with the help of my own algorithm and is working for me in ruby.Hope it will help them who are searching for it
in the following code the periodflag ,dayflag subjectflag and the teacherflag are the hash with the corresponding id and the flag value which is Boolean.
Any issue contact me.......(-_-)
periodflag.each do |k2,v2|
if(TimetableDefinition.find(k2).period.to_i != 0)
subjectflag.each do |k3,v3|
if (v3 == 0)
if(getflag_period(periodflag,k2))
#teachers=EmployeesSubject.where(subject_name: #subjects.find(k3).name, division_id: division.id).pluck(:employee_id)
#teacherlists=Employee.find(#teachers)
teacherflag=Hash[teacher_flag(#teacherlists,teacherflag,flag).to_a.shuffle]
teacherflag.each do |k4,v4|
if(v4 == 0)
if(getflag_subject(subjectflag,k3))
subjectperiod=TimetableAssign.where("timetable_definition_id = ? AND subject_id = ?",k2,k3)
if subjectperiod.blank?
issubjectpresent=TimetableAssign.where("section_id = ? AND subject_id = ?",section.id,k3)
if issubjectpresent.blank?
isteacherpresent=TimetableAssign.where("section_id = ? AND employee_id = ?",section.id,k4)
if isteacherpresent.blank?
#finaltt=TimetableAssign.new
#finaltt.timetable_struct_id=#timetable_struct.id
#finaltt.employee_id=k4
#finaltt.section_id=section.id
#finaltt.standard_id=standard.id
#finaltt.division_id=division.id
#finaltt.subject_id=k3
#finaltt.timetable_definition_id=k2
#finaltt.timetable_day_id=k1
set_school_id(#finaltt,current_user)
if(#finaltt.save)
setflag_sub(subjectflag,k3,1)
setflag_period(periodflag,k2,1)
setflag_teacher(teacherflag,k4,1)
end
end
else
#subjectdetail=TimetableAssign.find_by_section_id_and_subject_id(#section.id,k3)
#finaltt=TimetableAssign.new
#finaltt.timetable_struct_id=#subjectdetail.timetable_struct_id
#finaltt.employee_id=#subjectdetail.employee_id
#finaltt.section_id=section.id
#finaltt.standard_id=standard.id
#finaltt.division_id=division.id
#finaltt.subject_id=#subjectdetail.subject_id
#finaltt.timetable_definition_id=k2
#finaltt.timetable_day_id=k1
set_school_id(#finaltt,current_user)
if(#finaltt.save)
setflag_sub(subjectflag,k3,1)
setflag_period(periodflag,k2,1)
setflag_teacher(teacherflag,k4,1)
end
end
end
end
end
end
end
end
end
end
end

Algorithm for a planning tool

I'm writing a small software application that needs to serve as a simple planning tool for a local school. The 'problem' it needs to solve is fairly basic. Namely, the teachers need to talk with the parents of all children. However, some children have, of course, brothers and sisters in different groups, so these talks need to be scheduled next to eachother, to avoid the situations were parents have a talk at 6 pm and another one at 10 pm. Thus in short, given a collection of n children, where some children have 1 or more brothers or sisters, generate a schedule where all the talks of these children are planned next to each other.
Now, maybe the problem can be solved extremely easy, but on the other I have a feeling this can be a pretty complicated problem, that needs and can be solved with some sort of algorithm. Elegantly. But am I right? Is there? I've looked at the Hungarian alorithm but it doesn't quite apply to this particular problem.
Edit: I forgot to mention, that all talks take the same amount of time.
Thanks!
I think it is quite easy.
First group the kids which belong together because they share parents. Schedule the children inside a group consecutively, schedule the rest as random.
Another way to abstract it and make the problem easier is to look from the parent perspective, see brothers and sister as "child" and give them more time. Then you can just schedule the parents at random, but some need more time (because they have multiple childeren).
One approach woul dbe to define the problem in a declarative constraint language and then let it solve the problem for you. The last time I did this, I used ECLiPSe, which is a nifty little language where you define your problem space by constraints, and then let it find allowable values that satisfy those constraints.
For example, I believe you have two classes of constraints:
A teacher may only have one
conference at a time
All students in the same family must
have consecutive slots
Once you define these in ECLiPSe, it will calculate values for each student that satisfy the requirements. If you go this way, you can also easily add constraints as you need to. For example, it's easy to say that a teach is unavailable for slot Y, or teachers must take turns doing administrative work, etc.
This sorts feels like a "backpack algorithm" type of problem. You need to group the family members together then fill slots appropriately.
If you google "backpack algorithm", you'll see enough write-ups to make your head spin and also some good coded solutions.
I think if each talk could be reduced to "activities" where each activity has a start time and an end time you could use the activity-selection algorithm studied in computer science. It is based on a greedy approach and could be solved in O(n) (where n is the number of activities). You could find more information here. I am sure you will need to have to do a pre-processing here to be able to reduce the brother/sister issue as activities of the same type.

Possible NP-complete problem?

I'd just like someone to verify whether the following problem is NP-complete or if there is actually a better/easier solution to it than simple brute-force combination checking.
We have a sort-of resource allocation problem in our software, and I'll explain it with an example.
Let's say we need 4 people to be at work during the day-shift. This number, and the fact that it is a "day-shift" is recorded in our database.
However, we don't require just anyone to fill those spots, there's some requirements that needs to be filled in order to fit the bill.
Of those 4, let's say 2 of them has to be a nurse, and 1 of them has to be doctors.
One of the doctors also has to work as part of a particular team.
So we have this set of information:
Day-shift: 4
1 doctor
1 doctor, need to work in team A
1 nurse
The above is not the problem. The problem comes when we start picking people to work the day-shift and trying to figure out if the people we've picked so far can actually fill the criteria.
For instance, let's say we pick James, John, Ursula and Mary to work, where James and Ursula are doctors, John and Mary are nurses.
Ursula also works in team A.
Now, depending on the order we try to fit the bill, we might end up deducing that we have the right people, or not, unless we start trying different combinations.
For instance, if go down the list and pick Ursula first, we could match her with the "1 doctor" criteria. Then we get to James, and we notice that since he doesn't work in team A, the other criteria about "1 doctor, need to work in team A", can't be filled with him. Since the other two people are nurses, they won't fit that criteria either.
So we backtrack and try James first, and he too can fit the first criteria, and then Ursula can fit the criteria that needs that team.
So the problem looks to us as we need to try different combinations until we've either tried them all, in which case we have some criteria that aren't filled yet, even if the total number of heads working is the same as the total number of heads needed, or we've found a combination that works.
Is this the only solution, can anyone think of a better one?
Edit: Some clarification.
Comments to this question mentions that with this few people, we should go with brute-force, and I agree, that's probably what we could do, and we might even do that, in the same lane that some sort optimizations look at the size of the data and picks different sort algorithms with less initial overhead if the data size is small.
The problem though is that this is part of a roster planning system, in which you might have quite a few number of people involved, both as "We need X people on the day shift" as well as "We have this pool of Y people that will be doing it", as well as potential for a large "We have this list of Z criteria for those X people that will have to somehow match up with these Y people", and then you add to the fact that we will have a number of days to do the same calculation for, in real-time, as the leader adjusts the roster, and then the need for a speedy solution has come up.
Basically, the leader will see a live sum information on-screen that says how many people are still missing, both on the day-shift as a whole, as well as how many people is fitting the various criteria, and how many people we actually ned in addition to the ones we have. This display will have to update semi-live while the leader adjusts the roster with "What if James takes the day-shift instead of Ursula, and Ursula takes the night-shift".
But huge thanks to the people that has answered this so far, the constraint satisfaction problem sounds like the way we need to go, but we'll definitely look hard at all the links and algorithm names here.
This is why I love StackOverflow :)
What you have there is a constraint satisfaction problem; their relationship to NP is interesting, because they're typically NP but often not NP-complete, i.e. they're tractable to polynomial-time solutions.
As ebo noted in comments, your situation sounds like it can be formulated as an exact cover problem, which you can apply Knuth's Algorithm X to. If you take this tack, please let us know how it works out for you.
It does look like you have a constraint satisfaction problem.
In your case I would particularly look at constraint propagation techniques first -- you may be able to reduce the problem to a manageable size that way.
What happens if no one fits the criteria?
What you are describing is the 'Roommate Problem' it is lightly described in this thesis.
Bear with me, I'm searching for better links.
EDIT
Here's another fairly dense thesis.
As for me I would most likely trying to find reduction to bipartite graph matching problem. Also to prove that problem is NP usually is much more complicated than staying you cannot find polynomial solution.
I am not sure your problem is NP, it does not smell that way, but what I would do if I was you would be to order the requirements for the positions such that you try to fill the most specific first since fewer people will be available fill these positions, so you are less likely to have to backtrack a lot. There is no reason why you should not combine this with algorithm X, an algorithm of pure Knuth-ness.
I'll leave the theory to others, since my mathematical savvy is not so great, but you may find a tool like Cassowary/Cassowary.net or NSolver useful to represent your problem declaratively as a constraint satisfaction problem and then solve the constraints.
In such tools, the simplex method combined with constraint propagation is frequently employed to deterministically reduce the solution space and then find an optimal solution given a cost function. For larger solution spaces (which don't seem to apply in the size of problem you specify), occasionally genetic algorithms are employed.
If I remember correctly, NSolver also includes in sample code a simplification of an actual Nurse-rostering problem that Dr. Chun worked on in Hong Kong. And there's a paper on the work he did.
It sounds to me like you have a couple of separable problems that would be a lot easier to solve:
-- select one doctor from team A
-- select another doctor from any team
-- select two nurses
So you have three independent problems.
A clarification though, do you have to have two doctors (one from the specified team) and two nurses, or one doctor from the specified team, two nurses, and one other that can be either doctor or nurse?
Some Questions:
Is the goal to satisfy the constraints exactly, or only approximately (but as much as possible)?
Can a person be a member of several teams?
What are all possible constraints? (For example, could we need a doctor which is a member of several teams?)
If you want to satisfy the constraints exactly, then I would order the constraints decreasingly by strictness, that is, the ones which are most hardest to achieve (e.g. doctor AND team A in your example above) should be checked first!
If you want to satisfy the constraints approximately, then its a different story... you would have to specify some kind of weighting/importance-function which determines what we rather would have, when we can't match exactly, and have several possibilities to choose from.
If you have several or many constraints, take a look at Drools Planner (open source, java).
Brute force, branch and bound and similar techniques take to long. Deterministic algorithms such as fill the largest shifts first are very suboptimal. Meta-heuristics are a very good way to deal with this.
Take a specific look at the real-world nurse rostering example of Drools Planner. It's easy to add many constraints, such as "young nurses don't want to work the Saturday night" or "some nurses don't want to work to many days in a row".

Teacher time schedule algorithm

This is a problem I've had on my mind for a long time. Being the son of a teacher and a programmer, it occurred to me early on... but I still haven't found a solution for it.
So this is the problem. One needs to create a time schedule for a school, using some constraints. These are generally divided in two categories:
Sanity Checks
A teacher cannot teach two classes at the same time
A student cannot follow two lessons at the same time
Some teachers must have at least one day off during the week
All the days of the week should be covered by the time table
Subject X must have exactly so-and-so hours each week
...
Preferences
Each teacher's schedule should be as compact as possible (i.e. the teacher should work all hours for the day in a row with no pauses if possible)
Teachers that have days off should be able to express a preference on which day
Teachers that work part-time should be able to express a preference whether to work in the beginning or the end of the school day.
...
Now, after a few years of not finding a solution (and learning a thing or two in the meanwhile...), I realized that this smells like a NP-hard problem.
Is it proven as NP-hard?
Does anyone have an idea on how to crack this thing?
Looking at this question made me think about this problem, and whether genetic algorithms would be usable in this case. However it would be pretty hard to mutate possibilities while maintaining the sanity check rules. Also it's not clear to me how to distinguish incompatible requirements.
A small addendum to better specify the problem. This is applied to Italian school style classrooms where all students are associated in different classes (for example: year 1 section A) and the teachers move between classes. All students of the same class have the same schedule, and have no choice over which lessons to attend.
I am one of the developer that works on the scheduler part of a student information system.
During our original approach of the scheduling problem, we researched genetic algorithms to solve constraint satisfaction problems, and even though we were successful initially, we realized that there was a less complicated solution to the problem (after attending a school scheduling workshop)
Our current implementation works great, and uses brute force with smart heuristics to get a valid schedule in a short amount of time. The master schedule (assignment of the classes to the teachers) is first built, taking in consideration all the constraints that each teacher has while minimizing the possibility of conflicts for the students (based of their course requests). The students are then scheduled in the classes using the same method.
Doing this allows you to have the machine build a master schedule first, and then have a human tweak it if needed.
The scheduler current implementation is written in perl, but other options we visited early on were Prolog and CLIPS (expert system)
I think you might be missing some constraints.
One would prefer where possible to have teachers scheduled to classes for which they are certified.
One would suspect that the classes that are requested, and the expected headcount in each would be significant.
I think the place to start would be to list all of your constraints, figure out a data structure to represent them.
Then create some sort of engine to that builds a trial solution, then evaluates it for fitness according to the constraints.
You could then throw the fun genetic algorithms part at it, and see if you can get the fitness to increase over time as the genes mix.
Start with a small set of constraints, and increase them as you see success (if you see success)
There might be a way to take the constraints and shoehorn them together with something like a linear programming algorithm.
I agree. It sounds like a fun challenge
This is a mapping problem:
you need to map to every hour in a week and every teacher an activity (teach to a certain class or free hour ).
Split the problem:
Create the list of teachers, classes and preferences then let the user populate some of the preferences on a map to have as a starting point.
Randomly take one element from the list and put it at a random free position on the map
if it doesn't cross any sanity checks until the list is empty. If at any certain iteration you can't place an element on the map without crossing a sanity check shift two positions on the map and try again.
When the map is filled, try shifting positions on the map to optimize the result.
In steps 2 and 3 show each iteration to the user: items left in the list, positions on the map and the next computed move and let the user intervene.
I did not try this, but this would be my initial approach.
I've tackled similar planning/scheduling problems in the past and the AI technique that is often best suited for this class of problem is "Constraint Based Reasoning".
It's basically a brute force method like Laurenty suggested, but the approach involves applying constraints in an efficient order to cause the infeasible solutions to fail fast - to minimise the computation required.
Googling "Constraint Based Reasoning" brings up a lot of resources on the technique and its application to scheduling problems.
Answering my own question:
The FET project mentioned by gnud uses this algorithm:
Some words about the algorithm: FET
uses a heuristical algorithm, placing
the activities in turn, starting with
the most difficult ones. If it cannot
find a solution it points you to the
potential impossible activities, so
you can correct errors. The algorithm
swaps activities recursively if that
is possible in order to make space for
a new activity, or, in extreme cases,
backtracks and switches order of
evaluation. The important code is in
src/engine/generate.cpp. Please e-mail
me for details or join the mailing
list. The algorithm mimics the
operation of a human timetabler, I
think.
Link
Following up the "Constraint Based Reasoning" lead by Stringent Software on Wikipedia lead me to these pages which have an interesting paragraph:
Solving a constraint satisfaction
problem on a finite domain is an
NP-complete problem in general.
Research has shown a number of
polynomial-time subcases, mostly
obtained by restricting either the
allowed domains or constraints or the
way constraints can be placed over the
variables. Research has also
established relationship of the
constraint satisfaction problem with
problems in other areas such as finite
model theory and databases.
This reminds me of this blog post about scheduling a conference, with a video explanation here.
How I would do it:
Have the population include two things:
Who teaches what class (I expect the teachers to teach one subject).
What a class takes on a specific time slot.
This way we can't have conflicts (a teacher in 2 places, or a class having two subjects at the same time).
The fitness function would include:
How many time slots each teacher gives per week.
How many time slots a teacher has on the same day (They can't have a full day of teaching, this too must be balanced).
How many time slots of the same subject a class has on the same day (They can't have a full day of math!).
Maybe take the standard deviation for all of them since they should be balanced.
Looking at this question made me think
about this problem, and whether
genetic algorithms would be usable in
this case. However it would be pretty
hard to mutate possibilities while
maintaining the sanity check rules.
Also it's not clear to me how to
distinguish incompatible requirements.
Genetic Algorithms are very well suited to problems such as this. Once you come up with a decent representation of the chromosome (in this case, probably a vector representing all of the available class slots) you're most of the way there.
Don't worry about maintaining sanity checks during the mutation phase. Mutation is random. Sanity and preference checks both belong in the selection phase. A failed sanity check would drastically lower the fitness of an individual, while a failed preference would only mildly lower the fitness.
Incompatible requirements are a different problem altogether. If they're completely incompatible, you'll get a population that doesn't converge on anything useful.
Good luck. Being the son of a father with this sort of problem is what took me to the research group that I ended up in ...
When I was a kid my father scheduled match officials in a local sports league, this had a similarly long list of constraints and I tried to write something to help. When I got to University I even used it as my final year project eventually settling on a Monte Carlo implementation (using a Simulated Annealing model).
The basic idea is that if it's not NP, it's pretty close, so rather than assuming there is a solution, I would set out to find the best within a given timeframe. I would weight all the constraints with costs for breaking them: sanity checks would have huge costs, the preferences would have lower costs (but increasing for more breaks, so breaking it once would be less than half the cost of breaking it twice).
The basic idea is that I started with a 'random' solution and costed it; then made changes by swapping a small number of assignments, re-valued it and then, probalistically accepted or declined the change.
After thousands of iterations you inch closer to an acceptable solution.
Believe me, though, that this class of problems has research groups churning out PhDs so you're in very good company.
You might also find some interest in the Linear Programming arena, e.g. simplex and so on.
Yes, I think this is NP complete - or at least to find the optimal solution is NP complete.
I worked on a similar problem in college when i told a friend's father (who was a teacher) that I could solve his scheduling problems for him if he did not find a suitable program for it (this was back in 1990 or so)
I had no idea what I got myself into. Luckily for us all I had to do was find one solution that fit the constraints. But in my testing I was always worried about determining IF there was a solution at all. He never had too many constraints and the program used different heuristics and back tracking. It was a lot of fun.
I think Bill Gates also worked on a system like this in high school or college for his high school. Not sure though.
Good luck. All my notes are gone and I never got around to implementing a solution that I could market. It was a specialty project that I re-coded as I learned new languages (Basic, Scheme, C, VB, C++)
Have fun with it
i see that this problem can be solved by Prolog program by connecting it to a database
and the program can make the schedule given a set of constraints
read abt "Constraint satisfaction Problem prolog"

Resources