Ограничение по времени для смешанного целочисленного программирования с Python PuLP
Я использую PuLP для решения конкретной интересной целочисленной линейной программы (MIP), которая меня интересует. Однако, поскольку размер проблемы растет, PuLP занимает слишком много времени. Я хочу иметь возможность запустить солвер в течение некоторого времени и преждевременно прекратить его, если он займет много времени и получит наилучшее из возможных на сегодняшний день решение. Я попытался вручную синхронизировать решатель с сигналом, но все переменные "Нет".
Я просмотрел документацию, и PuLP, похоже, не поддерживает это, хотя, насколько я понимаю, большинство решающих процедур, которые он вызывает, делают. Есть ли способ наложить ограничение по времени для PuLP?
3 ответа
Вместо того, чтобы напрямую вызывать solve(), вы можете сами вызывать шаги, выполняемые в solve (). Вот пример использования 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)
После buildSolverModel () solver.solverModel содержит экземпляр API решателя. Затем вы можете использовать все функции из документации решателя. Я использовал cplex, но в gurobi можно использовать тот же подход, что и в http://www.gurobi.com/documentation/7.5/refman/python_parameter_examples.html
Если вы используете CBC MILP Solver с Pulp , вы можете установить предел времени оптимизации, используя
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))
В целлюлозу можно вызвать другие внешние решатели, такие как cplex и gurobi. Обычно вы можете установить ограничение по времени и оптимальный промежуток в их параметрах при вызове решателей. Взять хотя бы гуроби:
prob = LpProblem("anything", LpMinimize)
prob.solve(GUROBI(timeLimit=1200))
Вы можете найти конкретные параметры из исходного кода целлюлозы. https://github.com/coin-or/pulp/blob/master/src/pulp/solvers.py
Например, если вы используете gurobi, посмотрите параметры init
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)