Source code for hots.core.interfaces

# hots/core/interfaces.py

"""HOTS core interfaces: plugin base classes."""

from abc import ABC, abstractmethod
from typing import Any

import pandas as pd


[docs] class ClusteringPlugin(ABC): """Interface for clustering plugins."""
[docs] @abstractmethod def fit(self, df: pd.DataFrame) -> pd.Series: """Perform clustering and return labels.""" pass
[docs] class OptimizationPlugin(ABC): """Interface for optimization backends (Pyomo, OR-Tools, ...)."""
[docs] @abstractmethod def build(self, *, u_mat=None, w_mat=None, v_mat=None, dv_mat=None): """Create and return a model handle (e.g., a Pyomo model wrapper).""" pass
[docs] @abstractmethod def solve(self, *, solver=None): """Solve the problem using current data.""" pass
[docs] class ConnectorPlugin(ABC): """Interface for connector plugins."""
[docs] @abstractmethod def apply_moves(self, moves: Any) -> None: """Apply relocation moves to the target environment.""" pass
[docs] class ProblemPlugin(ABC): """Interface for domain‑specific problem plugins (placement, allocation, etc.)."""
[docs] @abstractmethod def adjust(self, solution: Any, **kwargs) -> Any: """ Given an optimization solution (and any auxiliary data), return an adjusted solution. """ pass
[docs] @abstractmethod def initial( self, labels: pd.Series, df_indiv: pd.DataFrame, df_host: pd.DataFrame, ) -> list[dict[str, Any]]: """ Produce the initial problem solution if needed. :param labels: cluster labels from initial clustering :param df_indiv: individual‐level data :param df_host: host‐level data :return: list of move dicts to apply """ pass