I'm trying to find an efficient solution for the following problem:
Problem: Assume I have some tasks (A,A,B,B,C) and I have some people who can perform one or more of these tasks:
Is it possible to give away all of my tasks to these persons? One person can only do one task.
There could be multiple solutions but I'm only interested in knowing if there is a solution.
My first attempt at solving this efficiently was:
This is good enough for solving the above problem.
But it isn't enough to solve more complex problems like: jobs: IGGGFFDDCCBBB persons: ABCDEFG CEI BEI CEFGI CEGI ADGI CEGI CI ADG BEI DI BCDEFI ABDF ABEFG BCEGI ACDI BD ABE BCDEFGI
Is there an efficient way of solving this problem? I can obviously solve this with a depth-first search algorithm but I'm wondering if I can solve this problem in polynomial time? I can't help but believe this is a well-known problem, but I have been unable to find it on google.
Thank you for reading :)
One way to efficiently solve this is to formulate it as a maximum flow problem.
Add edges between people and the tasks they can do (capacity 1).
Also add edges between a start and each person (capacity 1)
And an edge between a task and the destination (capacity = number of times that task needs to be done).
Example Python code using NetworkX:
import networkx as nx
from collections import Counter
jobs = 'IGGGFFDDCCBBB'
people = 'ABCDEFG CEI BEI CEFGI CEGI ADGI CEGI CI ADG BEI DI BCDEFI ABDF ABEFG BCEGI ACDI BD ABE BCDEFGI'
G=nx.DiGraph()
for person,tasks in enumerate(people.split()):
P = 'person'+str(person)
G.add_edge('start',P,capacity=1.0) # One person can do one thing
for task in tasks:
G.add_edge(P,'task'+task,capacity=1.0) # This person can do this task
C = Counter(jobs)
for task,count in C.items():
G.add_edge('task'+task,'end',capacity=count) # Task appears count times in our job list
print nx.max_flow(G,'start','end') >= len(jobs)