示例#1
0
    def generate_offspring(self, parents, generation, pool=None):
        """
    This function generates the offspring from the population
    :return: Population of offsprings
    """
        offsprings = Population(self.params, init_size=0, name='offsprings')

        parent_genome = parents['genome']
        parent_ids = parents['id']
        parent_ancestor = parents['ancestor']

        if pool is not None:
            offs = pool.map(self._generate_off,
                            zip(parent_ids, parent_genome, parent_ancestor))
        else:
            offs = []
            for id_gen in zip(
                    parent_ids, parent_genome,
                    parent_ancestor):  # Generate offsprings from each parent
                offs.append(self._generate_off(id_gen))

        offsprings.pop = [off for p_off in offs for off in p_off
                          ]  # Unpack list of lists and add it to offsprings
        offs_ids = parents.agent_id + np.array(range(
            len(offsprings)))  # Calculate offs IDs
        offsprings['id'] = offs_ids  # Update offs IDs
        offsprings['born'] = [generation] * offsprings.size
        parents.agent_id = max(
            offs_ids) + 1  # This saves the maximum ID reached till now
        return offsprings
示例#2
0
    def evolve(pop):

        new_pop = Population(0)
        LEN_POP = 0
        '''Keep The Fittest Chromosomes'''
        for i in range(settings.NUMBER_OF_ELITE_CHROMOSOMES):
            new_pop.append(pop[i])
            LEN_POP += 1

        while LEN_POP < settings.POPULATION_SIZE:
            parent1 = GeneticAlgorithm.select_tournament(pop)
            parent2 = GeneticAlgorithm.select_tournament(pop)

            child1, child2 = GeneticAlgorithm.crossover_chromosomes(
                parent1, parent2)

            GeneticAlgorithm.mutate_chromosome(child1)
            GeneticAlgorithm.mutate_chromosome(child2)

            new_pop.append(child1)
            LEN_POP += 1

            # make sure to not depass the population size if we keep the elite
            if LEN_POP < settings.POPULATION_SIZE:
                new_pop.append(child2)
                LEN_POP += 1

            # make sure to not depass the population size if we keep the elite
            # if len(new_pop.get_chromosomes()) < settings.POPULATION_SIZE:
            #     new_pop.get_chromosomes().append(child2)

        new_pop.sort(reverse=True)
        return new_pop
示例#3
0
    def __init__(self, parameters):
        self.parameters = parameters
        self.bd_extractor = BehaviorDescriptor(self.parameters)

        self.generation = 1

        if self.parameters.multiprocesses:
            global main_pool
            main_pool = mp.Pool(initializer=self.init_process,
                                processes=self.parameters.multiprocesses)

        self.evaluator = Evaluator(self.parameters)

        self.population = Population(self.parameters,
                                     init_size=self.parameters.pop_size)
        self.init_pop = True
        self.offsprings = None

        if self.parameters.exp_type == 'NS':
            self.evolver = NoveltySearch(self.parameters)

        elif self.parameters.exp_type == 'SIGN':
            self.evolver = NoveltySearch(self.parameters)

        elif self.parameters.exp_type == 'CMA-ES':
            self.evolver = CMAES(self.parameters)
            # Generate CMA-ES initial population
            del self.population
            self.population = Population(
                self.parameters, init_size=self.parameters.emitter_population)
            for agent in self.population:
                agent['genome'] = self.evolver.optimizer.ask()

        elif self.parameters.exp_type == 'CMA-NS':
            self.evolver = CMANS(self.parameters)
            self.reward_archive = self.evolver.rew_archive

        elif self.parameters.exp_type == 'NSGA-II':
            self.evolver = NSGAII(self.parameters)

        elif self.parameters.exp_type == 'SERENE':
            self.evolver = SERENE(self.parameters)

        elif self.parameters.exp_type == 'ME':
            self.evolver = MAPElites(self.parameters)

        elif self.parameters.exp_type == 'CMA-ME':
            self.evolver = CMAME(self.parameters)

        elif self.parameters.exp_type == 'RND':
            self.evolver = RandomSearch(self.parameters)

        else:
            print("Experiment type {} not implemented.".format(
                self.parameters.exp_type))
            raise ValueError
