简体   繁体   English

如何使用 PuLP 的 Gurobi 求解器设置 MIP 启动(初始解决方案)?

[英]How to set MIP start (initial solution) with Gurobi solver from PuLP?

I'm using the PuLP module in Python to formulate a mixed integer program.我在 Python 中使用PuLP模块来制定混合整数程序。 I am trying to work out how to set a MIP start (ie a feasible solution for the program to start from) via the PuLP interface.我正在尝试解决如何通过PuLP界面设置MIP start (即程序启动的可行解决方案)。

Details on how to set MIP start are given here 此处提供有关如何设置MIP start详细信息

And the developer of the PuLP package claims that you can access the full Gurobi model via the PuLP interface here而且PuLP包的开发者声称您可以通过此处PuLP接口访问完整的 Gurobi 模型

Pasted below are two complete models.下面粘贴的是两个完整的模型。 I have made these as small as possible whilst preventing the gurobi solver from finding the optimal value using a heuristic.我已经使这些尽可能小,同时防止 gurobi 求解器使用启发式方法找到最佳值。

I have attempted to set an initial solution (to the optimal values) in both models, but in the PuLP model it is ignored, but in the gurobipy model it works as expected.我试图在两个模型中设置一个初始解决方案(为最佳值),但在PuLP模型中它被忽略,但在gurobipy模型中它按预期工作。

How do you set an initial solution for the Gurobi solve via the PuLP interface?如何通过 PuLP 接口为 Gurobi 求解设置初始解?

from pulp import *

prob = LpProblem("min example",LpMinimize)

x1=LpVariable("x1",0,None,LpInteger)
x2=LpVariable("x2",0,None,LpInteger)
x3=LpVariable("x3",0,None,LpInteger)
x4=LpVariable("x4",0,None,LpInteger)

# Objective function
prob += 3*x1 + 5*x2 + 6*x3 + 9*x4

# A constraint
prob += -2*x1 + 6*x2 -3*x3 + 4*x4 >= 2, "Con1"
prob += -5*x1 + 3*x2 + x3 + 3*x4 >= -2, "Con2"
prob += 5*x1 - x2 + 4*x3 - 2*x4 >= 3, "Con3"

# Choose solver, and set it to problem, and build the Gurobi model
solver = pulp.GUROBI()
prob.setSolver(solver)
prob.solver.buildSolverModel(prob)

# Attempt to set an initial feasible solution (in this case to an optimal solution)
prob.solverModel.getVars()[0].start = 1
prob.solverModel.getVars()[1].start = 1
prob.solverModel.getVars()[2].start = 0
prob.solverModel.getVars()[3].start = 0

# Solve model
prob.solve()

# Status of the solution is printed to the screen
print "Status:", LpStatus[prob.status]

# Each of the variables is printed with it's resolved optimum value
for v in prob.variables():
    print v.name, "=", v.varValue

# Optimised objective function value is printed to the screen
print "OF = ", value(prob.objective)

Which returns:返回:

Optimize a model with 3 rows, 4 columns and 12 nonzeros
Coefficient statistics:
  Matrix range    [1e+00, 6e+00]
  Objective range [3e+00, 9e+00]
  Bounds range    [0e+00, 0e+00]
  RHS range       [2e+00, 3e+00]
Found heuristic solution: objective 12
Presolve removed 0 rows and 1 columns
Presolve time: 0.00s
Presolved: 3 rows, 3 columns, 9 nonzeros
Variable types: 0 continuous, 3 integer (0 binary)

Root relaxation: objective 7.400000e+00, 1 iterations, 0.00 seconds

    Nodes    |    Current Node    |     Objective Bounds      |     Work
 Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time

     0     0    7.40000    0    1   12.00000    7.40000  38.3%     -    0s
H    0     0                       8.0000000    7.40000  7.50%     -    0s

Explored 0 nodes (1 simplex iterations) in 0.00 seconds
Thread count was 8 (of 8 available processors)

Optimal solution found (tolerance 1.00e-04)
Best objective 8.000000000000e+00, best bound 8.000000000000e+00, gap 0.0%
('Gurobi status=', 2)
Status: Optimal
x1 = 1.0
x2 = 1.0
x3 = -0.0
x4 = -0.0
OF =  8.0

Secondly I can implement the same model using the gurobipy module, but in this case the MIP start is actually used:其次,我可以使用gurobipy模块实现相同的模型,但在这种情况下,实际使用的是 MIP 启动:

from gurobipy import *

m = Model("min example")
m.modelSense = GRB.MINIMIZE

objFcnCoeffs = [3, 5, 6, 9]
xVars = []
for i in range(4):
    xVars.append(m.addVar(vtype=GRB.INTEGER, obj=objFcnCoeffs[i], name="Open%d" % i))

# Update model to integrate new variables
m.update()

# Constraints
m.addConstr(-2*xVars[0] + 6*xVars[1] -3*xVars[2] + 4*xVars[3] >= 2, "Con1")
m.addConstr(-5*xVars[0] + 3*xVars[1] + xVars[2] + 3*xVars[3] >= -2, "Con2")
m.addConstr(5*xVars[0] - xVars[1] + 4*xVars[2] - 2*xVars[3] >= 3, "Con3")


# Attempt to set an initial feasible solution (in this case to an optimal solution)
startValues = [1, 1, 0, 0]
for i in range(4):
    xVars[i].start = startValues[i]

# Solve model
m.optimize()

# Print solution
print('\nTOTAL COSTS: %g' % m.objVal)
for i in range(4):
    print('\n xVar[%s] = %g' % i, xVars[i])

Which returns:返回:

Optimize a model with 3 rows, 4 columns and 12 nonzeros
Coefficient statistics:
  Matrix range    [1e+00, 6e+00]
  Objective range [3e+00, 9e+00]
  Bounds range    [0e+00, 0e+00]
  RHS range       [2e+00, 3e+00]
Found heuristic solution: objective 12
Presolve removed 0 rows and 1 columns
Presolve time: 0.00s
Presolved: 3 rows, 3 columns, 9 nonzeros

Loaded MIP start with objective 8

Variable types: 0 continuous, 3 integer (0 binary)

Root relaxation: infeasible, 0 iterations, 0.00 seconds

Explored 0 nodes (0 simplex iterations) in 0.00 seconds
Thread count was 8 (of 8 available processors)

Optimal solution found (tolerance 1.00e-04)
Best objective 8.000000000000e+00, best bound 8.000000000000e+00, gap 0.0%

TOTAL COSTS: 8

 xVar[0] = 1

 xVar[1] = 1

 xVar[2] = 0

 xVar[3] = 0

You are setting the start values like this您正在设置这样的起始值

prob.solverModel.getVars()[0].start = 1

and you are then solving the model with this call然后你用这个调用来解决模型

prob.solve().

The oritinal prob is not changed, if you call最初的prob不会改变,如果你打电话

prob.solver.callSolver(prob)

Gurobi will use the start vector. Gurobi 将使用起始向量。

Very late to the question but hopefully this will help new visitors.这个问题很晚了,但希望这会对新访客有所帮助。 Starting in version 2.3 of PuLP, the common warmStart interface supports the GUROBI api.从 PuLP 2.3 版本开始,通用的warmStart 接口支持GUROBI api。 By following the instructions here you should be able to warm start the gurobi solver without having to tinker with the pulp internals or the gurobi package.按照此处的说明您应该能够热启动 gurobi 求解器,而无需修补纸浆内部或 gurobi 包。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM