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

Last change on this file since 1294 was 1294, checked in by Maciej Komosinski, 3 months ago

Initialize more fields in constructors

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