示例#4
0
 def test_total_fitness(self):
     """
     Population - total fitness
     """
     population = Population(Mock)
     population += [
         _FakeIndividual(0.1),
         _FakeIndividual(0.5)
     ]
     population.calculate_fitness()
     self.assertEquals(population.total_fitness, 0.6)
示例#5
0
 def test_average_fitness(self):
     """
     Population - average fitness
     """
     population = Population(Mock)
     population += [
         _FakeIndividual(0.1),
         _FakeIndividual(0.5)
     ]
     population.calculate_fitness()
     self.assertEquals(population.average_fitness, 0.3)
示例#6
0
 def test_best_solution(self):
     """
     Population - return best solution
     """
     population = Population(Mock)
     population += [
         _FakeIndividual(0.1),
         _FakeIndividual(0.5)
     ]
     population.calculate_fitness()
     self.assertEquals(population.best_individual.fitness, 0.5)
示例#7
0
 def test_best_chromosomes(self):
     """
     Population - elite chromosomes
     """
     population = Population(Mock)
     population += [
         _FakeIndividual(0.5),
         _FakeIndividual(0.1),
         _FakeIndividual(0.9),
     ]
     population.calculate_fitness()
     self.assertSequenceEqual(
         population.best_individuals(2),
         [population[2], population[0]])
示例#8
0
    def generate_off(self, generation):
        """
    This function generates the offsprings of the emitter
    :return:
    """
        offsprings = Population(self._params,
                                init_size=2 * self.pop.size,
                                name='offsprings')
        off_genomes = []
        off_ancestors = []
        off_parents = []
        for agent in self.pop:  # Generate 2 offsprings from each parent
            off_genomes.append(self.mutate_genome(agent['genome']))
            off_genomes.append(self.mutate_genome(agent['genome']))
            off_ancestors.append(agent['ancestor'] if agent['ancestor']
                                 is not None else agent['id'])
            off_ancestors.append(agent['ancestor'] if agent['ancestor']
                                 is not None else agent['id'])
            off_parents.append(agent['id'])
            off_parents.append(agent['id'])

        off_ids = self.pop.agent_id + np.array(range(len(offsprings)))

        offsprings['genome'] = off_genomes
        offsprings['id'] = off_ids
        offsprings['ancestor'] = off_ancestors
        offsprings['parent'] = off_parents
        offsprings['born'] = [generation] * offsprings.size
        self.pop.agent_id = max(
            off_ids) + 1  # This saves the maximum ID reached till now
        return offsprings
示例#9
0
 def generate_offspring(self, parents, generation, pool=None):
   """
   This function generates the offspring from the population
   :return: Population of offsprings
   """
   offsprings = Population(self.params, init_size=self.params.pop_size, name='offsprings')
   return offsprings
示例#10
0
    def run(self, generations=None):
        """
        Runs genetic algorithm for a number of iterations,
        starting with a randomly created initial population.
        If iteration count is not specified, algorithm would run
        until terminated explicitly.
        Yields current population AND generation number.
        """
        if generations is not None and generations < 1:
            raise ValueError(
                "Generation count must be positive, non-zero integer")

        # Initial random population for generation-0:
        self._population = Population(
            self.phenotype,
            self.population_size,
            parallelizer=self._parallelizer)
        self._population.calculate_fitness()

        # Run specified amount of iterations
        if generations:
            for generation in xrange(1, generations + 1):
                self._population = self._next_population()
                yield self.population, generation

        # Run indefintely
        else:
            generation = 0
            while True:
                self._population = self._next_population()
                generation += 1
                yield self.population, generation
示例#11
0
 def _init_pop(self):
     """
 This function initializes the emitter pop around the parent
 :return:
 """
     pop = Population(self._params, self._pop_size)
     for agent in pop:
         agent['genome'] = self.mutate_genome(self._init_mean)
     return pop
示例#12
0
    def __init__(self, parameters):
        self.parameters = parameters
        self.bd_extractor = BehaviorDescriptor(self.parameters)

        self.generation = 0

        if self.parameters.multiprocesses:
            global main_pool
            main_pool = mp.Pool(initializer=self.init_process,
                                processes=self.parameters.multiprocesses)
        else:
            self.evaluator = Evaluator(self.parameters)

        self.evolver = NoveltySearch(self.parameters)
        self.population = Population(self.parameters,
                                     init_size=self.parameters.pop_size)
        self.offsprings = None
        self.ns_archive = self.evolver.archive
示例#13
0
    def _next_population(self):
        # Start with an empty population
        new_population = Population(
            self.phenotype,
            size=0,
            parallelizer=self._parallelizer)

        # Pick best individuals from previous population if necessary
        new_population += self.population.best_individuals(
            self.elitism_count)

        # Form the new population
        while len(new_population) < self.population_size:
            # Selection
            individual1 = self._selection.run(self.population)
            individual2 = self._selection.run(self.population)

            # Crossover
            # Individuals are copied, regardless of whether
            # crossover actually occurs.
            offspring1, offspring2 = self._crossover.run(
                individual1, individual2)

            # Mutation
            offspring1.mutate(self.mutation_rate)
            offspring2.mutate(self.mutation_rate)

            new_population += [offspring1, offspring2]

        # If elitism param is odd number, the new population might have got
        # one extra individual. Remove the worst?
        if self._remove_extra_individual is True:
            new_population.calculate_fitness(
                truncate_if_above=self.population_size)
        else:
            new_population.calculate_fitness()

        return new_population
示例#14
0
    def __init__(self, parameters, **kwargs):
        super().__init__(parameters)

        self.update_criteria = 'novelty'
        self.rew_archive = Archive(self.params, name='rew_archive')

        # Instantiated only to extract genome size
        controller = registered_envs[
            self.params.env_name]['controller']['controller'](
                **registered_envs[self.params.env_name]['controller'])

        self.genome_size = controller.genome_size
        self.bounds = self.params.genome_limit * np.ones(
            (self.genome_size, len(self.params.genome_limit)))
        self.emitter_pop = Population(self.params,
                                      init_size=self.params.emitter_population,
                                      name='emitter')
        self.emitter_based = True
        self.archive_candidates = {}
        self.emitters = {}
        self.emitter_candidate = {}
示例#15
0
    def create_random_cells(self, n_cells):
        """
        Creation of a basic population for cells, with latitude and longitude
        """

        cells = Population(size=n_cells)

        latitude_generator = FakerGenerator(method="latitude",
                                            seed=next(self.seeder))
        longitude_generator = FakerGenerator(method="longitude",
                                             seed=next(self.seeder))

        cells.create_attribute("latitude", init_gen=latitude_generator)
        cells.create_attribute("longitude", init_gen=longitude_generator)

        return cells
示例#16
0
    def __init__(self, ancestor, mutation_rate, parameters):
        self.ancestor = ancestor
        self._init_mean = self.ancestor['genome']
        self.id = ancestor['id']
        self._mutation_rate = mutation_rate
        self._params = parameters
        self._pop_size = self._params.emitter_population
        self.pop = self._init_pop()
        self.ns_arch_candidates = Population(self._params,
                                             init_size=0,
                                             name='ns_arch_cand')

        # List of lists. Each inner list corresponds to the values obtained during a step
        # We init with the ancestor reward so it's easier to calculate the improvement
        self.values = []
        self.archived_values = []
        self.improvement = 0
        self._init_values = None
        self.archived = [
        ]  # List containing the number of archived agents at each step
        self.most_novel = self.ancestor
        self.steps = 0
