Source code for glompo.hunters.valueannealing

import numpy as np

from .basehunter import BaseHunter
from ..core.optimizerlogger import BaseLogger

__all__ = ("ValueAnnealing",)


[docs]class ValueAnnealing(BaseHunter): """ Keeps optimizers alive based on the function values they are exploring. This condition is unlikely to kill a victim which is very near the hunter (in terms of function value) but the probability of killing increases with the difference between them. This condition can be applied in combination with others to prevent 'competitive' optimizers for being killed while still terminating poorly performing ones. The decision criteria follows an exponential distribution which corresponds to the probability of survival. Control of the probability can be achieved through the `med_kill_chance` initialisation criteria. Parameters ---------- med_kill_chance: float The probability of killing a victim which is twice as large as the hunter in absolute value. The default is 50%. Returns ------- bool :obj:`True` if the difference between the explored function values of the hunter and victim fails a comparison test with a uniformly randomly generated number. """ def __init__(self, med_kill_chance: float = 0.5): super().__init__() assert 0 < med_kill_chance < 1, "med_kill_chance must be between 0 and 1" self.med_kill_chance = med_kill_chance self.strictness = np.log(med_kill_chance) def __call__(self, log: BaseLogger, hunter_opt_id: int, victim_opt_id: int) -> bool: f_hunter = log.get_best_iter(hunter_opt_id)['fx'] f_victim = log.get_best_iter(victim_opt_id)['fx'] if f_hunter == 0 or f_victim <= f_hunter: # Catch very unlikely corner cases self.last_result = False return self.last_result prob = (f_hunter - f_victim) / f_hunter prob = np.abs(prob) prob *= self.strictness prob = np.exp(prob) test_num = np.random.uniform(0, 1) self.last_result = test_num > prob return self.last_result