Introduction to
the use of solvers Integer linear programming:
formulations, techniques and
with python applications.
14
Santiago Valdés Ravelo
[email protected] October,
2020
“First, solve the problem. Then, write the code.”
Attributed to John Johnson.
1 Introduction
2 PuLP
Coding formulations
Solving formulations
3 DipPy
Introduction
Introduction
Commercial solvers
Introduction
Non-commercial solvers
Introduction
Why python?
▶ Very intuitive and easy-to-program language.
▶ Growing community and popularity:
▶ 3𝑟𝑑 in TIOBE index .
▶ 2𝑛𝑑 in GitHub .
▶ Common interfaces for different solvers (e.g., PuLP/DipPy):
▶ Simplifies the formulations coding.
▶ Facilitates to embed solvers calls in algorithm solutions (e.g.,
matheuristics) or in software applications.
PuLP
PuLP
Description
PuLP is a linear programming modeler written in Python and able
to integrate with different solvers.
The main classes for coding formulations are LpProblem,
LpVariable, LpConstraint and LpConstraintVar.
The solvers interfaces are given by the classes LpSolver and
LpSolver_CMD.
Access documentation here
PuLP
Coding formulations
Import PuLP classes and functions: from pulp import *
Define the variables:
▶ myVariable = LpVariable(name, lowBound = None, upBound = None, cat =
’Continuous’, e = None)
▶ myVariables = LpVariable.dicts(name, indexs, lowBound = None, upBound =
None, cat = 0)
Define the problem:
▶ myProblem = LpProblem(”name”, LpMinimize)
▶ myProblem = LpProblem(”name”, LpMaximize)
Define the objective function: myProblem += expression, name
Define the constraints:
▶ myProblem += expression <= value
▶ myProblem += expression == value
▶ myProblem += expression >= value
PuLP
Coding formulations. Simple example
Consider the following problem:
max 3×𝑥+2×𝑦
𝑠.𝑡. ∶
𝑥−𝑦+𝑧 =1
𝑥 + 2 × 𝑦 ≤ 14
4 × 𝑥 + 𝑦 ≤ 20
𝑥, 𝑦 ∈ ℤ+ , 𝑧 ∈ ℝ+
PuLP
Coding formulations. Simple example
1 from pulp import *
2
3 x = LpVariable("x", lowBound = 0, cat = 'Integer')
max 3×𝑥+2×𝑦 4 y = LpVariable("y", lowBound = 0, cat = 'Integer')
5 z = LpVariable("z", lowBound = 0)
𝑠.𝑡. ∶ 6
𝑥−𝑦+𝑧=1 7 problem = LpProblem("myProblem", LpMaximize)
8
𝑥 + 2 × 𝑦 ≤ 14 9 problem += 3 * x + 2 * y, "myObjective"
4 × 𝑥 + 𝑦 ≤ 20 10
𝑥, 𝑦 ∈ ℤ+ , 𝑧 ∈ ℝ+
11 problem += x - y + z == 1
12 problem += x + 2 * y <= 14
13 problem += 4 * x + y <= 20
PuLP
Coding formulations. Knapsack
Instance: 𝑂, 𝜈 ∶ 𝑂 → ℝ+ , 𝜔 ∶ 𝑂 → ℝ+ , 𝑊 ∈ ℝ+ .
max ∑ 𝜈(𝑜) × 𝑥𝑜
𝑜∈𝑂
𝑠.𝑡. ∶
∑ 𝜔(𝑜) × 𝑥𝑜 ≤ 𝑊
𝑜∈𝑂
𝑥𝑜 ∈ {0, 1} , ∀𝑜 ∈ 𝑂
PuLP
Coding formulations. Knapsack
1 from pulp import *
2
3 def knapsack(values, weights, W):
4 x = LpVariable.dicts("x", [o for o in range(len(values))], lowBound = 0, upBound = 1,
↪ cat='Integer')
5
6 problem = LpProblem("BinaryKnapsack", LpMaximize)
7
8 problem += lpSum(values[o] * x[o] for o in range(len(values))), "profit"
9
10 problem += lpSum(weights[o] * x[o] for o in range(len(values))) <= W
PuLP
Coding formulations. Multiple knapsack
Instance: 𝑂, 𝜈 ∶ 𝑂 → ℝ+ , 𝜔 ∶ 𝑂 → ℝ+ , 𝑊 ∈ ℝ𝑚
+.
𝑚
max ∑ ∑ 𝜈(𝑜) × 𝑥𝑜𝑖
𝑜∈𝑂 𝑖=1
𝑠.𝑡. ∶
∑ 𝜔(𝑜) × 𝑥𝑜𝑖 ≤ 𝑊𝑖 ∀1 ≤ 𝑖 ≤ 𝑚
𝑜∈𝑂
𝑚
∑ 𝑥𝑜𝑖 ≤ 1 ∀𝑜 ∈ 𝑂
𝑖=1
𝑥𝑜𝑖 ∈ {0, 1} ∀𝑜 ∈ 𝑂, 1 ≤ 𝑖 ≤ 𝑚
PuLP
Coding formulations. Multiple knapsack
1 from pulp import *
2
3 def multipleKnapsack(values, weights, W):
4 x = LpVariable.dicts("x", [(o, i) for o in range(len(values)) for i in range(len(W))],
↪ lowBound = 0, upBound = 1, cat='Integer')
5
6 problem = LpProblem("MultipleKnapsack", LpMaximize)
7
8 problem += lpSum(values[o] * x[o, i] for o in range(len(values)) for i in range(len(W))),
↪ "profit"
9
10 for i in range(len(W)):
11 problem += lpSum(weights[o] * x[o, i] for o in range(len(values))) <= W[i]
12
13 for o in range(len(W)):
14 problem += lpSum(x[o, i] for i in range(len(W))) <= 1
PuLP
Solving formulations
The function list_solvers() returns the available solvers:
▶ e.g., [’GLPK_CMD’, ’PYGLPK’, ’CPLEX_CMD’, ’CPLEX_PY’, ’GUROBI’,
’GUROBI_CMD’, ’XPRESS’, ’COIN_CMD’, ’SCIP_CMD’]
Get the solver:
▶ e.g., solver = GUROBI(parameters).
▶ Some of the parameters may include: timeLimit in seconds, Cuts, Heuristics and
Presolve to indicate if there will be used, respectively, standard cut generation,
embedded heuristics and preprocessing.
Solve the problem:
▶ myProblem.solve(solver)
▶ solver.buildSolverModel(myProblem), solver.callSolver(myProblem) and
solver.findSolutionValues(myProblem)
Get solution value: value(myProblem.objective).
The variables are elements in myProblem.variables() each one with attributes name
and varValue.
PuLP
Solving formulations. Simple example
1 from pulp import *
2
3 x = LpVariable("x", lowBound = 0, cat = 'Integer')
4 y = LpVariable("y", lowBound = 0, cat = 'Integer')
5 z = LpVariable("z", lowBound = 0)
6
7 problem = LpProblem("myProblem", LpMaximize)
8
9 problem += 3 * x + 2 * y, "myObjective"
10
11 problem += x - y + z == 1
12 problem += x + 2 * y <= 14
13 problem += 4 * x + y <= 20
14
15 problem.solve(GUROBI_CMD())
16
17 print('Optimal value: ' + str(value(problem.objective)))
18 print('Optimal solution: ')
19 for variable in problem.variables():
20 print(' ' + variable.name + " = " + str(variable.varValue))
PuLP
Solving formulations. Knapsack
1 from pulp import *
2
3 def knapsack(values, weights, W):
4 x = LpVariable.dicts("x", [o for o in range(len(values))], lowBound = 0, upBound = 1,
↪ cat='Integer')
5
6 problem = LpProblem("BinaryKnapsack", LpMaximize)
7
8 problem += lpSum(values[o] * x[o] for o in range(len(values))), "profit"
9
10 problem += lpSum(weights[o] * x[o] for o in range(len(values))) <= W
11
12 solver = GUROBI(timeLimit = 3600)
13
14 solver.buildSolverModel(problem)
15 solver.callSolver(problem)
16 solver.findSolutionValues(problem)
17
18 print('Optimal value: ' + str(value(problem.objective)))
19 print('Optimal solution: ')
20 for variable in problem.variables():
21 print(' ' + variable.name + " = " + str(variable.varValue))
DipPy
DipPy
PuLP extension
▶ Advanced branching. Includes branch_method.
▶ Customized cuts. Includes generate_cuts and
is_solution_feasible.
▶ Customized columns. Includes relaxed_solver and init_vars.
▶ Heuristics. Includes heuristics.
* Michael O’Sullivan, Qi-Shan Lim, Cameron Walker and Iain Dunning “Dippy – a simplified interface for advanced
mixed integer programming”. (2012).
Introduction to
the use of solvers Integer linear programming:
formulations, techniques and
with python applications.
14
Santiago Valdés Ravelo
[email protected] October,
2020