示例#17
0
class Algorithm(object):
    def __init__(self,
                 phenotype,
                 crossover,
                 selection,
                 population_size=10,
                 mutation_rate=0.01,
                 elitism_count=0,
                 parallelizer=None):
        # Classes
        self.phenotype = phenotype

        # Parameters
        self.population_size = population_size
        self.mutation_rate = mutation_rate
        self.elitism_count = elitism_count

        # GA operator instances
        self._crossover = crossover
        self._selection = selection

        # Etc
        self._parallelizer = parallelizer
        self._population = None
        # Odd elitist size - selection/crossover/mutation is done in pairs
        # so eventually the new population will get one extra individual
        # which needs to be dealt with
        if self.elitism_count % 2 == 1:
            self._remove_extra_individual = True
        else:
            self._remove_extra_individual = False

    @property
    def population(self):
        return self._population

    def _next_population(self):
        # Start with an empty population
        new_population = Population(
            self.phenotype,
            size=0,
            parallelizer=self._parallelizer)

        # Pick best individuals from previous population if necessary
        new_population += self.population.best_individuals(
            self.elitism_count)

        # Form the new population
        while len(new_population) < self.population_size:
            # Selection
            individual1 = self._selection.run(self.population)
            individual2 = self._selection.run(self.population)

            # Crossover
            # Individuals are copied, regardless of whether
            # crossover actually occurs.
            offspring1, offspring2 = self._crossover.run(
                individual1, individual2)

            # Mutation
            offspring1.mutate(self.mutation_rate)
            offspring2.mutate(self.mutation_rate)

            new_population += [offspring1, offspring2]

        # If elitism param is odd number, the new population might have got
        # one extra individual. Remove the worst?
        if self._remove_extra_individual is True:
            new_population.calculate_fitness(
                truncate_if_above=self.population_size)
        else:
            new_population.calculate_fitness()

        return new_population

    def run(self, generations=None):
        """
        Runs genetic algorithm for a number of iterations,
        starting with a randomly created initial population.
        If iteration count is not specified, algorithm would run
        until terminated explicitly.
        Yields current population AND generation number.
        """
        if generations is not None and generations < 1:
            raise ValueError(
                "Generation count must be positive, non-zero integer")

        # Initial random population for generation-0:
        self._population = Population(
            self.phenotype,
            self.population_size,
            parallelizer=self._parallelizer)
        self._population.calculate_fitness()

        # Run specified amount of iterations
        if generations:
            for generation in xrange(1, generations + 1):
                self._population = self._next_population()
                yield self.population, generation

        # Run indefintely
        else:
            generation = 0
            while True:
                self._population = self._next_population()
                generation += 1
                yield self.population, generation
