From 6330354c476b1ca18eb5cc933c96de1ef9ecc1bf Mon Sep 17 00:00:00 2001 From: Alinson S Xavier Date: Thu, 8 Apr 2021 07:50:16 -0500 Subject: [PATCH] Remove EnforceOverrides; automatically convert np.ndarray features --- CHANGELOG.md | 2 -- miplearn/__init__.py | 10 +++++++--- miplearn/components/component.py | 2 +- miplearn/features.py | 7 +++++++ miplearn/instance/base.py | 2 +- miplearn/solvers/internal.py | 2 +- 6 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0abce9..b849f8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,8 +28,6 @@ def get_variable_category(self, var_name: str) -> Optional[Hashable]: pass ```` -- Features are now represented as a list of floating point numbers, as indicated in the snippet above. This change was required for performance reasons. Returning numpy arrays is no longer supported, and raises an error. - - Internal solvers must now be specified as objects, instead of strings. For example, ```python solver = LearningSolver( diff --git a/miplearn/__init__.py b/miplearn/__init__.py index cb32eea..7360cfd 100644 --- a/miplearn/__init__.py +++ b/miplearn/__init__.py @@ -13,6 +13,13 @@ from .components.dynamic_user_cuts import UserCutsComponent from .components.objective import ObjectiveValueComponent from .components.primal import PrimalSolutionComponent from .components.static_lazy import StaticLazyConstraintsComponent +from .features import ( + Features, + TrainingSample, + ConstraintFeatures, + VariableFeatures, + InstanceFeatures, +) from .instance.base import Instance from .instance.picklegz import ( PickleGzInstance, @@ -27,6 +34,3 @@ from .solvers.learning import LearningSolver from .solvers.pyomo.base import BasePyomoSolver from .solvers.pyomo.cplex import CplexPyomoSolver from .solvers.pyomo.gurobi import GurobiPyomoSolver - -# noinspection PyUnresolvedReferences -from overrides import overrides diff --git a/miplearn/components/component.py b/miplearn/components/component.py index 6f4d87c..23a75db 100644 --- a/miplearn/components/component.py +++ b/miplearn/components/component.py @@ -16,7 +16,7 @@ if TYPE_CHECKING: # noinspection PyMethodMayBeStatic -class Component(EnforceOverrides): +class Component: """ A Component is an object which adds functionality to a LearningSolver. diff --git a/miplearn/features.py b/miplearn/features.py index 2a5ae53..02ee586 100644 --- a/miplearn/features.py +++ b/miplearn/features.py @@ -8,6 +8,7 @@ from dataclasses import dataclass from typing import TYPE_CHECKING, Dict, Optional, Set, List, Hashable from miplearn.types import Solution, VariableName, Category +import numpy as np if TYPE_CHECKING: from miplearn.solvers.internal import InternalSolver @@ -83,6 +84,8 @@ class FeaturesExtractor: f"Found {type(category).__name__} instead for var={var_name}." ) user_features = instance.get_variable_features(var_name) + if isinstance(user_features, np.ndarray): + user_features = user_features.tolist() assert isinstance(user_features, list), ( f"Variable features must be a list. " f"Found {type(user_features).__name__} instead for " @@ -115,6 +118,8 @@ class FeaturesExtractor: f"Found {type(category).__name__} instead for cid={cid}.", ) user_features = instance.get_constraint_features(cid) + if isinstance(user_features, np.ndarray): + user_features = user_features.tolist() assert isinstance(user_features, list), ( f"Constraint features must be a list. " f"Found {type(user_features).__name__} instead for cid={cid}." @@ -141,6 +146,8 @@ class FeaturesExtractor: ) -> InstanceFeatures: assert features.constraints is not None user_features = instance.get_instance_features() + if isinstance(user_features, np.ndarray): + user_features = user_features.tolist() assert isinstance(user_features, list), ( f"Instance features must be a list. " f"Found {type(user_features).__name__} instead." diff --git a/miplearn/instance/base.py b/miplearn/instance/base.py index 4a9d81b..2a963d0 100644 --- a/miplearn/instance/base.py +++ b/miplearn/instance/base.py @@ -15,7 +15,7 @@ logger = logging.getLogger(__name__) # noinspection PyMethodMayBeStatic -class Instance(ABC, EnforceOverrides): +class Instance(ABC): """ Abstract class holding all the data necessary to generate a concrete model of the proble. diff --git a/miplearn/solvers/internal.py b/miplearn/solvers/internal.py index 7640f1b..067b1e6 100644 --- a/miplearn/solvers/internal.py +++ b/miplearn/solvers/internal.py @@ -24,7 +24,7 @@ from miplearn.types import ( logger = logging.getLogger(__name__) -class InternalSolver(ABC, EnforceOverrides): +class InternalSolver(ABC): """ Abstract class representing the MIP solver used internally by LearningSolver. """