Open retorquere opened 8 years ago
Ruby appears to be Turing-complete. Therefore, so long as a problem is tractable, I'm sure there's a way to solve it in Ruby. :smiley:
I was unfamiliar with the nurse scheduling problem prior to this, but after a bit of research, here's my two cents on the problem:
First, this library is not built to handle soft constraints; only hard constraints. There are a few algorithms dedicated to "constrained optimization" problems, the general case of this problem, but we can still attempt to solve this problem by treating all constraints as hard constraints.
The problem as I understand it is as follows:
To build a constraint satisfaction problem (CSP) from this set of information, we need to choose variables, a set of constraints among sets of these variables, and assignable domain values for each variable. The CSP solver will do the rest by returning an assignment that does not violate any constraints.
Let's make a 2-day schedule (6 shifts), and there have to be 2 nurses on staff for each. Thus I'll choose to create two variables for each shift (each variable representing a position to be filled) for a total of 12 variables. I'll use the naming convention "day #, shift, position #" for my variable names:
d1_day_1
d1_day_2
d1_evening_1
d1_evening_2
d1_night_1
d1_night_2
d2_day_1
d2_day_2
d2_evening_1
d2_evening_2
d2_night_1
d2_night_2
Naturally, this would mean that the available nurses to fill positions are our domain values for these variables. If a nurse requests a holiday for day 2, then that person should not be in the domain of those variables. Suppose we have 8 nurses, A
through H
. Clever names, I know, but bear with me.
Now for our constraints. I'll use a globbing shorthand to keep it concise:
all_different(d1_*)
, all_different(d2_*)
constrain(d1_night*, d2_day*) { |a,b| a != b }
That should be all of the information needed to solve the problem. Let me know if any part of this was unclear.
A man after my heart :) I did mean to ask can this library be used to find a satisficing solution more efficiently than brute force or Monte Carlo.
Unfortunately, soft constraints are an important aspect of the nurse scheduling problem, and converting them to hard constraints may lead to the discarding of an acceptable solution.
Do you know of any other tools that can deal with soft constraints?
Haha. Always a pleasure to meet a fellow computer scientist!
I don't know of any Ruby libraries that address soft constraints or general-case optimization problems, but I'll keep an eye out. I'll throw some other related methods and algorithms I can think of into the mix just to help brainstorm:
@komputerwiz just a semi-related thought: could the library be extended to deal with soft constraints by keeping a counter of satisfied constraints and then outputting solutions in rank order of most constraints met?
@retorquere maybe a bit late, but this one might suit your needs https://github.com/gverger/ruby-cbc except I couldn't find a way to express "not equals".
@nurettin thanks! It's still of interest. It doesn't have NE constraints but I'm looking at whether they can be added to the lib.
I know I can in principle do this with OptaPlanner, but ruby is my language of preference, so if it can be done in ruby that would be really nice.