示例#18
0
class Searcher(object):
    """
  This class creates the instance of the NS algorithm and everything related
  """
    def __init__(self, parameters):
        self.parameters = parameters
        self.bd_extractor = BehaviorDescriptor(self.parameters)

        self.generation = 0

        if self.parameters.multiprocesses:
            global main_pool
            main_pool = mp.Pool(initializer=self.init_process,
                                processes=self.parameters.multiprocesses)
        else:
            self.evaluator = Evaluator(self.parameters)

        self.evolver = NoveltySearch(self.parameters)
        self.population = Population(self.parameters,
                                     init_size=self.parameters.pop_size)
        self.offsprings = None
        self.ns_archive = self.evolver.archive

    def init_process(self):
        """
    This function is used to initialize the pool so each process has its own instance of the evaluator
    :return:
    """
        global evaluator
        evaluator = Evaluator(self.parameters)

    def _feed_eval(self, agent):
        """
    This function feeds the agent to the evaluator and returns the updated agent
    :param agent:
    :return:
    """
        global evaluator
        eval_agent = evaluator(
            agent, self.bd_extractor.__call__
        )  # Is passing the call better than init the evaluator with the bd inside???
        return eval_agent

    def evaluate_in_env(self, pop, pool=None):
        """
    This function evaluates the population in the environment by passing it to the parallel evaluators.
    :return:
    """
        if self.parameters.verbose:
            print('Evaluating {} in environment.'.format(pop.name))
        if self.parameters.multiprocesses:
            pop.pop = pool.map(
                self._feed_eval, pop.pop
            )  # As long as the ID is fine, the order of the element in the list does not matter
        else:
            for i in range(pop.size):
                if self.parameters.verbose:
                    print(".", end='')  # The end prevents the newline
                pop[i] = self.evaluator(pop[i], self.bd_extractor)
            if self.parameters.verbose: print()

    def generational_step(self):
        """
    This function performs all the calculations needed for one generation.
    Generates offsprings, evaluates them and the parents in the environment, calculates the performance metrics,
    updates archive and population and finally saves offsprings, population and archive.
    :return: time taken for running the generation
    """
        global main_pool
        start_time = timer()

        # NB if you pass a pool here the offsprings are not well generated. This is probably due to the fact that
        # the sampling for the mutation are done in parallel so multiple offsprings will have same mutations.
        self.offsprings = self.evolver.generate_offspring(
            self.population, pool=None)  # Generate offsprings

        # Evaluate population and offsprings in the environment
        self.evaluate_in_env(self.population, pool=main_pool)
        self.evaluate_in_env(self.offsprings, pool=main_pool)

        # Do evolution stuff #TODO maybe can wrap these 3 functions into a single ea.step function
        self.evolver.evaluate_performances(
            self.population, self.offsprings,
            pool=main_pool)  # Calculate novelty/fitness/curiosity etc
        self.evolver.update_archive(self.offsprings)
        self.evolver.update_population(self.population, self.offsprings)

        self.generation += 1

        # Save pop, archive and off
        self.population.save(self.parameters.save_path,
                             'gen_{}'.format(self.generation))
        self.evolver.archive.save(self.parameters.save_path,
                                  'gen_{}'.format(self.generation))
        self.offsprings.save(self.parameters.save_path,
                             'gen_{}'.format(self.generation))
        return timer() - start_time

    def load_generation(self, generation, path):
        """
    This function loads the population, the offsprings and the archive at a given generation, so it can restart the
    search from there.
    :param generation:
    :param path: experiment path
    :return:
    """
        self.generation = generation

        self.population.load(
            os.path.join(path,
                         'population_gen_{}.pkl'.format(self.generation)))
        self.offsprings.load(
            os.path.join(path,
                         'offsprings_gen_{}.pkl'.format(self.generation)))
        self.evolver.archive.load(
            os.path.join(path, 'archive_gen_{}.pkl'.format(self.generation)))

    def close(self):
        """
    This function closes the pool and deletes everything.
    :return:
    """
        if self.parameters.multiprocesses:
            global main_pool
            main_pool.close()
            main_pool.join()
示例#19
0
    def __init__(self, evaluate):
        self.evaluate = evaluate
        self.population = Population()

        self.starting_compatibility_threshold = config.compatibility_threshold
示例#20
0
    def reset(self):
        self.population = Population()

        config.compatibility_threshold = self.starting_compatibility_threshold
