10

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?

1
  • It is supported and usage depends somewhat on the solver used. Look more carefully at the docs. Commented Dec 27, 2017 at 4:12

4 Answers 4

4

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

Sign up to request clarification or add additional context in comments.

1 Comment

here is the code to set max seconds (time out) for CBC solver
4

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, timeLimit=time_limit_in_seconds))

Comments

1

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)

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.