komputerwiz / csp-solver

A Ruby library for solving any type of constraint satisfaction problem (CSP)
http://komputerwiz.net/apps/csp-solver
MIT License
39 stars 9 forks source link

How would I go about implementing the nurse scheduling problem using csp-solver? #2

Open retorquere opened 8 years ago

retorquere commented 8 years ago

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.

komputerwiz commented 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:

  1. d1_day_1
  2. d1_day_2
  3. d1_evening_1
  4. d1_evening_2
  5. d1_night_1
  6. d1_night_2
  7. d2_day_1
  8. d2_day_2
  9. d2_evening_1
  10. d2_evening_2
  11. d2_night_1
  12. 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:

That should be all of the information needed to solve the problem. Let me know if any part of this was unclear.

retorquere commented 8 years ago

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?

komputerwiz commented 8 years ago

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:

mooreniemi commented 8 years ago

@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?

nurettin commented 6 years ago

@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".

retorquere commented 6 years ago

@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.