Once we've added the model constraints, we call optimize and
then output the optimal solution:
# Compute optimal solution
m.optimize()
# Print solution
if m.Status == GRB.OPTIMAL:
solution = m.getAttr('X', flow)
for h in commodities:
print('\nOptimal flows for %s:' % h)
for i, j in arcs:
if solution[h, i, j] > 0:
print('%s -> %s: %g' % (i, j, solution[h, i, j]))
If you run the example gurobi.sh netflow.py, you should see the following output:
Gurobi Optimizer version 10.0.2 build v10.0.2rc0 (linux64)
CPU model: AMD EPYC 7282 16-Core Processor, instruction set [SSE2|AVX|AVX2]
Thread count: 4 physical cores, 4 logical processors, using up to 4 threads
Optimize a model with 16 rows, 12 columns and 36 nonzeros
Model fingerprint: 0xc43e5943
Coefficient statistics:
Matrix range [1e+00, 1e+00]
Objective range [1e+01, 8e+01]
Bounds range [0e+00, 0e+00]
RHS range [1e+01, 1e+02]
Presolve removed 16 rows and 12 columns
Presolve time: 0.00s
Presolve: All rows and columns removed
Iteration Objective Primal Inf. Dual Inf. Time
0 5.5000000e+03 0.000000e+00 2.000000e+01 0s
Extra simplex iterations after uncrush: 1
1 5.5000000e+03 0.000000e+00 0.000000e+00 0s
Solved in 1 iterations and 0.00 seconds (0.00 work units)
Optimal objective 5.500000000e+03
Optimal flows for Pencils:
Detroit -> Boston: 50
Denver -> New York: 50
Denver -> Seattle: 10
Optimal flows for Pens:
Detroit -> Boston: 30
Detroit -> New York: 30
Denver -> Boston: 10
Denver -> Seattle: 30