Aquí es un pequeño código que se muestra cómo utilizar un inicio en caliente con el Xpress optimizador.
Tenga en cuenta que no soy un experto en Pyomo, por lo que hay mejores formas de implementar el create_model
la función, pero para el uso de warmstarts usted debe centrarse en el resto del código de todos modos.
import pyomo.environ as pyo
from pyomo.environ import value
from pyomo.opt import SolverFactory
def create_model():
"""Create a model that is non-trivial to solve.
The returned model has two variables: `x` and `s`. It also has an
objective function that is stored in `obj`.
"""
model = pyo.ConcreteModel()
model.X = pyo.RangeSet(50)
model.S = pyo.RangeSet(6)
model.x = pyo.Var(model.X, within=pyo.Binary)
x = model.x
model.s = pyo.Var(model.S, bounds = (0, None))
s = model.s
model.obj = pyo.Objective(expr=s[1] + s[2] + s[3] + s[4] + s[5] + s[6])
model.cons = pyo.ConstraintList()
model.cons.add(s[1] + 25*x[1] + 35*x[2] + 14*x[3] + 76*x[4] + 58*x[5] + 10*x[6] + 20*x[7]
+ 51*x[8] + 58*x[9] + x[10] + 35*x[11] + 40*x[12] + 65*x[13] + 59*x[14] + 24*x[15]
+ 44*x[16] + x[17] + 93*x[18] + 24*x[19] + 68*x[20] + 38*x[21] + 64*x[22] + 93*x[23]
+ 14*x[24] + 83*x[25] + 6*x[26] + 58*x[27] + 14*x[28] + 71*x[29] + 17*x[30]
+ 18*x[31] + 8*x[32] + 57*x[33] + 48*x[34] + 35*x[35] + 13*x[36] + 47*x[37]
+ 46*x[38] + 8*x[39] + 82*x[40] + 51*x[41] + 49*x[42] + 85*x[43] + 66*x[44]
+ 45*x[45] + 99*x[46] + 21*x[47] + 75*x[48] + 78*x[49] + 43*x[50] == 1116)
model.cons.add(s[2] + 97*x[1] + 64*x[2] + 24*x[3] + 63*x[4] + 58*x[5] + 45*x[6] + 20*x[7]
+ 71*x[8] + 32*x[9] + 7*x[10] + 28*x[11] + 77*x[12] + 95*x[13] + 96*x[14]
+ 70*x[15] + 22*x[16] + 93*x[17] + 32*x[18] + 17*x[19] + 56*x[20] + 74*x[21]
+ 62*x[22] + 94*x[23] + 9*x[24] + 92*x[25] + 90*x[26] + 40*x[27] + 45*x[28]
+ 84*x[29] + 62*x[30] + 62*x[31] + 34*x[32] + 21*x[33] + 2*x[34] + 75*x[35]
+ 42*x[36] + 75*x[37] + 29*x[38] + 4*x[39] + 64*x[40] + 80*x[41] + 17*x[42]
+ 55*x[43] + 73*x[44] + 23*x[45] + 13*x[46] + 91*x[47] + 70*x[48] + 73*x[49]
+ 28*x[50] == 1325)
model.cons.add(s[3] + 95*x[1] + 71*x[2] + 19*x[3] + 15*x[4] + 66*x[5] + 76*x[6] + 4*x[7]
+ 50*x[8] + 50*x[9] + 97*x[10] + 83*x[11] + 14*x[12] + 27*x[13] + 14*x[14]
+ 34*x[15] + 9*x[16] + 99*x[17] + 62*x[18] + 92*x[19] + 39*x[20] + 56*x[21]
+ 53*x[22] + 91*x[23] + 81*x[24] + 46*x[25] + 94*x[26] + 76*x[27] + 53*x[28]
+ 58*x[29] + 23*x[30] + 15*x[31] + 63*x[32] + 2*x[33] + 31*x[34] + 55*x[35]
+ 71*x[36] + 97*x[37] + 71*x[38] + 55*x[39] + 8*x[40] + 57*x[41] + 14*x[42]
+ 76*x[43] + x[44] + 46*x[45] + 87*x[46] + 22*x[47] + 97*x[48] + 99*x[49] + 92*x[50]
== 1353)
model.cons.add(s[4] + x[1] + 27*x[2] + 46*x[3] + 48*x[4] + 66*x[5] + 58*x[6] + 52*x[7] + 6*x[8]
+ 14*x[9] + 26*x[10] + 55*x[11] + 61*x[12] + 60*x[13] + 3*x[14] + 33*x[15]
+ 99*x[16] + 36*x[17] + 55*x[18] + 70*x[19] + 73*x[20] + 70*x[21] + 38*x[22]
+ 66*x[23] + 39*x[24] + 43*x[25] + 63*x[26] + 88*x[27] + 47*x[28] + 18*x[29]
+ 73*x[30] + 40*x[31] + 91*x[32] + 96*x[33] + 49*x[34] + 13*x[35] + 27*x[36]
+ 22*x[37] + 71*x[38] + 99*x[39] + 66*x[40] + 57*x[41] + x[42] + 54*x[43] + 35*x[44]
+ 52*x[45] + 66*x[46] + 26*x[47] + x[48] + 26*x[49] + 12*x[50] == 1169)
model.cons.add(s[5] + 3*x[1] + 94*x[2] + 51*x[3] + 4*x[4] + 25*x[5] + 46*x[6] + 30*x[7]
+ 2*x[8] + 89*x[9] + 65*x[10] + 28*x[11] + 46*x[12] + 36*x[13] + 53*x[14]
+ 30*x[15] + 73*x[16] + 37*x[17] + 60*x[18] + 21*x[19] + 41*x[20] + 2*x[21]
+ 21*x[22] + 93*x[23] + 82*x[24] + 16*x[25] + 97*x[26] + 75*x[27] + 50*x[28]
+ 13*x[29] + 43*x[30] + 45*x[31] + 64*x[32] + 78*x[33] + 78*x[34] + 6*x[35]
+ 35*x[36] + 72*x[37] + 31*x[38] + 28*x[39] + 56*x[40] + 60*x[41] + 23*x[42]
+ 70*x[43] + 46*x[44] + 88*x[45] + 20*x[46] + 69*x[47] + 13*x[48] + 40*x[49]
+ 73*x[50] == 1160)
model.cons.add(s[6] + 69*x[1] + 72*x[2] + 94*x[3] + 56*x[4] + 90*x[5] + 20*x[6] + 56*x[7]
+ 50*x[8] + 79*x[9] + 59*x[10] + 36*x[11] + 24*x[12] + 42*x[13] + 9*x[14]
+ 29*x[15] + 68*x[16] + 10*x[17] + x[18] + 44*x[19] + 74*x[20] + 61*x[21] + 37*x[22]
+ 71*x[23] + 63*x[24] + 44*x[25] + 77*x[26] + 57*x[27] + 46*x[28] + 51*x[29]
+ 43*x[30] + 4*x[31] + 85*x[32] + 59*x[33] + 7*x[34] + 25*x[35] + 46*x[36] + 25*x[37]
+ 70*x[38] + 78*x[39] + 88*x[40] + 20*x[41] + 40*x[42] + 40*x[43] + 16*x[44]
+ 3*x[45] + 3*x[46] + 5*x[47] + 77*x[48] + 88*x[49] + 16*x[50] == 1163)
return model
for load in [False, True]:
model = create_model()
opt = SolverFactory('xpress_direct')
opt.options['MAXNODE'] = 1
if not load:
# In the first iteration just solve and store the best solution
# found in x_start and s_start.
print('First iteration: Solve to get a feasible solution')
opt.solve(model, tee=True)
print('Saving solution with objective %f' % value(model.obj))
x_start, s_start = dict(), dict()
for i in model.x:
x_start[i] = model.x[i].value
for i in model.s:
s_start[i] = model.s[i].value
else:
# In the second iteration load the solution from x_start and
# s_start and then solve. The log should show lines like
# User solution (_) stored.
# ...
# Its Type BestSoln BestBound Sols Add Del Gap GInf Time
# User solution (_) accepted: Feasible after reoptimizing with fixed globals.
# U 62.000000 .000000 3 62 0 0
# That indicate that the user solution was used and accepted.
print('Second iteration: Solve with a warmstart')
for i in model.x:
model.x[i] = x_start[i]
for i in model.s:
model.s[i] = s_start[i]
opt.solve(model, warmstart=True, tee=True)
En el fin de utilizar un warmstart, puede asignar la warmstart valor a cada variable y llame a solve
con warmstart=True
. El registro de salida se muestra a través de tee
contendrá líneas como estas:
User solution (_) stored.
...
User solution (_) accepted: Feasible after reoptimizing with fixed globals.
U 62.000000 .000000 3 62 0 0
La primera línea indica que un warmstart solución fue registrado con el Xpress de solver. Las últimas dos líneas indican que el warmstart solución fue procesada y aceptada. Un warmstart solución se presenta como una solución de la 'U' heurística en el registro.
Tenga en cuenta que el procesamiento de warmstart soluciones se puede retrasar hasta después de que el primer LP de resolver, así que puede tomar un tiempo antes de que se informó en el registro.