+1  A: 

I don't understand baseball at all so sorry if I'm on the wrong track. I do like rounders though, but there are only 2 positions to play in rounders, a batter or everyone else.

Have you considered using Genetic Algorithms to solve this problem? They are very good at solving NP hard problems and work surprisingly well for rota and time schedule type problems as well.

You have a solution model which can easily be scored and easily manipulated which is a great start for a genetic algorithm.

For more complex problems where the total permutations are too large to calculate a genetic algorithm should find a near optimum or excellent solution (along with lots and lots of other valid solutions) in a fairly short amount of time. Although if you wish the find the optimum solution every time, you are going to have to brute force it in all likelihood (I have only skimmed the problem so this may not be the case but it sounds like it probably is).

In your example, you would have a solution class, this represents a solution, IE a line-up for the baseball team. You randomly generate say 20 solutions, regardless if they are valid or not, then you have a rating algorithm that rates the solution. In your case, a better player in the line-up would score more than a worse player, and any invalid line-ups (for whatever reason) would force a score of 0.

Any 0 scoring solutions are killed off, and replaced with new random ones, and the rest of the solutions breed together to form new solutions. Theoretically and after enough time the pool of solutions should improve.

This has the benefit of not only finding lots of valid unique line-ups, but also rating them. You didn't specify in your problem the need to rate the solutions, but it offers plenty of benefits (for example if a player is injured, he can be temporarily rated as a -10 or whatever). All other players score based on their quantifiable stats.

It's scalable and performs well.

Tom Gullen
+1  A: 

It sounds as though you have a bipartite matching problem. One partition has a vertex for each player on the roster. The other has a vertex for each roster position. There is an edge between a player vertex and a position vertex if and only if the player can play that position. You are interested in matchings: collections of edges such that no endpoint is repeated.

Given an assignment of players to positions (a matching) and a new player to be accommodated, there is a simple algorithm to determine if it can be done. Direct each edge in the current matching from the position to the player; direct the others from the player to the position. Now, using breadth-first search, look for a path from the new player to an unassigned position. If you find one, it tells you one possible series of reassignments. If you don't, there's no matching with all of the players.

For example, suppose player A can play positions 1 or 2

A--1
 \
  \
   2

We provisionally assign A to 2. Now B shows up and can only play 2. Direct the graph:

A->1
 <
  \
B->2

We find a path B->2->A->1, which means "assign B to 2, displacing A to 1".

There is lots of pretty theory for dealing with hypothetical matchings. Genetic algorithms need not apply.


EDIT: I should add that because of the use of BFS, it computes the least disruptive sequence of reassignments.

Precisely - this is the root of the problem. At first approach, this seemed much simpler than it seems to now be.
Joseph G.
Disruption is secondary to minimizing the amount of work required to make a determination. However, since least disruptive seems to logically imply that the least number of adjustments required are made first, this would seem to me the most efficient approach.
Joseph G.
I'm considering an attempt at trying to implement Hopcroft-Karp in C#. I'm fairly unfamiliar with it, so before I start getting my hands dirty, do you feel this would be an apt solution to implement a bipartite matching algorithm for this problem?
Joseph G.
Yes. I'm fond of this Python implementation: http://code.activestate.com/recipes/123641-hopcroft-karp-bipartite-matching/?in=user-218935
So the snag I've hit is that I don't yet understand where I would make a common determination between the ordered list(slots) and the unordered list (objects). Would the graph I be passing in be a list of the objects and their eligibility and then check the MIS return value against the open slots?
Joseph G.
Yes, for each object, you should prepare a list of slots to which it is eligible to be assigned, and vice versa -- this gives the input graph in adjacency-list format.
This appears to have worked. I really appreciate your guidance. I've translated the Python into C# (and C++ first, incidentally), and have refactored a lot of lengthier syntactic inefficiencies of Python. I will post it when it's all finished so if anyone else runs into a similar situation, there will be a C interpretation on-hand. Thanks again.
Joseph G.