Source code for mealpy.utils.termination

# !/usr/bin/env python
# Created by "Thieu" at 17:29, 13/10/2021 ----------%
#       Email: nguyenthieu2102@gmail.com            %
#       Github: https://github.com/thieu1995        %
# --------------------------------------------------%

[docs]class Termination: """ Define the Stopping Condition (Termination) for the Optimizer Notes ~~~~~ + By default, the stopping condition is maximum generations (epochs/iterations) in Optimizer class. + By using this class, the default termination will be overridden + In general, there are 4 termination cases: FE, MG, ES, TB + FE: Number of Function Evaluation + MG: Maximum Generations / Epochs - This is default in all algorithms + ES: Early Stopping - Same idea in training neural network (If the global best solution not better an epsilon after K epochs then stop the program) + TB: Time Bound - You just want your algorithm run in K seconds. Especially when comparing different algorithms. + Parameters for Termination class + mode (str): FE, MG, ES or TB + quantity (int): value for termination type + problem (dict): dictionary of the termination (contains at least the parameter 'mode' and 'quantity') (Optional) Examples ~~~~~~~~ >>> ## 1st way to define and use termination object >>> import numpy as np >>> from mealpy.swarm_based.PSO import BasePSO >>> >>> def fitness_function(solution): >>> return np.sum(solution**2) >>> >>> problem_dict = { >>> "fit_func": fitness_function, >>> "lb": [-10, -15, -4, -2, -8], >>> "ub": [10, 15, 12, 8, 20], >>> } >>> >>> term_dict = { >>> "mode": "FE", >>> "quantity": 100000 # 100000 number of function evaluation >>> } >>> model1 = BasePSO(problem_dict, epoch=1000, pop_size=50, termination=term_dict) >>> >>> ## 2nd and 3rd ways: >>> from mealpy.utils.termination import Termination >>> >>> term_obj2 = Termination(termination = term_dict) >>> model2 = BasePSO(problem_dict, epoch=1000, pop_size=50, termination=term_obj2) >>> >>> term_obj3 = Termination(termination = term_dict) >>> model3 = BasePSO(problem_dict, epoch=1000, pop_size=50, termination=term_obj3) """ DEFAULT_MAX_MG = 1000 # Maximum number of epochs / generations (Default: 1000 epochs) DEFAULT_MAX_FE = 100000 # Maximum number of function evaluation (Default: 100000 FE) DEFAULT_MAX_TB = 20 # Maximum number of time bound (Default: 20 seconds) DEFAULT_MAX_ES = 20 # Maximum number of early stopping iterations (Default: 20 loops / generations) def __init__(self, **kwargs): self.name = "Maximum Generation" self.mode = "MG" self.quantity = self.DEFAULT_MAX_MG self.exit_flag, self.message = False, "" self.__set_keyword_arguments(kwargs) self.__check_termination(kwargs) def __set_keyword_arguments(self, kwargs): for key, value in kwargs.items(): setattr(self, key, value) def __check_termination(self, kwargs): if ("mode" in kwargs) and ("quantity" in kwargs): self.__check_mode(kwargs["mode"], kwargs["quantity"]) else: if "termination" in kwargs: termination = kwargs["termination"] if type(termination) is dict: if ("mode" in termination) and ("quantity" in termination): self.__check_mode(termination["mode"], termination["quantity"]) else: self.__set_error_message(True, "You need to set up the termination dictionary with at least 'mode' and 'quantity'.") else: self.__set_error_message(True, "You need to set up the termination dictionary with at least 'mode' and 'quantity'.") else: self.__set_error_message(True, "You need to set up the termination dictionary with at least 'mode' and 'quantity'.") if self.exit_flag: print(self.message) exit(0) else: print(f"Stopping condition mode: {self.name}, with maximum value is: {self.quantity}") def __check_mode(self, mode, quantity): if type(mode) == str: self.mode = mode if mode == "FE": self.name = "Function Evaluation" self.__check_quantity(quantity, self.DEFAULT_MAX_FE) elif self.mode == "TB": self.name = "Time Bound" self.__check_quantity(quantity, self.DEFAULT_MAX_TB) elif self.mode == "ES": self.name = "Early Stopping" self.__check_quantity(quantity, self.DEFAULT_MAX_ES) elif self.mode == "MG": self.name = "Maximum Generation" self.__check_quantity(quantity, self.DEFAULT_MAX_MG) else: self.__set_error_message(True, "Your stopping condition is not support. Please choice other one.") else: self.__set_error_message(True, "Please set up your termination mode and quantity.") def __set_error_message(self, flag, message): self.exit_flag = flag self.message = message def __check_quantity(self, quantity, default_value): self.quantity = quantity if (type(quantity) is int and quantity > 0) else default_value
[docs] def logging(self, verbose=True): if verbose: print(f"Stopping criterion with mode {self.name} occurs. End program!")