|
|
@ -4,6 +4,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
from . import WarmStartComponent, BranchPriorityComponent
|
|
|
|
from . import WarmStartComponent, BranchPriorityComponent
|
|
|
|
import pyomo.environ as pe
|
|
|
|
import pyomo.environ as pe
|
|
|
|
|
|
|
|
from pyomo.core import Var
|
|
|
|
from copy import deepcopy
|
|
|
|
from copy import deepcopy
|
|
|
|
import pickle
|
|
|
|
import pickle
|
|
|
|
from scipy.stats import randint
|
|
|
|
from scipy.stats import randint
|
|
|
@ -76,7 +77,7 @@ class LearningSolver:
|
|
|
|
if self.threads is not None:
|
|
|
|
if self.threads is not None:
|
|
|
|
self.internal_solver.options["Threads"] = self.threads
|
|
|
|
self.internal_solver.options["Threads"] = self.threads
|
|
|
|
if self.time_limit is not None:
|
|
|
|
if self.time_limit is not None:
|
|
|
|
self.internal_solver.options["TimeLimit"] = self.time_limit
|
|
|
|
self.internal_solver.options["timelimit"] = self.time_limit
|
|
|
|
if self.gap_limit is not None:
|
|
|
|
if self.gap_limit is not None:
|
|
|
|
self.internal_solver.options["MIPGap"] = self.gap_limit
|
|
|
|
self.internal_solver.options["MIPGap"] = self.gap_limit
|
|
|
|
|
|
|
|
|
|
|
@ -100,6 +101,14 @@ class LearningSolver:
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
solve_results = self.internal_solver.solve(model, tee=tee, warmstart=is_warm_start_available)
|
|
|
|
solve_results = self.internal_solver.solve(model, tee=tee, warmstart=is_warm_start_available)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
instance.solution = {}
|
|
|
|
|
|
|
|
instance.lower_bound = solve_results["Problem"][0]["Lower bound"]
|
|
|
|
|
|
|
|
instance.upper_bound = solve_results["Problem"][0]["Upper bound"]
|
|
|
|
|
|
|
|
for var in model.component_objects(Var):
|
|
|
|
|
|
|
|
instance.solution[str(var)] = {}
|
|
|
|
|
|
|
|
for index in var:
|
|
|
|
|
|
|
|
instance.solution[str(var)][index] = var[index].value
|
|
|
|
|
|
|
|
|
|
|
|
if self.internal_solver.name == "gurobi_persistent":
|
|
|
|
if self.internal_solver.name == "gurobi_persistent":
|
|
|
|
solve_results["Solver"][0]["Nodes"] = self.internal_solver._solver_model.getAttr("NodeCount")
|
|
|
|
solve_results["Solver"][0]["Nodes"] = self.internal_solver._solver_model.getAttr("NodeCount")
|
|
|
|
else:
|
|
|
|
else:
|
|
|
@ -124,11 +133,22 @@ class LearningSolver:
|
|
|
|
solver.internal_solver = None
|
|
|
|
solver.internal_solver = None
|
|
|
|
if not collect_training_data:
|
|
|
|
if not collect_training_data:
|
|
|
|
solver.components = {}
|
|
|
|
solver.components = {}
|
|
|
|
return solver, results
|
|
|
|
return {
|
|
|
|
|
|
|
|
"solver": solver,
|
|
|
|
|
|
|
|
"results": results,
|
|
|
|
|
|
|
|
"solution": instance.solution,
|
|
|
|
|
|
|
|
"upper bound": instance.upper_bound,
|
|
|
|
|
|
|
|
"lower bound": instance.lower_bound,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p_map_results = p_map(_process, instances, num_cpus=n_jobs, desc=label)
|
|
|
|
|
|
|
|
subsolvers = [p["solver"] for p in p_map_results]
|
|
|
|
|
|
|
|
results = [p["results"] for p in p_map_results]
|
|
|
|
|
|
|
|
|
|
|
|
solver_result_pairs = p_map(_process, instances, num_cpus=n_jobs, desc=label)
|
|
|
|
for (idx, r) in enumerate(p_map_results):
|
|
|
|
subsolvers = [p[0] for p in solver_result_pairs]
|
|
|
|
instances[idx].solution = r["solution"]
|
|
|
|
results = [p[1] for p in solver_result_pairs]
|
|
|
|
instances[idx].lower_bound = r["lower bound"]
|
|
|
|
|
|
|
|
instances[idx].upper_bound = r["upper bound"]
|
|
|
|
|
|
|
|
|
|
|
|
for (name, component) in self.components.items():
|
|
|
|
for (name, component) in self.components.items():
|
|
|
|
subcomponents = [subsolver.components[name]
|
|
|
|
subcomponents = [subsolver.components[name]
|
|
|
|