Python PuLP的混合整数规划求解时间限制

8
我一直在使用PuLP解决一个特定的混合整数线性规划(MIP)问题,但随着问题规模的增长,PuLP所需时间太长。我希望能够运行求解器一段时间,并在计算时间过长时提前终止并获得到目前为止计算出的最佳可行解。我尝试使用信号手动计时求解器,但变量全部为“None”。
我查看了文档,发现PuLP似乎不支持这种操作,尽管我理解它调用的大多数求解器例程都支持。有没有一种方法可以为PuLP设置时间限制?

它是受支持的,使用取决于所使用的求解器。请仔细查看文档 - sascha
4个回答

4

你可以通过手动调用 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#PythonParameterExamples


2
这里是设置CBC求解器最大秒数(超时)的代码。 - Prakash M

3
如果您正在使用CBC MILP SolverPulp,您可以使用以下方法设置优化时间限制。
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))

1
在pulp中,你可以调用其他外部求解器,例如cplex和gurobi。通常在调用求解器时,你可以设置时间限制和最优差距在它们的参数中。以gurobi为例: prob = LpProblem("anything", LpMinimize) prob.solve(GUROBI(timeLimit=1200)) 你可以从pulp的源代码中找到具体的参数。https://github.com/coin-or/pulp/blob/master/src/pulp/solvers.py 例如,如果你正在使用gurobi,请查看初始化参数。
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)

0
使用PuLP的默认求解器,您还可以添加参数threads来提高速度,以及timeLimit
time_limit = 900
status = model.solve(PULP_CBC_CMD(msg=0, timeLimit=time_limit, threads=1))

P.S.

这里是关于scipy的带线性约束的自然语言处理的建议:

由于所有约束都是线性的,我们可以通过一个仿射线性函数Ax-b来表示它们,使得我们有不等式Ax >= b。 相反,我们可以直接通过以下方式传递所有约束:

cons = [{"type": "ineq", "fun": lambda x: A @ x - b}]

我认为,@或者说,相同的,np.matmul()也可以增加速度,返回乘积矩阵,而不是为每个变量进行顺序/并行优化。对于两个一维向量,您可以使用np.dot() 得到相同的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接