source: framspy/evolalg/base/experiment_islands_model_abc.py @ 1272

Last change on this file since 1272 was 1190, checked in by Maciej Komosinski, 2 years ago

Added the "evolalg" module for evolutionary optimization

File size: 4.5 KB
Line 
1import time
2from abc import ABC
3from typing import List
4
5from ..structures.individual import Individual
6from ..structures.population import PopulationStructures
7from .experiment_abc import ExperimentABC
8
9
10class ExperimentIslands(ExperimentABC, ABC):
11
12    number_of_populations = 5
13    popsize = 100
14    populations: List[PopulationStructures] = []
15    migration_interval = 10
16
17    def __init__(self, popsize, hof_size, number_of_populations, migration_interval, save_only_best) -> None:
18        super().__init__(popsize=popsize, hof_size=hof_size, save_only_best=save_only_best)
19        self.number_of_populations=number_of_populations
20        self.migration_interval=migration_interval
21
22    def migrate_populations(self):
23        print("Performing base migration")
24        pool_of_all_individuals = []
25        for p in self.populations:
26            pool_of_all_individuals.extend(p.population)
27        print(f"Pool of individuals: {len(pool_of_all_individuals)}")
28        sorted_individuals = sorted(
29            pool_of_all_individuals, key=lambda x: x.rawfitness)
30        print(f"Best indiviudal for new islands:")
31        for i in range(self.number_of_populations):
32            shift = i*self.popsize
33            self.populations[i].population = sorted_individuals[shift:shift+self.popsize]
34            print(i, self.populations[i].population[-1].rawfitness)
35
36    def initialize_evolution(self, initialgenotype):
37        self.current_generation = 0
38        self.time_elapsed = 0
39        self.stats = []  # stores the best individuals, one from each generation
40        initial_individual = Individual()
41        initial_individual.set_and_evaluate(initialgenotype, self.evaluate)
42        self.stats.append(initial_individual.rawfitness)
43        [self.populations.append(PopulationStructures(initial_individual=initial_individual,
44                                                      popsize=self.popsize))
45         for _ in range(self.number_of_populations)]
46
47    def get_state(self):
48        return [self.time_elapsed, self.current_generation, self.populations, self.hof, self.stats]
49
50    def set_state(self, state):
51        self.time_elapsed, self.current_generation, self.populations, hof_, self.stats = state
52        # sorting: ensure that we add from worst to best so all individuals are added to HOF
53        for h in sorted(hof_, key=lambda x: x.rawfitness):
54            self.hof.add(h)
55
56    def evolve(self, hof_savefile, generations, initialgenotype, pmut, pxov, tournament_size):
57        file_name = self.get_state_filename(hof_savefile)
58        state = self.load_state(file_name)
59        if state is not None:  # loaded state from file
60            # saved generation has been completed, start with the next one
61            self.current_generation += 1
62            print("...Resuming from saved state: population size = %d, hof size = %d, stats size = %d, generation = %d/%d" % (len(self.populations[0].population), len(
63                self.hof), len(self.stats), self.current_generation, generations))  # self.current_generation (and g) are 0-based, parsed_args.generations is 1-based
64        else:
65            self.initialize_evolution(initialgenotype)
66        time0 = time.process_time()
67        for g in range(self.current_generation, generations):
68            for p in self.populations:
69                p.population = self.make_new_population(
70                    p.population, pmut, pxov, tournament_size)
71
72            if g % self.migration_interval == 0:
73                print("---------Start of migration-------")
74                self.migrate_populations()
75                print("---------End of migration---------")
76
77            pool_of_all_individuals = []
78            [pool_of_all_individuals.extend(p.population)
79             for p in self.populations]
80            self.update_stats(g, pool_of_all_individuals)
81            if hof_savefile is not None:
82                self.current_generation = g
83                self.time_elapsed += time.process_time() - time0
84                self.save_state(file_name)
85
86        if hof_savefile is not None:
87            self.save_genotypes(hof_savefile)
88
89        return self.hof, self.stats
90
91    @staticmethod
92    def get_args_for_parser():
93        parser = ExperimentABC.get_args_for_parser()
94
95        parser.add_argument("-islands",type=int, default=5,
96                            help="Number of subpopulations (islands)")
97        parser.add_argument("-generations_migration",type=int, default=10,
98                            help="Number of generations separating migration events when genotypes migrate between subpopulations (islands)")
99        return parser
Note: See TracBrowser for help on using the repository browser.