mirror of
https://github.com/ANL-CEEESA/MIPLearn.git
synced 2025-12-06 09:28:51 -06:00
MIPLearn v0.3
This commit is contained in:
0
tests/components/primal/__init__.py
Normal file
0
tests/components/primal/__init__.py
Normal file
26
tests/components/primal/test_expert.py
Normal file
26
tests/components/primal/test_expert.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||
# Copyright (C) 2020-2022, UChicago Argonne, LLC. All rights reserved.
|
||||
# Released under the modified BSD license. See COPYING.md for more details.
|
||||
from typing import List, Dict, Any
|
||||
from unittest.mock import Mock
|
||||
|
||||
from miplearn.components.primal.actions import SetWarmStart, FixVariables
|
||||
from miplearn.components.primal.expert import ExpertPrimalComponent
|
||||
|
||||
|
||||
def test_expert(multiknapsack_h5: List[str]) -> None:
|
||||
model = Mock()
|
||||
stats: Dict[str, Any] = {}
|
||||
comp = ExpertPrimalComponent(action=SetWarmStart())
|
||||
comp.before_mip(multiknapsack_h5[0], model, stats)
|
||||
model.set_warm_starts.assert_called()
|
||||
names, starts, _ = model.set_warm_starts.call_args.args
|
||||
assert names.shape == (100,)
|
||||
assert starts.shape == (1, 100)
|
||||
|
||||
comp = ExpertPrimalComponent(action=FixVariables())
|
||||
comp.before_mip(multiknapsack_h5[0], model, stats)
|
||||
model.fix_variables.assert_called()
|
||||
names, v, _ = model.fix_variables.call_args.args
|
||||
assert names.shape == (100,)
|
||||
assert v.shape == (100,)
|
||||
51
tests/components/primal/test_indep.py
Normal file
51
tests/components/primal/test_indep.py
Normal file
@@ -0,0 +1,51 @@
|
||||
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||
# Copyright (C) 2020-2022, UChicago Argonne, LLC. All rights reserved.
|
||||
# Released under the modified BSD license. See COPYING.md for more details.
|
||||
from typing import List, Dict, Any
|
||||
from unittest.mock import Mock, call
|
||||
|
||||
from sklearn.dummy import DummyClassifier
|
||||
|
||||
from miplearn.components.primal.actions import SetWarmStart
|
||||
from miplearn.components.primal.indep import IndependentVarsPrimalComponent
|
||||
from miplearn.extractors.fields import H5FieldsExtractor
|
||||
|
||||
|
||||
def test_indep(multiknapsack_h5: List[str]) -> None:
|
||||
# Create and fit component
|
||||
clone_fn = Mock(return_value=Mock(wraps=DummyClassifier()))
|
||||
comp = IndependentVarsPrimalComponent(
|
||||
base_clf="dummy",
|
||||
extractor=H5FieldsExtractor(var_fields=["lp_var_values"]),
|
||||
clone_fn=clone_fn,
|
||||
action=SetWarmStart(),
|
||||
)
|
||||
comp.fit(multiknapsack_h5)
|
||||
|
||||
# Should call clone 100 times and store the 100 classifiers
|
||||
clone_fn.assert_has_calls([call("dummy") for _ in range(100)])
|
||||
assert len(comp.clf_) == 100
|
||||
|
||||
for v in [b"x[0]", b"x[1]"]:
|
||||
# Should pass correct data to fit
|
||||
comp.clf_[v].fit.assert_called()
|
||||
x, y = comp.clf_[v].fit.call_args.args
|
||||
assert x.shape == (3, 1)
|
||||
assert y.shape == (3,)
|
||||
|
||||
# Call before-mip
|
||||
stats: Dict[str, Any] = {}
|
||||
model = Mock()
|
||||
comp.before_mip(multiknapsack_h5[0], model, stats)
|
||||
|
||||
# Should call predict with correct args
|
||||
for v in [b"x[0]", b"x[1]"]:
|
||||
comp.clf_[v].predict.assert_called()
|
||||
(x_test,) = comp.clf_[v].predict.call_args.args
|
||||
assert x_test.shape == (1, 1)
|
||||
|
||||
# Should set warm starts
|
||||
model.set_warm_starts.assert_called()
|
||||
names, starts, _ = model.set_warm_starts.call_args.args
|
||||
assert len(names) == 100
|
||||
assert starts.shape == (1, 100)
|
||||
46
tests/components/primal/test_joint.py
Normal file
46
tests/components/primal/test_joint.py
Normal file
@@ -0,0 +1,46 @@
|
||||
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||
# Copyright (C) 2020-2022, UChicago Argonne, LLC. All rights reserved.
|
||||
# Released under the modified BSD license. See COPYING.md for more details.
|
||||
from typing import List, Dict, Any
|
||||
from unittest.mock import Mock
|
||||
|
||||
from sklearn.dummy import DummyClassifier
|
||||
|
||||
from miplearn.components.primal.actions import SetWarmStart
|
||||
from miplearn.components.primal.joint import JointVarsPrimalComponent
|
||||
from miplearn.extractors.fields import H5FieldsExtractor
|
||||
|
||||
|
||||
def test_joint(multiknapsack_h5: List[str]) -> None:
|
||||
# Create mock classifier
|
||||
clf = Mock(wraps=DummyClassifier())
|
||||
|
||||
# Create and fit component
|
||||
comp = JointVarsPrimalComponent(
|
||||
clf=clf,
|
||||
extractor=H5FieldsExtractor(instance_fields=["static_var_obj_coeffs"]),
|
||||
action=SetWarmStart(),
|
||||
)
|
||||
comp.fit(multiknapsack_h5)
|
||||
|
||||
# Should call fit method with correct arguments
|
||||
clf.fit.assert_called()
|
||||
x, y = clf.fit.call_args.args
|
||||
assert x.shape == (3, 100)
|
||||
assert y.shape == (3, 100)
|
||||
|
||||
# Call before-mip
|
||||
stats: Dict[str, Any] = {}
|
||||
model = Mock()
|
||||
comp.before_mip(multiknapsack_h5[0], model, stats)
|
||||
|
||||
# Should call predict with correct args
|
||||
clf.predict.assert_called()
|
||||
(x_test,) = clf.predict.call_args.args
|
||||
assert x_test.shape == (1, 100)
|
||||
|
||||
# Should set warm starts
|
||||
model.set_warm_starts.assert_called()
|
||||
names, starts, _ = model.set_warm_starts.call_args.args
|
||||
assert len(names) == 100
|
||||
assert starts.shape == (1, 100)
|
||||
86
tests/components/primal/test_mem.py
Normal file
86
tests/components/primal/test_mem.py
Normal file
@@ -0,0 +1,86 @@
|
||||
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||
# Copyright (C) 2020-2022, UChicago Argonne, LLC. All rights reserved.
|
||||
# Released under the modified BSD license. See COPYING.md for more details.
|
||||
import logging
|
||||
from typing import List, Dict, Any
|
||||
from unittest.mock import Mock
|
||||
|
||||
import numpy as np
|
||||
from sklearn.dummy import DummyClassifier
|
||||
|
||||
from miplearn.components.primal.actions import SetWarmStart
|
||||
from miplearn.components.primal.mem import (
|
||||
MemorizingPrimalComponent,
|
||||
SelectTopSolutions,
|
||||
MergeTopSolutions,
|
||||
)
|
||||
from miplearn.extractors.abstract import FeaturesExtractor
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def test_mem_component(
|
||||
multiknapsack_h5: List[str], default_extractor: FeaturesExtractor
|
||||
) -> None:
|
||||
# Create mock classifier
|
||||
clf = Mock(wraps=DummyClassifier())
|
||||
|
||||
# Create and fit component
|
||||
comp = MemorizingPrimalComponent(
|
||||
clf,
|
||||
extractor=default_extractor,
|
||||
constructor=SelectTopSolutions(2),
|
||||
action=SetWarmStart(),
|
||||
)
|
||||
comp.fit(multiknapsack_h5)
|
||||
|
||||
# Should call fit method with correct arguments
|
||||
clf.fit.assert_called()
|
||||
x, y = clf.fit.call_args.args
|
||||
assert x.shape == (3, 100)
|
||||
assert y.tolist() == [0, 1, 2]
|
||||
|
||||
# Should store solutions
|
||||
assert comp.solutions_ is not None
|
||||
assert comp.solutions_.shape == (3, 100)
|
||||
assert comp.bin_var_names_ is not None
|
||||
assert len(comp.bin_var_names_) == 100
|
||||
|
||||
# Call before-mip
|
||||
stats: Dict[str, Any] = {}
|
||||
model = Mock()
|
||||
comp.before_mip(multiknapsack_h5[0], model, stats)
|
||||
|
||||
# Should call predict_proba with correct args
|
||||
clf.predict_proba.assert_called()
|
||||
(x_test,) = clf.predict_proba.call_args.args
|
||||
assert x_test.shape == (1, 100)
|
||||
|
||||
# Should set warm starts
|
||||
model.set_warm_starts.assert_called()
|
||||
names, starts, _ = model.set_warm_starts.call_args.args
|
||||
assert len(names) == 100
|
||||
assert starts.shape == (2, 100)
|
||||
assert np.all(starts[0, :] == comp.solutions_[0, :])
|
||||
assert np.all(starts[1, :] == comp.solutions_[1, :])
|
||||
|
||||
|
||||
def test_merge_top_solutions() -> None:
|
||||
solutions = np.array(
|
||||
[
|
||||
[0, 1, 0, 0],
|
||||
[0, 1, 0, 1],
|
||||
[0, 1, 1, 1],
|
||||
[0, 1, 1, 1],
|
||||
[1, 1, 1, 1],
|
||||
]
|
||||
)
|
||||
y_proba = np.array([0.25, 0.25, 0.25, 0.25, 0])
|
||||
starts = MergeTopSolutions(k=4, thresholds=[0.25, 0.75]).construct(
|
||||
y_proba, solutions
|
||||
)
|
||||
assert starts.shape == (1, 4)
|
||||
assert starts[0, 0] == 0
|
||||
assert starts[0, 1] == 1
|
||||
assert np.isnan(starts[0, 2])
|
||||
assert starts[0, 3] == 1
|
||||
Reference in New Issue
Block a user