Source code for pychemia.searcher.swarm

from .searcher import Searcher
from pychemia import pcm_log


[docs]class ParticleSwarm(Searcher): def __init__(self, population, params=None, generation_size=32, stabilization_limit=10): """ Implementation fo the Particle Swarm Optimization algorithm for global minimization :param population: :param params: (dict) Parameters to setup the Searcher. For PSO the parameters are: 'beta0': A value in the range (0,1) that defines how close the mobile structure will be from to the target structure 'alpha0': Factor of scale for the random movement 'delta': How the random change decreases with time :param generation_size: (int) :param stabilization_limit: (int) :return: """ # Initializing objects Searcher.__init__(self, population, generation_size, stabilization_limit) # Parameters self.beta0 = None self.alpha0 = None self.delta = None self.set_params(params)
[docs] def set_params(self, params): # Default parameters self.beta0 = 0.9 self.alpha0 = 0.3 self.delta = 0.9 if params is None: params = {} if 'beta0' in params: self.beta0 = params['beta0'] if 'alpha0' in params: self.alpha0 = params['alpha0'] if 'delta' in params: self.delta = params['delta']
[docs] def get_params(self): return {'beta0': self.beta0, 'alpha0': self.alpha0, 'delta': self.delta}
[docs] def run_one(self): # Get a static selection of the values in the generation that are relaxed selection = self.population.ids_sorted(self.actives_in_generation) pcm_log.info('Size of selection : %d' % len(selection)) # Minus sign because we are searching for minima intensity = self.population.get_values(selection) for entry_id in intensity: intensity[entry_id] *= -1 moves = {} new_selection = {} for entry_id in selection: new_selection[entry_id] = None moves[entry_id] = 0 # Move all the particles (Except the elite) # as the selection is sorted it means that the first one will no move pcm_log.debug('No Moving %d %s. Intensity: %7.3f' % (0, str(selection[0]), intensity[selection[0]])) for i in range(1, len(selection)): entry_id = selection[i] pcm_log.debug('Moving %d %s. Intensity: %7.3f' % (i, str(entry_id), intensity[entry_id])) new_selection[entry_id] = self.population.move(entry_id, selection[0], factor=self.beta0, in_place=False) factor = self.alpha0 * (self.delta ** self.current_generation) self.population.move_random(new_selection[entry_id], factor=factor, in_place=True) for entry_id in selection: if new_selection[entry_id] is not None: pcm_log.debug('[%s] Moved to: %s (%d moves)' % (str(entry_id), new_selection[entry_id], moves[entry_id])) self.replace_by_other(entry_id, new_selection[entry_id], reason='Moved %d times' % moves[entry_id]) self.population.enable(new_selection[entry_id]) else: pcm_log.debug('[%s] Promoted to new generation' % str(entry_id)) self.pass_to_new_generation(entry_id, reason='The best')