Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Time limit for mixed integer programming with Python PuLP

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?

like image 508
eepperly16 Avatar asked Dec 27 '17 01:12

eepperly16


People also ask

What solver does PuLP use?

In PuLP, the default solver is CBC, but it can work with other solvers as well.

What is PuLP in Python?

PuLP is a python library which can be used to solve linear programming problems. Linear Programming is used to solve optimization problems and has uses in various industries such as Manufacturing, Transportation, Food Diets etc.

What is MIP in operations research?

A mixed-integer programming (MIP) problem is one where some of the decision variables are constrained to be integer values (i.e. whole numbers such as -1, 0, 1, 2, etc.) at the optimal solution. The use of integer variables greatly expands the scope of useful optimization problems that you can define and solve.

What is LpProblem?

Bases: pulp.pulp.LpProblem. Contains the subproblem generated by converting a fixed constraint. into an elastic constraint. Parameters: constraint – The LpConstraint that the elastic constraint is based on.


2 Answers

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

like image 198
user3053216 Avatar answered Oct 12 '22 16:10

user3053216


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)
like image 30
Yaning Li Avatar answered Oct 12 '22 15:10

Yaning Li