Assignment Problem¶
Assignment Problems can be solved with numpy, and many other python libraries.
One of the simplest ways to solve an Assignment Problem is with Python and Google OR-Tools:
http://developers.google.com/optimization/assignment/simple_assignment
Here is a walk-through of the small example problem at the OR-Tools page. A much larger problem is solved afterward.¶
(OR-Tools needs to be installed with pip; see the Installation tab)
In [1]:
from ortools.graph import pywrapgraph
In [2]:
def create_data_array():
cost = [[90, 76, 75, 70],
[35, 85, 55, 65],
[125, 95, 90, 105],
[45, 110, 95, 115]]
return cost
In [3]:
cost = create_data_array()
rows = len(cost)
cols = len(cost[0])
In [4]:
assignment = pywrapgraph.LinearSumAssignment()
for worker in range(rows):
for task in range(cols):
if cost[worker][task]:
assignment.AddArcWithCost(worker, task, cost[worker][task])
In [5]:
%%time
solve_status = assignment.Solve()
In [6]:
if solve_status == assignment.OPTIMAL:
print('Total cost = ', assignment.OptimalCost())
print()
for i in range(0, assignment.NumNodes()):
print('Worker %d assigned to task %d. Cost = %d' % (
i,
assignment.RightMate(i),
assignment.AssignmentCost(i)))
elif solve_status == assignment.INFEASIBLE:
print('No assignment is possible.')
elif solve_status == assignment.POSSIBLE_OVERFLOW:
print('Some input costs are too large and may cause an integer overflow.')
The key Solve step runs very quickly. This is not surprising since there are only 4! different assignments to be scored.
Let's try a much larger problem!¶
What happens if N=100? Below, A random 100x100 cost matrix is created in the function create_data_array2.
In [7]:
import random
def create_data_array2():
randomcost = []
for i in range(0,100):
randomrow = []
for j in range(0,100):
n = random.randint(0,10000)
randomrow.append(n)
randomcost.append(randomrow)
return randomcost
In [8]:
cost = create_data_array2()
rows = len(cost)
cols = len(cost[0])
In [9]:
assignment = pywrapgraph.LinearSumAssignment()
for worker in range(rows):
for task in range(cols):
if cost[worker][task]:
assignment.AddArcWithCost(worker, task, cost[worker][task])
In [10]:
%%time
solve_status = assignment.Solve()
In [11]:
if solve_status == assignment.OPTIMAL:
print('Total cost = ', assignment.OptimalCost())
print()
for i in range(0, assignment.NumNodes()):
print('Worker %d assigned to task %d. Cost = %d' % (
i,
assignment.RightMate(i),
assignment.AssignmentCost(i)))
elif solve_status == assignment.INFEASIBLE:
print('No assignment is possible.')
elif solve_status == assignment.POSSIBLE_OVERFLOW:
print('Some input costs are too large and may cause an integer overflow.')