From ca925119b365104727c2f61651ca93537e2491ca Mon Sep 17 00:00:00 2001 From: "Alinson S. Xavier" Date: Wed, 4 Aug 2021 13:35:16 -0500 Subject: [PATCH] Add static_ prefix to all static features --- miplearn/components/dynamic_common.py | 2 +- miplearn/components/objective.py | 2 +- miplearn/components/primal.py | 14 +++---- miplearn/components/static_lazy.py | 12 +++--- miplearn/features/extractor.py | 59 +++++++++++++-------------- miplearn/solvers/internal.py | 10 ++--- tests/components/test_dynamic_lazy.py | 6 +-- tests/components/test_primal.py | 8 ++-- tests/components/test_static_lazy.py | 10 ++--- tests/features/test_extractor.py | 38 +++++++++-------- 10 files changed, 82 insertions(+), 79 deletions(-) diff --git a/miplearn/components/dynamic_common.py b/miplearn/components/dynamic_common.py index e319a01..ce78dd2 100644 --- a/miplearn/components/dynamic_common.py +++ b/miplearn/components/dynamic_common.py @@ -52,7 +52,7 @@ class DynamicConstraintsComponent(Component): cids: Dict[str, List[str]] = {} constr_categories_dict = instance.get_constraint_categories() constr_features_dict = instance.get_constraint_features() - instance_features = sample.get_vector("instance_features") + instance_features = sample.get_vector("static_instance_features") assert instance_features is not None for cid in self.known_cids: # Initialize categories diff --git a/miplearn/components/objective.py b/miplearn/components/objective.py index 707d699..cc4e30c 100644 --- a/miplearn/components/objective.py +++ b/miplearn/components/objective.py @@ -79,7 +79,7 @@ class ObjectiveValueComponent(Component): ) -> Tuple[Dict[str, List[List[float]]], Dict[str, List[List[float]]]]: lp_instance_features = sample.get_vector("lp_instance_features") if lp_instance_features is None: - lp_instance_features = sample.get_vector("instance_features") + lp_instance_features = sample.get_vector("static_instance_features") assert lp_instance_features is not None # Features diff --git a/miplearn/components/primal.py b/miplearn/components/primal.py index 5b73f8c..50c7991 100644 --- a/miplearn/components/primal.py +++ b/miplearn/components/primal.py @@ -95,8 +95,8 @@ class PrimalSolutionComponent(Component): ) def sample_predict(self, sample: Sample) -> Solution: - var_names = sample.get_vector("var_names") - var_categories = sample.get_vector("var_categories") + var_names = sample.get_vector("static_var_names") + var_categories = sample.get_vector("static_var_categories") assert var_names is not None assert var_categories is not None @@ -142,13 +142,13 @@ class PrimalSolutionComponent(Component): ) -> Tuple[Dict[Category, List[List[float]]], Dict[Category, List[List[float]]]]: x: Dict = {} y: Dict = {} - instance_features = sample.get_vector("instance_features") + instance_features = sample.get_vector("static_instance_features") mip_var_values = sample.get_vector("mip_var_values") var_features = sample.get_vector_list("lp_var_features") - var_names = sample.get_vector("var_names") - var_categories = sample.get_vector("var_categories") + var_names = sample.get_vector("static_var_names") + var_categories = sample.get_vector("static_var_categories") if var_features is None: - var_features = sample.get_vector_list("var_features") + var_features = sample.get_vector_list("static_var_features") assert instance_features is not None assert var_features is not None assert var_names is not None @@ -188,7 +188,7 @@ class PrimalSolutionComponent(Component): sample: Sample, ) -> Dict[str, Dict[str, float]]: mip_var_values = sample.get_vector("mip_var_values") - var_names = sample.get_vector("var_names") + var_names = sample.get_vector("static_var_names") assert mip_var_values is not None assert var_names is not None diff --git a/miplearn/components/static_lazy.py b/miplearn/components/static_lazy.py index 7022f04..99aba1c 100644 --- a/miplearn/components/static_lazy.py +++ b/miplearn/components/static_lazy.py @@ -75,7 +75,7 @@ class StaticLazyConstraintsComponent(Component): sample: Sample, ) -> None: assert solver.internal_solver is not None - static_lazy_count = sample.get_scalar("static_lazy_count") + static_lazy_count = sample.get_scalar("static_constr_lazy_count") assert static_lazy_count is not None logger.info("Predicting violated (static) lazy constraints...") @@ -204,14 +204,14 @@ class StaticLazyConstraintsComponent(Component): x: Dict[str, List[List[float]]] = {} y: Dict[str, List[List[float]]] = {} cids: Dict[str, List[str]] = {} - instance_features = sample.get_vector("instance_features") + instance_features = sample.get_vector("static_instance_features") constr_features = sample.get_vector_list("lp_constr_features") - constr_names = sample.get_vector("constr_names") - constr_categories = sample.get_vector("constr_categories") - constr_lazy = sample.get_vector("constr_lazy") + constr_names = sample.get_vector("static_constr_names") + constr_categories = sample.get_vector("static_constr_categories") + constr_lazy = sample.get_vector("static_constr_lazy") lazy_enforced = sample.get_set("lazy_enforced") if constr_features is None: - constr_features = sample.get_vector_list("constr_features") + constr_features = sample.get_vector_list("static_constr_features") assert instance_features is not None assert constr_features is not None diff --git a/miplearn/features/extractor.py b/miplearn/features/extractor.py index d466a72..74c359d 100644 --- a/miplearn/features/extractor.py +++ b/miplearn/features/extractor.py @@ -33,31 +33,31 @@ class FeaturesExtractor: ) -> None: variables = solver.get_variables(with_static=True) constraints = solver.get_constraints(with_static=True, with_lhs=self.with_lhs) - sample.put_vector("var_lower_bounds", variables.lower_bounds) - sample.put_vector("var_names", variables.names) - sample.put_vector("var_obj_coeffs", variables.obj_coeffs) - sample.put_vector("var_types", variables.types) - sample.put_vector("var_upper_bounds", variables.upper_bounds) - sample.put_vector("constr_names", constraints.names) - # sample.put("constr_lhs", constraints.lhs) - sample.put_vector("constr_rhs", constraints.rhs) - sample.put_vector("constr_senses", constraints.senses) + sample.put_vector("static_var_lower_bounds", variables.lower_bounds) + sample.put_vector("static_var_names", variables.names) + sample.put_vector("static_var_obj_coeffs", variables.obj_coeffs) + sample.put_vector("static_var_types", variables.types) + sample.put_vector("static_var_upper_bounds", variables.upper_bounds) + sample.put_vector("static_constr_names", constraints.names) + # sample.put("static_constr_lhs", constraints.lhs) + sample.put_vector("static_constr_rhs", constraints.rhs) + sample.put_vector("static_constr_senses", constraints.senses) vars_features_user, var_categories = self._extract_user_features_vars( instance, sample ) - sample.put_vector("var_categories", var_categories) + sample.put_vector("static_var_categories", var_categories) self._extract_user_features_constrs(instance, sample) self._extract_user_features_instance(instance, sample) alw17 = self._extract_var_features_AlvLouWeh2017(sample) sample.put_vector_list( - "var_features", + "static_var_features", self._combine( [ alw17, vars_features_user, - sample.get_vector("var_lower_bounds"), - sample.get_vector("var_obj_coeffs"), - sample.get_vector("var_upper_bounds"), + sample.get_vector("static_var_lower_bounds"), + sample.get_vector("static_var_obj_coeffs"), + sample.get_vector("static_var_upper_bounds"), ], ), ) @@ -97,10 +97,7 @@ class FeaturesExtractor: sample.get_vector("lp_var_sa_ub_down"), sample.get_vector("lp_var_sa_ub_up"), sample.get_vector("lp_var_values"), - sample.get_vector_list("var_features_user"), - sample.get_vector("var_lower_bounds"), - sample.get_vector("var_obj_coeffs"), - sample.get_vector("var_upper_bounds"), + sample.get_vector_list("static_var_features"), ], ), ) @@ -108,7 +105,7 @@ class FeaturesExtractor: "lp_constr_features", self._combine( [ - sample.get_vector_list("constr_features"), + sample.get_vector_list("static_constr_features"), sample.get_vector("lp_constr_dual_values"), sample.get_vector("lp_constr_sa_rhs_down"), sample.get_vector("lp_constr_sa_rhs_up"), @@ -116,11 +113,11 @@ class FeaturesExtractor: ], ), ) - instance_features = sample.get_vector("instance_features") - assert instance_features is not None + static_instance_features = sample.get_vector("static_instance_features") + assert static_instance_features is not None sample.put_vector( "lp_instance_features", - instance_features + static_instance_features + [ sample.get_scalar("lp_value"), sample.get_scalar("lp_wallclock_time"), @@ -146,7 +143,7 @@ class FeaturesExtractor: user_features: List[Optional[List[float]]] = [] var_features_dict = instance.get_variable_features() var_categories_dict = instance.get_variable_categories() - var_names = sample.get_vector("var_names") + var_names = sample.get_vector("static_var_names") assert var_names is not None for (i, var_name) in enumerate(var_names): if var_name not in var_categories_dict: @@ -190,7 +187,7 @@ class FeaturesExtractor: lazy: List[bool] = [] constr_categories_dict = instance.get_constraint_categories() constr_features_dict = instance.get_constraint_features() - constr_names = sample.get_vector("constr_names") + constr_names = sample.get_vector("static_constr_names") assert constr_names is not None for (cidx, cname) in enumerate(constr_names): @@ -226,9 +223,9 @@ class FeaturesExtractor: lazy.append(instance.is_constraint_lazy(cname)) else: lazy.append(False) - sample.put_vector_list("constr_features", user_features) - sample.put_vector("constr_lazy", lazy) - sample.put_vector("constr_categories", categories) + sample.put_vector_list("static_constr_features", user_features) + sample.put_vector("static_constr_lazy", lazy) + sample.put_vector("static_constr_categories", categories) def _extract_user_features_instance( self, @@ -247,15 +244,15 @@ class FeaturesExtractor: f"Instance features must be a list of numbers. " f"Found {type(v).__name__} instead." ) - constr_lazy = sample.get_vector("constr_lazy") + constr_lazy = sample.get_vector("static_constr_lazy") assert constr_lazy is not None - sample.put_vector("instance_features", user_features) - sample.put_scalar("static_lazy_count", sum(constr_lazy)) + sample.put_vector("static_instance_features", user_features) + sample.put_scalar("static_constr_lazy_count", sum(constr_lazy)) # Alvarez, A. M., Louveaux, Q., & Wehenkel, L. (2017). A machine learning-based # approximation of strong branching. INFORMS Journal on Computing, 29(1), 185-195. def _extract_var_features_AlvLouWeh2017(self, sample: Sample) -> List: - obj_coeffs = sample.get_vector("var_obj_coeffs") + obj_coeffs = sample.get_vector("static_var_obj_coeffs") obj_sa_down = sample.get_vector("lp_var_sa_obj_down") obj_sa_up = sample.get_vector("lp_var_sa_obj_up") values = sample.get_vector(f"lp_var_values") diff --git a/miplearn/solvers/internal.py b/miplearn/solvers/internal.py index 82191c6..c462797 100644 --- a/miplearn/solvers/internal.py +++ b/miplearn/solvers/internal.py @@ -82,13 +82,13 @@ class Constraints: return Constraints( basis_status=sample.get_vector("lp_constr_basis_status"), dual_values=sample.get_vector("lp_constr_dual_values"), - lazy=sample.get_vector("constr_lazy"), - # lhs=sample.get_vector("constr_lhs"), - names=sample.get_vector("constr_names"), - rhs=sample.get_vector("constr_rhs"), + lazy=sample.get_vector("static_constr_lazy"), + # lhs=sample.get_vector("static_constr_lhs"), + names=sample.get_vector("static_constr_names"), + rhs=sample.get_vector("static_constr_rhs"), sa_rhs_down=sample.get_vector("lp_constr_sa_rhs_down"), sa_rhs_up=sample.get_vector("lp_constr_sa_rhs_up"), - senses=sample.get_vector("constr_senses"), + senses=sample.get_vector("static_constr_senses"), slacks=sample.get_vector("lp_constr_slacks"), ) diff --git a/tests/components/test_dynamic_lazy.py b/tests/components/test_dynamic_lazy.py index 6d469d5..037b904 100644 --- a/tests/components/test_dynamic_lazy.py +++ b/tests/components/test_dynamic_lazy.py @@ -25,13 +25,13 @@ def training_instances() -> List[Instance]: MemorySample( { "lazy_enforced": {"c1", "c2"}, - "instance_features": [5.0], + "static_instance_features": [5.0], }, ), MemorySample( { "lazy_enforced": {"c2", "c3"}, - "instance_features": [5.0], + "static_instance_features": [5.0], }, ), ] @@ -56,7 +56,7 @@ def training_instances() -> List[Instance]: MemorySample( { "lazy_enforced": {"c3", "c4"}, - "instance_features": [8.0], + "static_instance_features": [8.0], }, ) ] diff --git a/tests/components/test_primal.py b/tests/components/test_primal.py index d58a4e6..a5958ac 100644 --- a/tests/components/test_primal.py +++ b/tests/components/test_primal.py @@ -22,11 +22,11 @@ from miplearn.solvers.tests import assert_equals def sample() -> Sample: sample = MemorySample( { - "var_names": ["x[0]", "x[1]", "x[2]", "x[3]"], - "var_categories": ["default", None, "default", "default"], + "static_var_names": ["x[0]", "x[1]", "x[2]", "x[3]"], + "static_var_categories": ["default", None, "default", "default"], "mip_var_values": [0.0, 1.0, 1.0, 0.0], - "instance_features": [5.0], - "var_features": [ + "static_instance_features": [5.0], + "static_var_features": [ [0.0, 0.0], None, [1.0, 0.0], diff --git a/tests/components/test_static_lazy.py b/tests/components/test_static_lazy.py index b0b2664..6ef4ec9 100644 --- a/tests/components/test_static_lazy.py +++ b/tests/components/test_static_lazy.py @@ -24,16 +24,16 @@ from miplearn.types import ( def sample() -> Sample: sample = MemorySample( { - "constr_categories": [ + "static_constr_categories": [ "type-a", "type-a", "type-a", "type-b", "type-b", ], - "constr_lazy": [True, True, True, True, False], - "constr_names": ["c1", "c2", "c3", "c4", "c5"], - "instance_features": [5.0], + "static_constr_lazy": [True, True, True, True, False], + "static_constr_names": ["c1", "c2", "c3", "c4", "c5"], + "static_instance_features": [5.0], "lazy_enforced": {"c1", "c2", "c4"}, "lp_constr_features": [ [1.0, 1.0], @@ -42,7 +42,7 @@ def sample() -> Sample: [1.0, 4.0, 0.0], None, ], - "static_lazy_count": 4, + "static_constr_lazy_count": 4, }, ) return sample diff --git a/tests/features/test_extractor.py b/tests/features/test_extractor.py index d746277..1053b4b 100644 --- a/tests/features/test_extractor.py +++ b/tests/features/test_extractor.py @@ -24,21 +24,27 @@ def test_knapsack() -> None: # after-load # ------------------------------------------------------- extractor.extract_after_load_features(instance, solver, sample) - assert_equals(sample.get_vector("var_names"), ["x[0]", "x[1]", "x[2]", "x[3]", "z"]) - assert_equals(sample.get_vector("var_lower_bounds"), [0.0, 0.0, 0.0, 0.0, 0.0]) assert_equals( - sample.get_vector("var_obj_coeffs"), [505.0, 352.0, 458.0, 220.0, 0.0] + sample.get_vector("static_var_names"), ["x[0]", "x[1]", "x[2]", "x[3]", "z"] ) - assert_equals(sample.get_vector("var_types"), ["B", "B", "B", "B", "C"]) - assert_equals(sample.get_vector("var_upper_bounds"), [1.0, 1.0, 1.0, 1.0, 67.0]) assert_equals( - sample.get_vector("var_categories"), + sample.get_vector("static_var_lower_bounds"), [0.0, 0.0, 0.0, 0.0, 0.0] + ) + assert_equals( + sample.get_vector("static_var_obj_coeffs"), [505.0, 352.0, 458.0, 220.0, 0.0] + ) + assert_equals(sample.get_vector("static_var_types"), ["B", "B", "B", "B", "C"]) + assert_equals( + sample.get_vector("static_var_upper_bounds"), [1.0, 1.0, 1.0, 1.0, 67.0] + ) + assert_equals( + sample.get_vector("static_var_categories"), ["default", "default", "default", "default", None], ) - assert sample.get_vector_list("var_features") is not None - assert_equals(sample.get_vector("constr_names"), ["eq_capacity"]) + assert sample.get_vector_list("static_var_features") is not None + assert_equals(sample.get_vector("static_constr_names"), ["eq_capacity"]) # assert_equals( - # sample.get_vector("constr_lhs"), + # sample.get_vector("static_constr_lhs"), # [ # [ # ("x[0]", 23.0), @@ -49,13 +55,13 @@ def test_knapsack() -> None: # ], # ], # ) - assert_equals(sample.get_vector("constr_rhs"), [0.0]) - assert_equals(sample.get_vector("constr_senses"), ["="]) - assert_equals(sample.get_vector("constr_features"), [None]) - assert_equals(sample.get_vector("constr_categories"), ["eq_capacity"]) - assert_equals(sample.get_vector("constr_lazy"), [False]) - assert_equals(sample.get_vector("instance_features"), [67.0, 21.75]) - assert_equals(sample.get_scalar("static_lazy_count"), 0) + assert_equals(sample.get_vector("static_constr_rhs"), [0.0]) + assert_equals(sample.get_vector("static_constr_senses"), ["="]) + assert_equals(sample.get_vector("static_constr_features"), [None]) + assert_equals(sample.get_vector("static_constr_categories"), ["eq_capacity"]) + assert_equals(sample.get_vector("static_constr_lazy"), [False]) + assert_equals(sample.get_vector("static_instance_features"), [67.0, 21.75]) + assert_equals(sample.get_scalar("static_constr_lazy_count"), 0) # after-lp # -------------------------------------------------------