示例#21
0
class Searcher(object):
    """
  This class creates the instance of the NS algorithm and everything related
  """
    def __init__(self, parameters):
        self.parameters = parameters
        self.bd_extractor = BehaviorDescriptor(self.parameters)

        self.generation = 1

        if self.parameters.multiprocesses:
            global main_pool
            main_pool = mp.Pool(initializer=self.init_process,
                                processes=self.parameters.multiprocesses)

        self.evaluator = Evaluator(self.parameters)

        self.population = Population(self.parameters,
                                     init_size=self.parameters.pop_size)
        self.init_pop = True
        self.offsprings = None

        if self.parameters.exp_type == 'NS':
            self.evolver = NoveltySearch(self.parameters)

        elif self.parameters.exp_type == 'SIGN':
            self.evolver = NoveltySearch(self.parameters)

        elif self.parameters.exp_type == 'CMA-ES':
            self.evolver = CMAES(self.parameters)
            # Generate CMA-ES initial population
            del self.population
            self.population = Population(
                self.parameters, init_size=self.parameters.emitter_population)
            for agent in self.population:
                agent['genome'] = self.evolver.optimizer.ask()

        elif self.parameters.exp_type == 'CMA-NS':
            self.evolver = CMANS(self.parameters)
            self.reward_archive = self.evolver.rew_archive

        elif self.parameters.exp_type == 'NSGA-II':
            self.evolver = NSGAII(self.parameters)

        elif self.parameters.exp_type == 'SERENE':
            self.evolver = SERENE(self.parameters)

        elif self.parameters.exp_type == 'ME':
            self.evolver = MAPElites(self.parameters)

        elif self.parameters.exp_type == 'CMA-ME':
            self.evolver = CMAME(self.parameters)

        elif self.parameters.exp_type == 'RND':
            self.evolver = RandomSearch(self.parameters)

        else:
            print("Experiment type {} not implemented.".format(
                self.parameters.exp_type))
            raise ValueError

    def init_process(self):
        """
    This function is used to initialize the pool so each process has its own instance of the evaluator
    :return:
    """
        global evaluator
        evaluator = Evaluator(self.parameters)

    def _feed_eval(self, agent):
        """
    This function feeds the agent to the evaluator and returns the updated agent
    :param agent:
    :return:
    """
        global evaluator
        if agent['evaluated'] == None:  # Agents are evaluated only once
            agent = evaluator(agent, self.bd_extractor.__call__)
        return agent

    def evaluate_in_env(self, pop, pool=None):
        """
    This function evaluates the population in the environment by passing it to the parallel evaluators.
    :return:
    """
        if self.parameters.verbose:
            print('Evaluating {} in environment.'.format(pop.name))
        if pool is not None:
            pop.pop = pool.map(
                self._feed_eval, pop.pop
            )  # As long as the ID is fine, the order of the element in the list does not matter
        else:
            for i in range(pop.size):
                if self.parameters.verbose:
                    print(".", end='')  # The end prevents the newline
                if pop[i][
                        'evaluated'] is None:  # Agents are evaluated only once
                    pop[i] = self.evaluator(pop[i], self.bd_extractor)
            if self.parameters.verbose: print()

    def _main_search(self, budget_chunk):
        """
    This function performs the main search e.g. NS/NSGA/CMA-ES
    :return:
    """
        # Only log reward here if NS or NSGA. Emitter based log during the emitter evaluation
        if self.evolver.emitter_based:
            log_reward = False
        else:
            log_reward = True

        # Evaluate population in the environment only the first time
        if self.init_pop:
            self.evaluate_in_env(self.population, pool=main_pool)
            self.population['evaluated'] = list(
                range(self.evolver.evaluated_points,
                      self.evolver.evaluated_points + self.population.size))
            self.evolver.evaluated_points += self.population.size
            self.evolver.evaluation_budget -= self.population.size
            budget_chunk -= self.population.size
            self.init_pop = False

            if not self.evolver.emitter_based:
                for area in self.population['rew_area']:
                    if area is not None:
                        name = 'rew_area_{}'.format(area)
                        if name not in Logger.data:
                            Logger.data[name] = 0
                        Logger.data[name] += 1

        while budget_chunk > 0 and self.evolver.evaluation_budget > 0:
            self.offsprings = self.evolver.generate_offspring(
                self.population, pool=None,
                generation=self.generation)  # Generate offsprings

            # Evaluate offsprings in the env
            self.evaluate_in_env(self.offsprings, pool=main_pool)
            self.offsprings['evaluated'] = list(
                range(self.evolver.evaluated_points,
                      self.evolver.evaluated_points + self.offsprings.size))
            self.evolver.evaluated_points += self.offsprings.size
            self.evolver.evaluation_budget -= self.offsprings.size
            budget_chunk -= self.offsprings.size
            self.evolver.init_emitters(self.population, self.offsprings)

            # Evaluate performances of pop and off and update archive
            self.evolver.evaluate_performances(
                self.population, self.offsprings,
                pool=main_pool)  # Calculate novelty/fitness/curiosity etc
            # Only update archive using NS stuff. No archive candidates from emitters
            self.evolver.update_archive(self.population,
                                        self.offsprings,
                                        generation=self.generation)

            # Save pop, archive and off
            if self.generation % 1 == 0:
                self.population.save(self.parameters.save_path,
                                     'gen_{}'.format(self.generation))
                self.evolver.archive.save(self.parameters.save_path,
                                          'gen_{}'.format(self.generation))
                self.offsprings.save(self.parameters.save_path,
                                     'gen_{}'.format(self.generation))

            # Log reward only if not emitter based
            if not self.evolver.emitter_based:
                for area in self.offsprings['rew_area']:
                    if area is not None:
                        name = 'rew_area_{}'.format(area)
                        if name not in Logger.data:
                            Logger.data[name] = 0
                        Logger.data[name] += 1

            # Last thing we do is to update the population
            self.generation += 1
            self.evolver.update_population(self.population,
                                           self.offsprings,
                                           generation=self.generation)

    def _emitter_search(self, budget_chunk):
        """
    This function performs the reward search through the emitters
    :return:
    """
        if self.evolver.emitter_based and (
                len(self.evolver.emitters) > 0
                or len(self.evolver.emitter_candidate) > 0):
            self.evolver.emitter_step(self.evaluate_in_env,
                                      self.generation,
                                      ns_pop=self.population,
                                      ns_off=self.offsprings,
                                      budget_chunk=budget_chunk,
                                      pool=None)
            self.evolver.rew_archive.save(self.parameters.save_path,
                                          'gen_{}'.format(self.generation))

            # Update the performaces due to possible changes in the pop and archive given by the emitters
            self.evolver.evaluate_performances(self.population,
                                               self.offsprings,
                                               pool=None)
            # Update main archive with the archive candidates from the emitters
            self.evolver.elaborate_archive_candidates(self.generation)

    def chunk_step(self):
        """
    This function performs all the calculations needed for one generation.
    Generates offsprings, evaluates them and the parents in the environment, calculates the performance metrics,
    updates archive and population and finally saves offsprings, population and archive.
    :return: time taken for running the generation
    """
        global main_pool
        start_time = timer()

        print("\nRemaining budget: {}".format(self.evolver.evaluation_budget))

        # -------------------
        # Base part
        # -------------------
        budget_chunk = self.parameters.chunk_size
        if self.evolver.evaluation_budget > 0:
            print("MAIN")
            self._main_search(budget_chunk)

        # -------------------
        # Emitters part
        # -------------------
        budget_chunk = self.parameters.chunk_size
        # Starts only if a reward has been found.
        if self.evolver.evaluation_budget > 0:
            print("EMITTERS: {}".format(len(self.evolver.emitters)))
            self._emitter_search(budget_chunk)
        # -------------------

        return timer() - start_time, self.evolver.evaluated_points

    def load_generation(self, generation, path):
        """
    This function loads the population, the offsprings and the archive at a given generation, so it can restart the
    search from there.
    :param generation:
    :param path: experiment path
    :return:
    """
        self.generation = generation

        self.population.load(
            os.path.join(path,
                         'population_gen_{}.pkl'.format(self.generation)))
        self.offsprings.load(
            os.path.join(path,
                         'offsprings_gen_{}.pkl'.format(self.generation)))
        self.evolver.archive.load(
            os.path.join(path, 'archive_gen_{}.pkl'.format(self.generation)))

    def close(self):
        """
    This function closes the pool and deletes everything.
    :return:
    """
        if self.parameters.multiprocesses:
            global main_pool
            main_pool.close()
            main_pool.join()
        gc.collect()
示例#22
0
from core.chromosome import Chromosome
from core.population import Population
from core.genetic_algorithm import GeneticAlgorithm
import core.settings as settings

if __name__ == "__main__":
    generation_number = 0
    MAX_FITNESS = 1
    population = Population(settings.POPULATION_SIZE)
    population.print_population(generation_number)

    while population[0].get_fitness(
    ) < MAX_FITNESS and generation_number < settings.MAX_GENERATION_NUMBER:
        generation_number += 1
        population = GeneticAlgorithm.evolve(population)
        population.print_population(generation_number)

    print(population[0].genes)

    print("\n---------- all timetables ------------")
    for c in settings.RAW_DATA["classes"]:
        print("class : {}".format(c))
        print(population[0].get_time_table(c))

        print("---------------------------------------------------\n")
示例#23
0
def load_population(namespace, population_id, circus):
    return Population.load_from(population_folder(namespace, population_id),
                                circus)