Reputation: 201
I've been using PuLP to solve a particular mixed integer linear program (MIP) I am interested in. However, as the problem size grows, PuLP is taking too long. I want to be able to run the solver for some time and terminate it prematurely if its taking to long and obtain the best feasible solution so-far computed. I have tried manually timing the solver out with signal, but the variables are all "None".
I've looked at the documentation and PuLP does not seem to support this, though as I understand it, most of the solver routines it calls do. Is there a way to impose a time limit for PuLP?
Upvotes: 10
Views: 13305
Reputation: 579
using PuLP
's default solver you can also add param threads
to increase speed, as well as timeLimit
:
time_limit = 900
status = model.solve(PULP_CBC_CMD(msg=0, timeLimit=time_limit, threads=1))
P.S.
HERE is an advice for scipy's NLP with Linear Constraints:
Since all constraints are linear, we can express them by a affin-linear function Ax-b such that we have the inequality Ax >= b. Instead, we can pass all constraints directly by:
cons = [{"type": "ineq", "fun": lambda x: A @ x - b}]
I suppose, @
or, the same, np.matmul()
also could increase speed returning the product matrix, instead of sequential/parallel optimization for each var. For 2 1-dimensional vectors you can use np.dot()
giving the same result.
Upvotes: 1
Reputation: 1629
If you are using the CBC MILP Solver with Pulp you can set the optimisation time limit using
from pulp import LpProblem, LpMinimize, PULP_CBC_CMD
prob = LpProblem("YOUR_PROBLEM_NAME", LpMinimize)
time_limit_in_seconds = 60*10
prob.solve(PULP_CBC_CMD(msg=1, maxSeconds=time_limit_in_seconds))
Upvotes: 3
Reputation: 809
Instead of directly calling solve(), you can call the steps executed in solve() yourself. Here is an example while using the cplex python api
#Create your problem
P = pulp.LpProblem()
#Build the solverModel for your preferred
solver = pulp.CPLEX_PY()
solver.buildSolverModel(P)
#Modify the solvermodel
solver.solverModel.parameters.timelimit.set(60)
#Solve P
solver.callSolver(P)
status = solver.findSolutionValues(P)
After buildSolverModel(), solver.solverModel contains an instance of the solver API. You can then use all functions from the solver documentation. I used cplex, but the same approach can be used in gurobi as seen http://www.gurobi.com/documentation/7.5/refman/python_parameter_examples.html#PythonParameterExamples
Upvotes: 4
Reputation: 11
In pulp, you can call other external solvers, such as cplex and gurobi. Typically you can set a time limit and an optimal gap in their parameters when calling the solvers. Take the gurobi for example:
prob = LpProblem("anything", LpMinimize)
prob.solve(GUROBI(timeLimit=1200))
You can find the specific params from the source code of pulp. https://github.com/coin-or/pulp/blob/master/src/pulp/solvers.py
For example, if you are using gurobi, see the init params
class GUROBI(LpSolver):
"""
The Gurobi LP/MIP solver (via its python interface)
The Gurobi variables are available (after a solve) in var.solverVar
Constriaints in constraint.solverConstraint
and the Model is in prob.solverModel
"""
try:
sys.path.append(gurobi_path)
# to import the name into the module scope
global gurobipy
import gurobipy
except: #FIXME: Bug because gurobi returns
#a gurobi exception on failed imports
def available(self):
"""True if the solver is available"""
return False
def actualSolve(self, lp, callback = None):
"""Solve a well formulated lp problem"""
raise PulpSolverError("GUROBI: Not Available")
else:
def __init__(self,
mip = True,
msg = True,
timeLimit = None,
epgap = None,
**solverParams):
"""
Initializes the Gurobi solver.
@param mip: if False the solver will solve a MIP as an LP
@param msg: displays information from the solver to stdout
@param timeLimit: sets the maximum time for solution
@param epgap: sets the integer bound gap
"""
LpSolver.__init__(self, mip, msg)
self.timeLimit = timeLimit
self.epgap = epgap
#set the output of gurobi
if not self.msg:
gurobipy.setParam("OutputFlag", 0)
#set the gurobi parameter values
for key,value in solverParams.items():
gurobipy.setParam(key, value)
Upvotes: 1