Assignment problem

Machineco has four machines and four jobs to be completed. Each machine must be assigned to complete one job. The time required to set up each machine for completing each job is shown in Table 43. Machineco wants to minimize the total setup time needed to complete the four jobs. Use linear programming to solve this problem.

Job1 Job2 Job3 Job4
Machine 1 14 5 8 7
Machine 2 2 12 6 5
Machine 3 7 8 3 9
Machine 4 2 4 6 10

In [10]:
from gurobipy import *

m = Model("Assignment Prolem")

NUMBER_OF_MACHINES = 4
NUMBER_OF_JOBS = 4


cost_matrix = [
    [14,5,8,7],[2,12,6,5], [7,8,3,9], [2,4,6,10]
]


variables = [ 
    [m.addVar(vtype=GRB.BINARY, 
              obj = cost_matrix[machine][job], 
              name="(Machine - %d , Job %d)" % (machine+1, job+1))
     for job in range(NUMBER_OF_JOBS) ] 
        for machine in range(NUMBER_OF_MACHINES)
    ]

In [11]:
variables


Out[11]:
[[<gurobi.Var *Awaiting Model Update*>,
  <gurobi.Var *Awaiting Model Update*>,
  <gurobi.Var *Awaiting Model Update*>,
  <gurobi.Var *Awaiting Model Update*>],
 [<gurobi.Var *Awaiting Model Update*>,
  <gurobi.Var *Awaiting Model Update*>,
  <gurobi.Var *Awaiting Model Update*>,
  <gurobi.Var *Awaiting Model Update*>],
 [<gurobi.Var *Awaiting Model Update*>,
  <gurobi.Var *Awaiting Model Update*>,
  <gurobi.Var *Awaiting Model Update*>,
  <gurobi.Var *Awaiting Model Update*>],
 [<gurobi.Var *Awaiting Model Update*>,
  <gurobi.Var *Awaiting Model Update*>,
  <gurobi.Var *Awaiting Model Update*>,
  <gurobi.Var *Awaiting Model Update*>]]

In [12]:
m.modelSense = GRB.MINIMIZE
m.update()

In [13]:
m.getObjective()


Out[13]:
<gurobi.LinExpr: 14.0 (Machine - 1 , Job 1) + 5.0 (Machine - 1 , Job 2) + 8.0 (Machine - 1 , Job 3) + 7.0 (Machine - 1 , Job 4) + 2.0 (Machine - 2 , Job 1) + 12.0 (Machine - 2 , Job 2) + 6.0 (Machine - 2 , Job 3) + 5.0 (Machine - 2 , Job 4) + 7.0 (Machine - 3 , Job 1) + 8.0 (Machine - 3 , Job 2) + 3.0 (Machine - 3 , Job 3) + 9.0 (Machine - 3 , Job 4) + 2.0 (Machine - 4 , Job 1) + 4.0 (Machine - 4 , Job 2) + 6.0 (Machine - 4 , Job 3) + 10.0 (Machine - 4 , Job 4)>

In [14]:
for machine in range(NUMBER_OF_MACHINES):
    m.addConstr(
        quicksum(variables[machine][job] for job in range(NUMBER_OF_JOBS)) == 1, 
        "Job requirment for machine %d" % (machine + 1))

In [15]:
for job in range(NUMBER_OF_JOBS):
    m.addConstr(
        quicksum(variables[machine][job] for machine in range(NUMBER_OF_MACHINES)) == 1, 
        "Machine requirment for machine %d" % (job + 1))

In [16]:
m.optimize()

for v in m.getVars():
    print (v.varName, v.x)
    

print (m.getObjective().getValue())


Optimize a model with 8 rows, 16 columns and 32 nonzeros
Variable types: 0 continuous, 16 integer (16 binary)
Coefficient statistics:
  Matrix range     [1e+00, 1e+00]
  Objective range  [2e+00, 1e+01]
  Bounds range     [1e+00, 1e+00]
  RHS range        [1e+00, 1e+00]
Found heuristic solution: objective 23
Presolve time: 0.05s
Presolved: 8 rows, 16 columns, 32 nonzeros
Variable types: 0 continuous, 16 integer (16 binary)

Root relaxation: objective 1.500000e+01, 6 iterations, 0.02 seconds

    Nodes    |    Current Node    |     Objective Bounds      |     Work
 Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time

*    0     0               0      15.0000000   15.00000  0.00%     -    0s

Explored 0 nodes (6 simplex iterations) in 0.20 seconds
Thread count was 8 (of 8 available processors)

Solution count 2: 15 23 
Pool objective bound 15

Optimal solution found (tolerance 1.00e-04)
Best objective 1.500000000000e+01, best bound 1.500000000000e+01, gap 0.0000%
(Machine - 1 , Job 1) -0.0
(Machine - 1 , Job 2) 1.0
(Machine - 1 , Job 3) -0.0
(Machine - 1 , Job 4) 0.0
(Machine - 2 , Job 1) 0.0
(Machine - 2 , Job 2) -0.0
(Machine - 2 , Job 3) -0.0
(Machine - 2 , Job 4) 1.0
(Machine - 3 , Job 1) -0.0
(Machine - 3 , Job 2) -0.0
(Machine - 3 , Job 3) 1.0
(Machine - 3 , Job 4) -0.0
(Machine - 4 , Job 1) 1.0
(Machine - 4 , Job 2) -0.0
(Machine - 4 , Job 3) -0.0
(Machine - 4 , Job 4) -0.0
15.0