# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization # Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. # Released under the modified BSD license. See COPYING.md for more details. import logging from abc import ABC, abstractmethod logger = logging.getLogger(__name__) class InternalSolver(ABC): """ Abstract class representing the MIP solver used internally by LearningSolver. """ @abstractmethod def solve_lp(self, tee=False): """ Solves the LP relaxation of the currently loaded instance. After this method finishes, the solution can be retrieved by calling `get_solution`. Parameters ---------- tee: bool If true, prints the solver log to the screen. Returns ------- dict A dictionary of solver statistics containing the following keys: "Optimal value". """ pass @abstractmethod def get_solution(self): """ Returns current solution found by the solver. If called after `solve`, returns the best primal solution found during the search. If called after `solve_lp`, returns the optimal solution to the LP relaxation. The solution is a dictionary `sol`, where the optimal value of `var[idx]` is given by `sol[var][idx]`. """ pass @abstractmethod def set_warm_start(self, solution): """ Sets the warm start to be used by the solver. The solution should be a dictionary following the same format as the one produced by `get_solution`. Only one warm start is supported. Calling this function when a warm start already exists will remove the previous warm start. """ pass @abstractmethod def clear_warm_start(self): """ Removes any existing warm start from the solver. """ pass @abstractmethod def set_instance(self, instance, model=None): """ Loads the given instance into the solver. Parameters ---------- instance: miplearn.Instance The instance to be loaded. model: The concrete optimization model corresponding to this instance (e.g. JuMP.Model or pyomo.core.ConcreteModel). If not provided, it will be generated by calling `instance.to_model()`. """ pass @abstractmethod def fix(self, solution): """ Fixes the values of a subset of decision variables. The values should be provided in the dictionary format generated by `get_solution`. Missing values in the solution indicate variables that should be left free. """ pass @abstractmethod def add_constraint(self, constraint): """ Adds a single constraint to the model. """ pass @abstractmethod def solve(self, tee=False): """ Solves the currently loaded instance. After this method finishes, the best solution found can be retrieved by calling `get_solution`. Parameters ---------- tee: bool If true, prints the solver log to the screen. Returns ------- dict A dictionary of solver statistics containing the following keys: "Lower bound", "Upper bound", "Wallclock time", "Nodes", "Sense", "Log" and "Warm start value". """ pass @abstractmethod def set_threads(self, threads): pass @abstractmethod def set_time_limit(self, time_limit): pass @abstractmethod def set_node_limit(self, node_limit): pass @abstractmethod def set_gap_tolerance(self, gap_tolerance): pass