boundml.solvers
141class DefaultScipSolver(ScipSolver): 142 """ 143 Default scip solver. 144 Solve the instances based on the given scip parameters. 145 """ 146 def __init__(self, branching_strategy, *args, **kwargs): 147 """ 148 Parameters 149 ---------- 150 branching_strategy : str 151 Branching strategy to use. Must be a default SCIP strategy, or a strategy included in the Model using 152 the configure callback 153 args : 154 Arguments to build the parent class ScipSolver 155 kwargs : 156 Arguments to build the parent class ScipSolver 157 """ 158 super().__init__(*args, **kwargs) 159 self.branching_strategy = branching_strategy 160 self.state = ( 161 [branching_strategy, *args], 162 kwargs 163 ) 164 165 def build_model(self): 166 super().build_model() 167 self.model.setParam(f"branching/{self.branching_strategy}/priority", 9999999) 168 169 170 def solve(self, instance: str): 171 self.build_model() 172 self.model.readProblem(instance) 173 self.model.optimize() 174 175 def __getstate__(self): 176 return self.state 177 178 def __setstate__(self, state): 179 self.__init__(*state[0], **state[1]) 180 181 def __str__(self): 182 return self.branching_strategy
Default scip solver. Solve the instances based on the given scip parameters.
DefaultScipSolver(branching_strategy, *args, **kwargs)
146 def __init__(self, branching_strategy, *args, **kwargs): 147 """ 148 Parameters 149 ---------- 150 branching_strategy : str 151 Branching strategy to use. Must be a default SCIP strategy, or a strategy included in the Model using 152 the configure callback 153 args : 154 Arguments to build the parent class ScipSolver 155 kwargs : 156 Arguments to build the parent class ScipSolver 157 """ 158 super().__init__(*args, **kwargs) 159 self.branching_strategy = branching_strategy 160 self.state = ( 161 [branching_strategy, *args], 162 kwargs 163 )
Parameters
- branching_strategy (str): Branching strategy to use. Must be a default SCIP strategy, or a strategy included in the Model using the configure callback
- args :: Arguments to build the parent class ScipSolver
- kwargs :: Arguments to build the parent class ScipSolver
12class ModularSolver(ScipSolver): 13 """ 14 A ModularSolver is ScipSolver that is parametrized with a list of Component 15 """ 16 17 def __init__(self, *components: Component, scip_params = None, configure: Callable[[Model], None] = None): 18 """ 19 Parameters 20 ---------- 21 components : [Component] 22 List of components that parametrized the solver. During a solving process, they are called depending on 23 their subtypes (e.g. BranchingComponent are called before making a branching strategy). If several 24 components have the same subtypes, they are called in the order they are given. Only the first component 25 of each subtype is allowed to perform an action (with passive=False). The other must remain passive. 26 scip_params : dict, optional 27 Dictionary of parameters to pass to the scip solver. 28 configure : Callable[[Model], None], optional 29 Callback function to configure the solver (e.g. add branching strategies, ...) 30 """ 31 super().__init__(scip_params, configure) 32 33 self.components = ComponentList(list(components)) 34 self.branching_components = [] 35 36 for component in components: 37 if isinstance(component, BranchingComponent): 38 self.branching_components.append(component) 39 40 41 42 def build_model(self): 43 super().build_model() 44 branchrule = BoundmlBranchrule(self.model, self.branching_components) 45 self.model.includeBranchrule( 46 branchrule, 47 "boundml", 48 "Custom branching rule for ModularSolver", 49 priority=10000000, 50 maxdepth=-1, 51 maxbounddist=1 52 ) 53 54 def solve(self, instance: str): 55 self.build_model() 56 57 self.model.readProblem(instance) 58 59 self.components.reset(self.model) 60 61 self.model.optimize() 62 63 self.components.done(self.model) 64 65 def __getstate__(self): 66 return (self.components, self.scip_params, self.configure) 67 68 def __setstate__(self, state): 69 self.__init__(*state[0], scip_params=state[1], configure=state[2]) 70 71 def __str__(self): 72 return "+".join([str(c) for c in self.components])
A ModularSolver is ScipSolver that is parametrized with a list of Component
ModularSolver( *components: boundml.components.Component, scip_params=None, configure: Callable[[pyscipopt.scip.Model], NoneType] = None)
17 def __init__(self, *components: Component, scip_params = None, configure: Callable[[Model], None] = None): 18 """ 19 Parameters 20 ---------- 21 components : [Component] 22 List of components that parametrized the solver. During a solving process, they are called depending on 23 their subtypes (e.g. BranchingComponent are called before making a branching strategy). If several 24 components have the same subtypes, they are called in the order they are given. Only the first component 25 of each subtype is allowed to perform an action (with passive=False). The other must remain passive. 26 scip_params : dict, optional 27 Dictionary of parameters to pass to the scip solver. 28 configure : Callable[[Model], None], optional 29 Callback function to configure the solver (e.g. add branching strategies, ...) 30 """ 31 super().__init__(scip_params, configure) 32 33 self.components = ComponentList(list(components)) 34 self.branching_components = [] 35 36 for component in components: 37 if isinstance(component, BranchingComponent): 38 self.branching_components.append(component)
Parameters
- components ([Component]): List of components that parametrized the solver. During a solving process, they are called depending on their subtypes (e.g. BranchingComponent are called before making a branching strategy). If several components have the same subtypes, they are called in the order they are given. Only the first component of each subtype is allowed to perform an action (with passive=False). The other must remain passive.
- scip_params (dict, optional): Dictionary of parameters to pass to the scip solver.
- configure (Callable[[Model], None], optional): Callback function to configure the solver (e.g. add branching strategies, ...)
def
solve(self, instance: str):
54 def solve(self, instance: str): 55 self.build_model() 56 57 self.model.readProblem(instance) 58 59 self.components.reset(self.model) 60 61 self.model.optimize() 62 63 self.components.done(self.model)
Solves a instancse that is a file
Parameters
- instance (str): Path to the instance
class
Solver(abc.ABC):
8class Solver(ABC): 9 """ 10 An abstract base class for solvers. 11 """ 12 13 def __init__(self): 14 self.seed = 0 15 16 17 def seed(self, seed): 18 """ 19 Seed used by the underground solver. 20 Parameters 21 ---------- 22 seed : int 23 The new seed 24 """ 25 self.seed = seed 26 27 @abstractmethod 28 def solve(self, instance: str): 29 """ 30 Solves a instancse that is a file 31 Parameters 32 ---------- 33 instance : str 34 Path to the instance 35 """ 36 raise NotImplementedError("Subclasses must implement this method.") 37 38 def solve_model(self, model: Model): 39 """ 40 Solve directly a pyscipopt model. 41 Can work even if the underlying solver is not SCIP, as it only write the corresponding problem to a file in 42 order to use the method solve 43 Parameters 44 ---------- 45 model : Model 46 model to solve. 47 """ 48 model.setParam("display/verblevel", 0) 49 prob_file = tempfile.NamedTemporaryFile(suffix=".lp") 50 model.writeProblem(prob_file.name, verbose=False) 51 52 self.solve(prob_file.name) 53 prob_file.close() 54 55 @abstractmethod 56 def __getitem__(self, item: str) -> float: 57 """ 58 Get an attribute from the solver after a solving process. 59 60 Parameters 61 ---------- 62 item : str 63 Name of the attribute to get. Depends on the subtype of the solver. 64 65 Returns 66 ------- 67 Value of the attribute. 68 """ 69 raise NotImplementedError("Subclasses must implement this method.")
An abstract base class for solvers.
def
seed(self, seed):
17 def seed(self, seed): 18 """ 19 Seed used by the underground solver. 20 Parameters 21 ---------- 22 seed : int 23 The new seed 24 """ 25 self.seed = seed
Seed used by the underground solver.
Parameters
- seed (int): The new seed
@abstractmethod
def
solve(self, instance: str):
27 @abstractmethod 28 def solve(self, instance: str): 29 """ 30 Solves a instancse that is a file 31 Parameters 32 ---------- 33 instance : str 34 Path to the instance 35 """ 36 raise NotImplementedError("Subclasses must implement this method.")
Solves a instancse that is a file
Parameters
- instance (str): Path to the instance
def
solve_model(self, model: pyscipopt.scip.Model):
38 def solve_model(self, model: Model): 39 """ 40 Solve directly a pyscipopt model. 41 Can work even if the underlying solver is not SCIP, as it only write the corresponding problem to a file in 42 order to use the method solve 43 Parameters 44 ---------- 45 model : Model 46 model to solve. 47 """ 48 model.setParam("display/verblevel", 0) 49 prob_file = tempfile.NamedTemporaryFile(suffix=".lp") 50 model.writeProblem(prob_file.name, verbose=False) 51 52 self.solve(prob_file.name) 53 prob_file.close()
Solve directly a pyscipopt model. Can work even if the underlying solver is not SCIP, as it only write the corresponding problem to a file in order to use the method solve
Parameters
- model (Model): model to solve.
71class ScipSolver(Solver): 72 def __init__(self, scip_params: dict = None, configure: Callable[[Model], None] = None): 73 """ 74 Parameters 75 ---------- 76 scip_params : dict, optional 77 Dictionary of parameters to pass to the scip solver. 78 configure : Callable[[Model], None], optional 79 Callback function to configure the solver (e.g. add branching strategies, ...) 80 """ 81 super().__init__() 82 self.scip_params = scip_params or {} 83 self.configure = configure 84 self.model = None 85 86 def build_model(self): 87 self.model = Model() 88 self.set_params(self.scip_params) 89 if self.configure is not None: 90 self.configure(self.model) 91 self.model.setParam("display/verblevel", 0) 92 self.model.setParam("randomization/randomseedshift", self.seed) 93 94 def set_params(self, params): 95 self.scip_params = params 96 97 def __getitem__(self, item: str) -> float: 98 """ 99 Get an attribute from the solver after a solving process. 100 101 Parameters 102 ---------- 103 item : str 104 Name of the attribute to get. Either: 105 time: time in seconds used by the solver 106 nnodes: number of nodes used by the solver 107 obj: Final objective value 108 sol: Best solution found 109 estimate_nnodes: Estimated number of nodes used by the solver to go to optimality 110 111 Returns 112 ------- 113 Value of the attribute. 114 """ 115 match item: 116 case "time": 117 return self.model.getSolvingTime() 118 case "nnodes": 119 # return self.model.getNNodes() 120 return self.model.getNTotalNodes() 121 case "obj": 122 return self.model.getObjVal() 123 case "gap": 124 return self.model.getGap() 125 case "sol": 126 return self.model.getBestSol() 127 case "estimate_nnodes": 128 if self.model.getGap() == 0: 129 return self["nnodes"] 130 else: 131 return self.model.getTreesizeEstimation() 132 case _: 133 raise KeyError 134 135 def __getstate__(self): 136 return self.scip_params, self.configure 137 138 def __setstate__(self, state): 139 self.__init__(*state)
An abstract base class for solvers.
ScipSolver( scip_params: dict = None, configure: Callable[[pyscipopt.scip.Model], NoneType] = None)
72 def __init__(self, scip_params: dict = None, configure: Callable[[Model], None] = None): 73 """ 74 Parameters 75 ---------- 76 scip_params : dict, optional 77 Dictionary of parameters to pass to the scip solver. 78 configure : Callable[[Model], None], optional 79 Callback function to configure the solver (e.g. add branching strategies, ...) 80 """ 81 super().__init__() 82 self.scip_params = scip_params or {} 83 self.configure = configure 84 self.model = None
Parameters
- scip_params (dict, optional): Dictionary of parameters to pass to the scip solver.
- configure (Callable[[Model], None], optional): Callback function to configure the solver (e.g. add branching strategies, ...)