Extract root relaxation solution

pull/1/head
Alinson S. Xavier 6 years ago
parent 7641504f3a
commit 0048fcce13

@ -13,7 +13,38 @@ import logging
logger = logging.getLogger(__name__)
class GurobiSolver:
class InternalSolver():
def __init__():
pass
def solve_lp(self, model, tee=False):
from pyomo.core.base.set_types import Reals
original_domain = {}
for var in model.component_data_objects(Var):
original_domain[str(var)] = var.domain
lb, ub = var.bounds
var.setlb(lb)
var.setub(ub)
var.domain = Reals
self.solver.set_instance(model)
self.solver.solve(tee=True)
for var in model.component_data_objects(Var):
var.domain = original_domain[str(var)]
def clear_values(self, model):
for var in model.component_objects(Var):
for index in var:
var[index].value = None
def get_solution(self, model):
solution = {}
for var in model.component_objects(Var):
solution[str(var)] = {}
for index in var:
solution[str(var)][index] = var[index].value
return solution
class GurobiSolver(InternalSolver):
def __init__(self):
self.solver = pe.SolverFactory('gurobi_persistent')
self.solver.options["Seed"] = randint(low=0, high=1000).rvs()
@ -37,9 +68,23 @@ class GurobiSolver:
"Nodes": self.solver._solver_model.getAttr("NodeCount"),
}
def _load_vars(self):
var_map = self._pyomo_var_to_solver_var_map
ref_vars = self._referenced_variables
vars_to_load = var_map.keys()
gurobi_vars_to_load = [var_map[pyomo_var] for pyomo_var in vars_to_load]
vals = self._solver_model.getAttr("X", gurobi_vars_to_load)
for var, val in zip(vars_to_load, vals):
if ref_vars[var] > 0:
var.stale = False
var.value = val
class CPLEXSolver:
class CPLEXSolver(InternalSolver):
def __init__(self):
import cplex
self.solver = pe.SolverFactory('cplex_persistent')
self.solver.options["randomseed"] = randint(low=0, high=1000).rvs()
@ -55,7 +100,6 @@ class CPLEXSolver:
def solve(self, model, tee=False, warmstart=False):
self.solver.set_instance(model)
results = self.solver.solve(tee=tee, warmstart=warmstart)
print(results)
return {
"Lower bound": results["Problem"][0]["Lower bound"],
"Upper bound": results["Problem"][0]["Upper bound"],
@ -63,6 +107,16 @@ class CPLEXSolver:
"Nodes": 1,
}
def solve_lp(self, model, tee=False):
import cplex
self.solver.set_instance(model)
lp = self.solver._solver_model
var_types = lp.variables.get_types()
n_vars = len(var_types)
lp.set_problem_type(cplex.Cplex.problem_type.LP)
results = self.solver.solve(tee=tee)
lp.variables.set_types(zip(range(n_vars), var_types))
class LearningSolver:
"""
@ -117,30 +171,34 @@ class LearningSolver:
def solve(self, instance, tee=False):
model = instance.to_model()
self.tee = tee
self.internal_solver = self._create_internal_solver()
# Solve LP relaxation
self.internal_solver.solve_lp(model, tee=tee)
instance.lp_solution = self.internal_solver.get_solution(model)
# Invoke before_solve callbacks
for component in self.components.values():
component.before_solve(self, instance, model)
# Check if warm start is available
is_warm_start_available = False
if "warm-start" in self.components.keys():
if self.components["warm-start"].is_warm_start_available:
is_warm_start_available = True
# Solver original MIP
self.internal_solver.clear_values(model)
results = self.internal_solver.solve(model,
tee=tee,
warmstart=is_warm_start_available)
tee=tee,
warmstart=is_warm_start_available)
instance.solution = {}
# Read MIP solution and bounds
instance.lower_bound = results["Lower bound"]
instance.upper_bound = results["Upper bound"]
instance.solution = self.internal_solver.get_solution(model)
for var in model.component_objects(Var):
instance.solution[str(var)] = {}
for index in var:
instance.solution[str(var)][index] = var[index].value
# Invoke after_solve callbacks
for component in self.components.values():
component.after_solve(self, instance, model)
@ -164,6 +222,7 @@ class LearningSolver:
"Solver": solver,
"Results": results,
"Solution": instance.solution,
"LP solution": instance.lp_solution,
"Upper bound": instance.upper_bound,
"Lower bound": instance.lower_bound,
}
@ -174,6 +233,7 @@ class LearningSolver:
for (idx, r) in enumerate(p_map_results):
instances[idx].solution = r["Solution"]
instances[idx].lp_solution = r["LP solution"]
instances[idx].lower_bound = r["Lower bound"]
instances[idx].upper_bound = r["Upper bound"]
@ -205,3 +265,4 @@ class LearningSolver:
continue
else:
self.components[component_name].merge([component])

@ -27,6 +27,12 @@ def test_solver():
assert instance.solution["x"][1] == 0.0
assert instance.solution["x"][2] == 1.0
assert instance.solution["x"][3] == 1.0
assert round(instance.lp_solution["x"][0], 3) == 1.000
assert round(instance.lp_solution["x"][1], 3) == 0.923
assert round(instance.lp_solution["x"][2], 3) == 1.000
assert round(instance.lp_solution["x"][3], 3) == 0.000
assert instance.lower_bound == 1183.0
assert instance.upper_bound == 1183.0
solver.fit()

Loading…
Cancel
Save