Source code for VeraGridEngine.Utils.MIP.mip_interface_template

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0

"""
This module abstracts the synthax of PuLP out
so that in the future it can be exchanged with some
other solver interface easily
"""
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import Any, Callable, Iterable, List, Tuple, Union
from VeraGridEngine.enumerations import MIPSolvers
from VeraGridEngine.basic_structures import Logger


[docs] class AbstractLpModel(ABC): """ Abstract base class for LP/MIP models. """ __slots__ = ( "name", "solver_type", "logger", "relaxed_slacks", "originally_infeasible", ) OPTIMAL: Any INFINITY: float = 1e20 def __init__(self, solver_type: MIPSolvers, name: str): self.name = name self.solver_type = solver_type self.logger = Logger() self.relaxed_slacks: List[Tuple[int, Any, float]] = [] self.originally_infeasible: bool = False # --- Abstract interface methods -------------------------------------------
[docs] @staticmethod @abstractmethod def set_var_bounds(var: Any, lb: float, ub: float): """Modify variable bounds."""
[docs] @abstractmethod def add_int(self, lb: int, ub: int, name: str = "") -> Any: """Add an integer variable."""
[docs] @abstractmethod def add_var(self, lb: float, ub: float, name: str = "") -> Any: """Add a continuous variable."""
[docs] @abstractmethod def add_bin(self, name: str = "") -> Any: """ add binary variable. """
[docs] @abstractmethod def add_cst(self, cst: Any, name: str = "") -> Any: """Add a constraint."""
[docs] @staticmethod @abstractmethod def sum(exprs: Iterable) -> Any: """Sum of expressions."""
[docs] @abstractmethod def minimize(self, obj_function: Any): """Define minimization objective."""
[docs] @abstractmethod def solve(self, robust: bool = False, show_logs: bool = False, progress_text: Callable[[str], None] | None = None) -> int: """Solve the optimization problem."""
[docs] @abstractmethod def fobj_value(self) -> float: """Get the objective value."""
[docs] @staticmethod @abstractmethod def get_value(x: Any) -> float: """Return the numerical value of a variable/expression."""
[docs] @staticmethod @abstractmethod def get_dual_value(x: Any) -> float: """Return the dual value of a constraint."""
[docs] @abstractmethod def status2string(self, stat: Any) -> str: """Convert solver status to readable string."""
# --- Optional helper methods ---------------------------------------------
[docs] @abstractmethod def save_model(self, file_name: str): """Export the model to LP/MPS for debugging."""
[docs] @abstractmethod def is_mip(self) -> bool: """Return True if model has integer variables."""
[docs] @abstractmethod def model_as_string(self) -> str: """Return model string representation (LP)"""