Question

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 :)

Was it helpful?

Solution

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.

OTHER TIPS

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:

  1. Is the goal to satisfy the constraints exactly, or only approximately (but as much as possible)?
  2. Can a person be a member of several teams?
  3. 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".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top