mirror of
https://github.com/ANL-CEEESA/MIPLearn.git
synced 2025-12-06 09:28:51 -06:00
Move instance fixtures into the main source; remove duplication
This commit is contained in:
@@ -289,35 +289,3 @@ class KnapsackInstance(Instance):
|
|||||||
self.weights[item],
|
self.weights[item],
|
||||||
self.prices[item],
|
self.prices[item],
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class GurobiKnapsackInstance(KnapsackInstance):
|
|
||||||
"""
|
|
||||||
Simpler (one-dimensional) knapsack instance, implemented directly in Gurobi
|
|
||||||
instead of Pyomo, used for testing.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
weights: List[float],
|
|
||||||
prices: List[float],
|
|
||||||
capacity: float,
|
|
||||||
) -> None:
|
|
||||||
super().__init__(weights, prices, capacity)
|
|
||||||
|
|
||||||
@overrides
|
|
||||||
def to_model(self) -> Any:
|
|
||||||
import gurobipy as gp
|
|
||||||
from gurobipy import GRB
|
|
||||||
|
|
||||||
model = gp.Model("Knapsack")
|
|
||||||
n = len(self.weights)
|
|
||||||
x = model.addVars(n, vtype=GRB.BINARY, name="x")
|
|
||||||
model.addConstr(
|
|
||||||
gp.quicksum(x[i] * self.weights[i] for i in range(n)) <= self.capacity,
|
|
||||||
"eq_capacity",
|
|
||||||
)
|
|
||||||
model.setObjective(
|
|
||||||
gp.quicksum(x[i] * self.prices[i] for i in range(n)), GRB.MAXIMIZE
|
|
||||||
)
|
|
||||||
return model
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ from miplearn.solvers.internal import (
|
|||||||
LazyCallback,
|
LazyCallback,
|
||||||
MIPSolveStats,
|
MIPSolveStats,
|
||||||
)
|
)
|
||||||
|
from miplearn.solvers.pyomo.base import PyomoTestInstanceKnapsack
|
||||||
from miplearn.types import (
|
from miplearn.types import (
|
||||||
SolverParams,
|
SolverParams,
|
||||||
UserCutCallback,
|
UserCutCallback,
|
||||||
@@ -442,3 +443,77 @@ class GurobiSolver(InternalSolver):
|
|||||||
params=self.params,
|
params=self.params,
|
||||||
lazy_cb_frequency=self.lazy_cb_frequency,
|
lazy_cb_frequency=self.lazy_cb_frequency,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@overrides
|
||||||
|
def build_test_instance_infeasible(self) -> Instance:
|
||||||
|
return GurobiTestInstanceInfeasible()
|
||||||
|
|
||||||
|
@overrides
|
||||||
|
def build_test_instance_redundancy(self) -> Instance:
|
||||||
|
return GurobiTestInstanceRedundancy()
|
||||||
|
|
||||||
|
@overrides
|
||||||
|
def build_test_instance_knapsack(self) -> Instance:
|
||||||
|
return GurobiTestInstanceKnapsack(
|
||||||
|
weights=[23.0, 26.0, 20.0, 18.0],
|
||||||
|
prices=[505.0, 352.0, 458.0, 220.0],
|
||||||
|
capacity=67.0,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class GurobiTestInstanceInfeasible(Instance):
|
||||||
|
@overrides
|
||||||
|
def to_model(self) -> Any:
|
||||||
|
import gurobipy as gp
|
||||||
|
from gurobipy import GRB
|
||||||
|
|
||||||
|
model = gp.Model()
|
||||||
|
x = model.addVars(1, vtype=GRB.BINARY, name="x")
|
||||||
|
model.addConstr(x[0] >= 2)
|
||||||
|
model.setObjective(x[0])
|
||||||
|
return model
|
||||||
|
|
||||||
|
|
||||||
|
class GurobiTestInstanceRedundancy(Instance):
|
||||||
|
def to_model(self) -> Any:
|
||||||
|
import gurobipy as gp
|
||||||
|
from gurobipy import GRB
|
||||||
|
|
||||||
|
model = gp.Model()
|
||||||
|
x = model.addVars(2, vtype=GRB.BINARY, name="x")
|
||||||
|
model.addConstr(x[0] + x[1] <= 1)
|
||||||
|
model.addConstr(x[0] + x[1] <= 2)
|
||||||
|
model.setObjective(x[0] + x[1], GRB.MAXIMIZE)
|
||||||
|
return model
|
||||||
|
|
||||||
|
|
||||||
|
class GurobiTestInstanceKnapsack(PyomoTestInstanceKnapsack):
|
||||||
|
"""
|
||||||
|
Simpler (one-dimensional) knapsack instance, implemented directly in Gurobi
|
||||||
|
instead of Pyomo, used for testing.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
weights: List[float],
|
||||||
|
prices: List[float],
|
||||||
|
capacity: float,
|
||||||
|
) -> None:
|
||||||
|
super().__init__(weights, prices, capacity)
|
||||||
|
|
||||||
|
@overrides
|
||||||
|
def to_model(self) -> Any:
|
||||||
|
import gurobipy as gp
|
||||||
|
from gurobipy import GRB
|
||||||
|
|
||||||
|
model = gp.Model("Knapsack")
|
||||||
|
n = len(self.weights)
|
||||||
|
x = model.addVars(n, vtype=GRB.BINARY, name="x")
|
||||||
|
model.addConstr(
|
||||||
|
gp.quicksum(x[i] * self.weights[i] for i in range(n)) <= self.capacity,
|
||||||
|
"eq_capacity",
|
||||||
|
)
|
||||||
|
model.setObjective(
|
||||||
|
gp.quicksum(x[i] * self.prices[i] for i in range(n)), GRB.MAXIMIZE
|
||||||
|
)
|
||||||
|
return model
|
||||||
|
|||||||
@@ -292,3 +292,15 @@ class InternalSolver(ABC):
|
|||||||
completely unitialized.
|
completely unitialized.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def build_test_instance_infeasible(self) -> Instance:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def build_test_instance_redundancy(self) -> Instance:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def build_test_instance_knapsack(self) -> Instance:
|
||||||
|
pass
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ from miplearn.types import (
|
|||||||
UserCutCallback,
|
UserCutCallback,
|
||||||
Solution,
|
Solution,
|
||||||
VariableName,
|
VariableName,
|
||||||
|
Category,
|
||||||
)
|
)
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -338,3 +340,88 @@ class BasePyomoSolver(InternalSolver):
|
|||||||
@overrides
|
@overrides
|
||||||
def get_sense(self) -> str:
|
def get_sense(self) -> str:
|
||||||
return self._obj_sense
|
return self._obj_sense
|
||||||
|
|
||||||
|
@overrides
|
||||||
|
def build_test_instance_infeasible(self) -> Instance:
|
||||||
|
return PyomoTestInstanceInfeasible()
|
||||||
|
|
||||||
|
@overrides
|
||||||
|
def build_test_instance_redundancy(self) -> Instance:
|
||||||
|
return PyomoTestInstanceRedundancy()
|
||||||
|
|
||||||
|
@overrides
|
||||||
|
def build_test_instance_knapsack(self) -> Instance:
|
||||||
|
return PyomoTestInstanceKnapsack(
|
||||||
|
weights=[23.0, 26.0, 20.0, 18.0],
|
||||||
|
prices=[505.0, 352.0, 458.0, 220.0],
|
||||||
|
capacity=67.0,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PyomoTestInstanceInfeasible(Instance):
|
||||||
|
@overrides
|
||||||
|
def to_model(self) -> pe.ConcreteModel:
|
||||||
|
model = pe.ConcreteModel()
|
||||||
|
model.x = pe.Var([0], domain=pe.Binary)
|
||||||
|
model.OBJ = pe.Objective(expr=model.x[0], sense=pe.maximize)
|
||||||
|
model.eq = pe.Constraint(expr=model.x[0] >= 2)
|
||||||
|
return model
|
||||||
|
|
||||||
|
|
||||||
|
class PyomoTestInstanceRedundancy(Instance):
|
||||||
|
def to_model(self) -> pe.ConcreteModel:
|
||||||
|
model = pe.ConcreteModel()
|
||||||
|
model.x = pe.Var([0, 1], domain=pe.Binary)
|
||||||
|
model.OBJ = pe.Objective(expr=model.x[0] + model.x[1], sense=pe.maximize)
|
||||||
|
model.eq1 = pe.Constraint(expr=model.x[0] + model.x[1] <= 1)
|
||||||
|
model.eq2 = pe.Constraint(expr=model.x[0] + model.x[1] <= 2)
|
||||||
|
return model
|
||||||
|
|
||||||
|
|
||||||
|
class PyomoTestInstanceKnapsack(Instance):
|
||||||
|
"""
|
||||||
|
Simpler (one-dimensional) Knapsack Problem, used for testing.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
weights: List[float],
|
||||||
|
prices: List[float],
|
||||||
|
capacity: float,
|
||||||
|
) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.weights = weights
|
||||||
|
self.prices = prices
|
||||||
|
self.capacity = capacity
|
||||||
|
self.varname_to_item: Dict[VariableName, int] = {
|
||||||
|
f"x[{i}]": i for i in range(len(self.weights))
|
||||||
|
}
|
||||||
|
|
||||||
|
@overrides
|
||||||
|
def to_model(self) -> pe.ConcreteModel:
|
||||||
|
model = pe.ConcreteModel()
|
||||||
|
items = range(len(self.weights))
|
||||||
|
model.x = pe.Var(items, domain=pe.Binary)
|
||||||
|
model.OBJ = pe.Objective(
|
||||||
|
expr=sum(model.x[v] * self.prices[v] for v in items),
|
||||||
|
sense=pe.maximize,
|
||||||
|
)
|
||||||
|
model.eq_capacity = pe.Constraint(
|
||||||
|
expr=sum(model.x[v] * self.weights[v] for v in items) <= self.capacity
|
||||||
|
)
|
||||||
|
return model
|
||||||
|
|
||||||
|
@overrides
|
||||||
|
def get_instance_features(self) -> List[float]:
|
||||||
|
return [
|
||||||
|
self.capacity,
|
||||||
|
np.average(self.weights),
|
||||||
|
]
|
||||||
|
|
||||||
|
@overrides
|
||||||
|
def get_variable_features(self, var_name: VariableName) -> List[Category]:
|
||||||
|
item = self.varname_to_item[var_name]
|
||||||
|
return [
|
||||||
|
self.weights[item],
|
||||||
|
self.prices[item],
|
||||||
|
]
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ from miplearn.features import TrainingSample, InstanceFeatures, Features
|
|||||||
from miplearn.instance.base import Instance
|
from miplearn.instance.base import Instance
|
||||||
from miplearn.solvers.learning import LearningSolver
|
from miplearn.solvers.learning import LearningSolver
|
||||||
from miplearn.solvers.pyomo.gurobi import GurobiPyomoSolver
|
from miplearn.solvers.pyomo.gurobi import GurobiPyomoSolver
|
||||||
from tests.fixtures.knapsack import get_knapsack_instance
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@@ -252,7 +251,7 @@ def test_sample_evaluate(instance: Instance, sample: TrainingSample) -> None:
|
|||||||
|
|
||||||
def test_usage() -> None:
|
def test_usage() -> None:
|
||||||
solver = LearningSolver(components=[ObjectiveValueComponent()])
|
solver = LearningSolver(components=[ObjectiveValueComponent()])
|
||||||
instance = get_knapsack_instance(GurobiPyomoSolver())
|
instance = GurobiPyomoSolver().build_test_instance_knapsack()
|
||||||
solver.solve(instance)
|
solver.solve(instance)
|
||||||
solver.fit([instance])
|
solver.fit([instance])
|
||||||
stats = solver.solve(instance)
|
stats = solver.solve(instance)
|
||||||
|
|||||||
3
tests/fixtures/__init__.py
vendored
3
tests/fixtures/__init__.py
vendored
@@ -1,3 +0,0 @@
|
|||||||
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
|
||||||
# Copyright (C) 2020-2021, UChicago Argonne, LLC. All rights reserved.
|
|
||||||
# Released under the modified BSD license. See COPYING.md for more details.
|
|
||||||
44
tests/fixtures/infeasible.py
vendored
44
tests/fixtures/infeasible.py
vendored
@@ -1,44 +0,0 @@
|
|||||||
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
|
||||||
# Copyright (C) 2020-2021, UChicago Argonne, LLC. All rights reserved.
|
|
||||||
# Released under the modified BSD license. See COPYING.md for more details.
|
|
||||||
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from overrides import overrides
|
|
||||||
from pyomo import environ as pe
|
|
||||||
|
|
||||||
from miplearn.instance.base import Instance
|
|
||||||
from miplearn.solvers.gurobi import GurobiSolver
|
|
||||||
from miplearn.solvers.pyomo.base import BasePyomoSolver
|
|
||||||
from tests.solvers import _is_subclass_or_instance
|
|
||||||
|
|
||||||
|
|
||||||
class InfeasiblePyomoInstance(Instance):
|
|
||||||
@overrides
|
|
||||||
def to_model(self) -> pe.ConcreteModel:
|
|
||||||
model = pe.ConcreteModel()
|
|
||||||
model.x = pe.Var([0], domain=pe.Binary)
|
|
||||||
model.OBJ = pe.Objective(expr=model.x[0], sense=pe.maximize)
|
|
||||||
model.eq = pe.Constraint(expr=model.x[0] >= 2)
|
|
||||||
return model
|
|
||||||
|
|
||||||
|
|
||||||
class InfeasibleGurobiInstance(Instance):
|
|
||||||
@overrides
|
|
||||||
def to_model(self) -> Any:
|
|
||||||
import gurobipy as gp
|
|
||||||
from gurobipy import GRB
|
|
||||||
|
|
||||||
model = gp.Model()
|
|
||||||
x = model.addVars(1, vtype=GRB.BINARY, name="x")
|
|
||||||
model.addConstr(x[0] >= 2)
|
|
||||||
model.setObjective(x[0])
|
|
||||||
return model
|
|
||||||
|
|
||||||
|
|
||||||
def get_infeasible_instance(solver: Any) -> Instance:
|
|
||||||
if _is_subclass_or_instance(solver, BasePyomoSolver):
|
|
||||||
return InfeasiblePyomoInstance()
|
|
||||||
if _is_subclass_or_instance(solver, GurobiSolver):
|
|
||||||
return InfeasibleGurobiInstance()
|
|
||||||
assert False
|
|
||||||
50
tests/fixtures/knapsack.py
vendored
50
tests/fixtures/knapsack.py
vendored
@@ -1,50 +0,0 @@
|
|||||||
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
|
||||||
# Copyright (C) 2020-2021, UChicago Argonne, LLC. All rights reserved.
|
|
||||||
# Released under the modified BSD license. See COPYING.md for more details.
|
|
||||||
|
|
||||||
from typing import List, Any, Tuple
|
|
||||||
|
|
||||||
from miplearn.instance.base import Instance
|
|
||||||
from miplearn.problems.knapsack import KnapsackInstance, GurobiKnapsackInstance
|
|
||||||
from miplearn.solvers.gurobi import GurobiSolver
|
|
||||||
from miplearn.solvers.internal import InternalSolver
|
|
||||||
from miplearn.solvers.learning import LearningSolver
|
|
||||||
from miplearn.solvers.pyomo.base import BasePyomoSolver
|
|
||||||
from tests.solvers import _is_subclass_or_instance
|
|
||||||
|
|
||||||
|
|
||||||
def get_test_pyomo_instances() -> Tuple[List[Instance], List[Any]]:
|
|
||||||
instances: List[Instance] = [
|
|
||||||
KnapsackInstance(
|
|
||||||
weights=[23.0, 26.0, 20.0, 18.0],
|
|
||||||
prices=[505.0, 352.0, 458.0, 220.0],
|
|
||||||
capacity=67.0,
|
|
||||||
),
|
|
||||||
KnapsackInstance(
|
|
||||||
weights=[25.0, 30.0, 22.0, 18.0],
|
|
||||||
prices=[500.0, 365.0, 420.0, 150.0],
|
|
||||||
capacity=70.0,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
models = [instance.to_model() for instance in instances]
|
|
||||||
solver = LearningSolver()
|
|
||||||
for i in range(len(instances)):
|
|
||||||
solver.solve(instances[i], models[i])
|
|
||||||
return instances, models
|
|
||||||
|
|
||||||
|
|
||||||
def get_knapsack_instance(solver: InternalSolver) -> Instance:
|
|
||||||
if _is_subclass_or_instance(solver, BasePyomoSolver):
|
|
||||||
return KnapsackInstance(
|
|
||||||
weights=[23.0, 26.0, 20.0, 18.0],
|
|
||||||
prices=[505.0, 352.0, 458.0, 220.0],
|
|
||||||
capacity=67.0,
|
|
||||||
)
|
|
||||||
elif _is_subclass_or_instance(solver, GurobiSolver):
|
|
||||||
return GurobiKnapsackInstance(
|
|
||||||
weights=[23.0, 26.0, 20.0, 18.0],
|
|
||||||
prices=[505.0, 352.0, 458.0, 220.0],
|
|
||||||
capacity=67.0,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
assert False
|
|
||||||
42
tests/fixtures/redundant.py
vendored
42
tests/fixtures/redundant.py
vendored
@@ -1,42 +0,0 @@
|
|||||||
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
|
||||||
# Copyright (C) 2020-2021, UChicago Argonne, LLC. All rights reserved.
|
|
||||||
# Released under the modified BSD license. See COPYING.md for more details.
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
import pyomo.environ as pe
|
|
||||||
|
|
||||||
from miplearn.instance.base import Instance
|
|
||||||
from miplearn.solvers.gurobi import GurobiSolver
|
|
||||||
from miplearn.solvers.pyomo.base import BasePyomoSolver
|
|
||||||
from tests.solvers import _is_subclass_or_instance
|
|
||||||
|
|
||||||
|
|
||||||
class PyomoInstanceWithRedundancy(Instance):
|
|
||||||
def to_model(self) -> pe.ConcreteModel:
|
|
||||||
model = pe.ConcreteModel()
|
|
||||||
model.x = pe.Var([0, 1], domain=pe.Binary)
|
|
||||||
model.OBJ = pe.Objective(expr=model.x[0] + model.x[1], sense=pe.maximize)
|
|
||||||
model.eq1 = pe.Constraint(expr=model.x[0] + model.x[1] <= 1)
|
|
||||||
model.eq2 = pe.Constraint(expr=model.x[0] + model.x[1] <= 2)
|
|
||||||
return model
|
|
||||||
|
|
||||||
|
|
||||||
class GurobiInstanceWithRedundancy(Instance):
|
|
||||||
def to_model(self) -> Any:
|
|
||||||
import gurobipy as gp
|
|
||||||
from gurobipy import GRB
|
|
||||||
|
|
||||||
model = gp.Model()
|
|
||||||
x = model.addVars(2, vtype=GRB.BINARY, name="x")
|
|
||||||
model.addConstr(x[0] + x[1] <= 1)
|
|
||||||
model.addConstr(x[0] + x[1] <= 2)
|
|
||||||
model.setObjective(x[0] + x[1], GRB.MAXIMIZE)
|
|
||||||
return model
|
|
||||||
|
|
||||||
|
|
||||||
def get_instance_with_redundancy(solver: Any) -> Instance:
|
|
||||||
if _is_subclass_or_instance(solver, BasePyomoSolver):
|
|
||||||
return PyomoInstanceWithRedundancy()
|
|
||||||
if _is_subclass_or_instance(solver, GurobiSolver):
|
|
||||||
return GurobiInstanceWithRedundancy()
|
|
||||||
assert False
|
|
||||||
@@ -5,11 +5,10 @@ import tempfile
|
|||||||
|
|
||||||
from miplearn.instance.picklegz import write_pickle_gz, PickleGzInstance
|
from miplearn.instance.picklegz import write_pickle_gz, PickleGzInstance
|
||||||
from miplearn.solvers.gurobi import GurobiSolver
|
from miplearn.solvers.gurobi import GurobiSolver
|
||||||
from tests.fixtures.knapsack import get_knapsack_instance
|
|
||||||
|
|
||||||
|
|
||||||
def test_usage() -> None:
|
def test_usage() -> None:
|
||||||
original = get_knapsack_instance(GurobiSolver())
|
original = GurobiSolver().build_test_instance_knapsack()
|
||||||
file = tempfile.NamedTemporaryFile()
|
file = tempfile.NamedTemporaryFile()
|
||||||
write_pickle_gz(original, file.name)
|
write_pickle_gz(original, file.name)
|
||||||
pickled = PickleGzInstance(file.name)
|
pickled = PickleGzInstance(file.name)
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
|
||||||
# Copyright (C) 2020-2021, UChicago Argonne, LLC. All rights reserved.
|
|
||||||
# Released under the modified BSD license. See COPYING.md for more details.
|
|
||||||
|
|
||||||
from inspect import isclass
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from miplearn.instance.base import Instance
|
|
||||||
from miplearn.problems.knapsack import KnapsackInstance, GurobiKnapsackInstance
|
|
||||||
from miplearn.solvers.gurobi import GurobiSolver
|
|
||||||
from miplearn.solvers.pyomo.base import BasePyomoSolver
|
|
||||||
|
|
||||||
|
|
||||||
def _is_subclass_or_instance(obj: Any, parent_class: Any) -> bool:
|
|
||||||
return isinstance(obj, parent_class) or (
|
|
||||||
isclass(obj) and issubclass(obj, parent_class)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_knapsack_instance(solver: Any) -> Instance:
|
|
||||||
if _is_subclass_or_instance(solver, BasePyomoSolver):
|
|
||||||
return KnapsackInstance(
|
|
||||||
weights=[23.0, 26.0, 20.0, 18.0],
|
|
||||||
prices=[505.0, 352.0, 458.0, 220.0],
|
|
||||||
capacity=67.0,
|
|
||||||
)
|
|
||||||
if _is_subclass_or_instance(solver, GurobiSolver):
|
|
||||||
return GurobiKnapsackInstance(
|
|
||||||
weights=[23.0, 26.0, 20.0, 18.0],
|
|
||||||
prices=[505.0, 352.0, 458.0, 220.0],
|
|
||||||
capacity=67.0,
|
|
||||||
)
|
|
||||||
assert False
|
|
||||||
|
|||||||
@@ -13,11 +13,9 @@ from miplearn import InternalSolver
|
|||||||
from miplearn.solvers import _RedirectOutput
|
from miplearn.solvers import _RedirectOutput
|
||||||
from miplearn.solvers.gurobi import GurobiSolver
|
from miplearn.solvers.gurobi import GurobiSolver
|
||||||
from miplearn.solvers.pyomo.base import BasePyomoSolver
|
from miplearn.solvers.pyomo.base import BasePyomoSolver
|
||||||
from . import _get_knapsack_instance
|
|
||||||
|
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
from .. import internal_solvers
|
from .. import internal_solvers
|
||||||
from ..fixtures.infeasible import get_infeasible_instance
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -38,7 +36,7 @@ def test_internal_solver_warm_starts(
|
|||||||
) -> None:
|
) -> None:
|
||||||
for solver in internal_solvers:
|
for solver in internal_solvers:
|
||||||
logger.info("Solver: %s" % solver)
|
logger.info("Solver: %s" % solver)
|
||||||
instance = _get_knapsack_instance(solver)
|
instance = solver.build_test_instance_knapsack()
|
||||||
model = instance.to_model()
|
model = instance.to_model()
|
||||||
solver.set_instance(instance, model)
|
solver.set_instance(instance, model)
|
||||||
solver.set_warm_start({"x[0]": 1.0, "x[1]": 0.0, "x[2]": 0.0, "x[3]": 1.0})
|
solver.set_warm_start({"x[0]": 1.0, "x[1]": 0.0, "x[2]": 0.0, "x[3]": 1.0})
|
||||||
@@ -64,7 +62,7 @@ def test_internal_solver(
|
|||||||
for solver in internal_solvers:
|
for solver in internal_solvers:
|
||||||
logger.info("Solver: %s" % solver)
|
logger.info("Solver: %s" % solver)
|
||||||
|
|
||||||
instance = _get_knapsack_instance(solver)
|
instance = solver.build_test_instance_knapsack()
|
||||||
model = instance.to_model()
|
model = instance.to_model()
|
||||||
solver.set_instance(instance, model)
|
solver.set_instance(instance, model)
|
||||||
|
|
||||||
@@ -169,7 +167,7 @@ def test_relax(
|
|||||||
internal_solvers: List[InternalSolver],
|
internal_solvers: List[InternalSolver],
|
||||||
) -> None:
|
) -> None:
|
||||||
for solver in internal_solvers:
|
for solver in internal_solvers:
|
||||||
instance = _get_knapsack_instance(solver)
|
instance = solver.build_test_instance_knapsack()
|
||||||
solver.set_instance(instance)
|
solver.set_instance(instance)
|
||||||
solver.relax()
|
solver.relax()
|
||||||
stats = solver.solve()
|
stats = solver.solve()
|
||||||
@@ -181,7 +179,7 @@ def test_infeasible_instance(
|
|||||||
internal_solvers: List[InternalSolver],
|
internal_solvers: List[InternalSolver],
|
||||||
) -> None:
|
) -> None:
|
||||||
for solver in internal_solvers:
|
for solver in internal_solvers:
|
||||||
instance = get_infeasible_instance(solver)
|
instance = solver.build_test_instance_infeasible()
|
||||||
solver.set_instance(instance)
|
solver.set_instance(instance)
|
||||||
mip_stats = solver.solve()
|
mip_stats = solver.solve()
|
||||||
|
|
||||||
@@ -200,7 +198,7 @@ def test_iteration_cb(
|
|||||||
) -> None:
|
) -> None:
|
||||||
for solver in internal_solvers:
|
for solver in internal_solvers:
|
||||||
logger.info("Solver: %s" % solver)
|
logger.info("Solver: %s" % solver)
|
||||||
instance = _get_knapsack_instance(solver)
|
instance = solver.build_test_instance_knapsack()
|
||||||
solver.set_instance(instance)
|
solver.set_instance(instance)
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,13 @@ from typing import Any
|
|||||||
|
|
||||||
from miplearn import InternalSolver
|
from miplearn import InternalSolver
|
||||||
from miplearn.solvers.gurobi import GurobiSolver
|
from miplearn.solvers.gurobi import GurobiSolver
|
||||||
from . import _get_knapsack_instance
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def test_lazy_cb() -> None:
|
def test_lazy_cb() -> None:
|
||||||
solver = GurobiSolver()
|
solver = GurobiSolver()
|
||||||
instance = _get_knapsack_instance(solver)
|
instance = solver.build_test_instance_knapsack()
|
||||||
model = instance.to_model()
|
model = instance.to_model()
|
||||||
|
|
||||||
def lazy_cb(cb_solver: InternalSolver, cb_model: Any) -> None:
|
def lazy_cb(cb_solver: InternalSolver, cb_model: Any) -> None:
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ from miplearn import Instance, InternalSolver
|
|||||||
from miplearn.instance.picklegz import PickleGzInstance, write_pickle_gz, read_pickle_gz
|
from miplearn.instance.picklegz import PickleGzInstance, write_pickle_gz, read_pickle_gz
|
||||||
from miplearn.solvers.gurobi import GurobiSolver
|
from miplearn.solvers.gurobi import GurobiSolver
|
||||||
from miplearn.solvers.learning import LearningSolver
|
from miplearn.solvers.learning import LearningSolver
|
||||||
from . import _get_knapsack_instance
|
|
||||||
|
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
from tests import internal_solvers
|
from tests import internal_solvers
|
||||||
@@ -27,7 +26,7 @@ def test_learning_solver(
|
|||||||
for mode in ["exact", "heuristic"]:
|
for mode in ["exact", "heuristic"]:
|
||||||
for internal_solver in internal_solvers:
|
for internal_solver in internal_solvers:
|
||||||
logger.info("Solver: %s" % internal_solver)
|
logger.info("Solver: %s" % internal_solver)
|
||||||
instance = _get_knapsack_instance(internal_solver)
|
instance = internal_solver.build_test_instance_knapsack()
|
||||||
solver = LearningSolver(
|
solver = LearningSolver(
|
||||||
solver=internal_solver,
|
solver=internal_solver,
|
||||||
mode=mode,
|
mode=mode,
|
||||||
@@ -71,7 +70,7 @@ def test_solve_without_lp(
|
|||||||
) -> None:
|
) -> None:
|
||||||
for internal_solver in internal_solvers:
|
for internal_solver in internal_solvers:
|
||||||
logger.info("Solver: %s" % internal_solver)
|
logger.info("Solver: %s" % internal_solver)
|
||||||
instance = _get_knapsack_instance(internal_solver)
|
instance = internal_solver.build_test_instance_knapsack()
|
||||||
solver = LearningSolver(
|
solver = LearningSolver(
|
||||||
solver=internal_solver,
|
solver=internal_solver,
|
||||||
solve_lp=False,
|
solve_lp=False,
|
||||||
@@ -85,7 +84,7 @@ def test_parallel_solve(
|
|||||||
internal_solvers: List[InternalSolver],
|
internal_solvers: List[InternalSolver],
|
||||||
) -> None:
|
) -> None:
|
||||||
for internal_solver in internal_solvers:
|
for internal_solver in internal_solvers:
|
||||||
instances = [_get_knapsack_instance(internal_solver) for _ in range(10)]
|
instances = [internal_solver.build_test_instance_knapsack() for _ in range(10)]
|
||||||
solver = LearningSolver(solver=internal_solver)
|
solver = LearningSolver(solver=internal_solver)
|
||||||
results = solver.parallel_solve(instances, n_jobs=3)
|
results = solver.parallel_solve(instances, n_jobs=3)
|
||||||
assert len(results) == 10
|
assert len(results) == 10
|
||||||
@@ -102,7 +101,7 @@ def test_solve_fit_from_disk(
|
|||||||
# Create instances and pickle them
|
# Create instances and pickle them
|
||||||
instances: List[Instance] = []
|
instances: List[Instance] = []
|
||||||
for k in range(3):
|
for k in range(3):
|
||||||
instance = _get_knapsack_instance(internal_solver)
|
instance = internal_solver.build_test_instance_knapsack()
|
||||||
with tempfile.NamedTemporaryFile(suffix=".pkl", delete=False) as file:
|
with tempfile.NamedTemporaryFile(suffix=".pkl", delete=False) as file:
|
||||||
instances += [PickleGzInstance(file.name)]
|
instances += [PickleGzInstance(file.name)]
|
||||||
write_pickle_gz(instance, file.name)
|
write_pickle_gz(instance, file.name)
|
||||||
@@ -132,7 +131,7 @@ def test_solve_fit_from_disk(
|
|||||||
|
|
||||||
def test_simulate_perfect() -> None:
|
def test_simulate_perfect() -> None:
|
||||||
internal_solver = GurobiSolver()
|
internal_solver = GurobiSolver()
|
||||||
instance = _get_knapsack_instance(internal_solver)
|
instance = internal_solver.build_test_instance_knapsack()
|
||||||
with tempfile.NamedTemporaryFile(suffix=".pkl", delete=False) as tmp:
|
with tempfile.NamedTemporaryFile(suffix=".pkl", delete=False) as tmp:
|
||||||
write_pickle_gz(instance, tmp.name)
|
write_pickle_gz(instance, tmp.name)
|
||||||
solver = LearningSolver(
|
solver = LearningSolver(
|
||||||
|
|||||||
@@ -9,13 +9,12 @@ from miplearn.features import (
|
|||||||
ConstraintFeatures,
|
ConstraintFeatures,
|
||||||
)
|
)
|
||||||
from miplearn.solvers.gurobi import GurobiSolver
|
from miplearn.solvers.gurobi import GurobiSolver
|
||||||
from tests.fixtures.knapsack import get_knapsack_instance
|
|
||||||
|
|
||||||
|
|
||||||
def test_knapsack() -> None:
|
def test_knapsack() -> None:
|
||||||
for solver_factory in [GurobiSolver]:
|
for solver_factory in [GurobiSolver]:
|
||||||
solver = solver_factory()
|
solver = solver_factory()
|
||||||
instance = get_knapsack_instance(solver)
|
instance = solver.build_test_instance_knapsack()
|
||||||
model = instance.to_model()
|
model = instance.to_model()
|
||||||
solver.set_instance(instance, model)
|
solver.set_instance(instance, model)
|
||||||
FeaturesExtractor(solver).extract(instance)
|
FeaturesExtractor(solver).extract(instance)
|
||||||
|
|||||||
Reference in New Issue
Block a user