Edit on GitHub

geneticalgorithm2

Genetic Algorithm (Elitist version) for Python3.8+

An implementation of elitist genetic algorithm for solving problems with continuous, integers, or mixed variables.

repo path: https://github.com/PasaOpasen/geneticalgorithm2

code docs path: https://pasaopasen.github.io/geneticalgorithm2/

 1"""
 2Genetic Algorithm (Elitist version) for Python3.8+
 3
 4An implementation of elitist genetic algorithm for solving problems with
 5continuous, integers, or mixed variables.
 6
 7repo path:       https://github.com/PasaOpasen/geneticalgorithm2
 8
 9code docs path:  https://pasaopasen.github.io/geneticalgorithm2/
10"""
11
12
13from typing_extensions import TypeAlias
14
15from .data_types.algorithm_params import AlgorithmParams
16from .data_types.generation import Generation
17
18from .geneticalgorithm2 import GeneticAlgorithm2
19
20# to keep backward compatibility like it was since geneticalgorithm package
21geneticalgorithm2: TypeAlias = GeneticAlgorithm2
22
23from .mutations import Mutations
24from .crossovers import Crossover
25from .selections import Selection
26
27from .population_initializer import get_population_initializer
28
29# to keep backward compatibility
30Population_initializer: TypeAlias = get_population_initializer
31
32from .callbacks import Callbacks, Actions, ActionConditions, MiddleCallbacks
33
34from .utils.cache import np_lru_cache
35from .utils.plotting import plot_pop_scores, plot_several_lines
geneticalgorithm2: typing_extensions.TypeAlias = <class 'geneticalgorithm2.geneticalgorithm2.GeneticAlgorithm2'>
def Population_initializer( select_best_of: int = 4, local_optimization_step: Literal['before_select', 'after_select', 'never'] = 'never', local_optimizer: Union[Callable[[numpy.ndarray, float], Tuple[numpy.ndarray, float]], NoneType] = None) -> Tuple[int, Callable[[numpy.ndarray, numpy.ndarray], Tuple[numpy.ndarray, numpy.ndarray]]]:
26def get_population_initializer(
27    select_best_of: int = 4,
28    local_optimization_step: LOCAL_OPTIMIZATION_STEP_CASE = 'never',
29    local_optimizer: Optional[
30        Callable[
31            [array1D, float],
32            Tuple[array1D, float]
33        ]
34    ] = None
35) -> Tuple[int, PopulationModifier]:
36    """
37    Args:
38        select_best_of: determines population size to select 1/select_best_of best part of start population.
39            For example, for select_best_of = 4 and population_size = N there will be selected N best objects
40                from 5N generated objects (if start_generation=None dictionary).
41            If start_generation is not None dictionary, there will be selected best (start_generation) / N objects
42        local_optimization_step: when to perform local optimization
43        local_optimizer: the local optimization function (object array, its score) -> (modified array, its score)
44
45    Returns:
46        select_best_of, population modifier
47    """
48    
49    assert select_best_of > 0 and isinstance(select_best_of, int), (select_best_of, type(select_best_of))
50
51    assert local_optimization_step in LOCAL_OPTIMIZATION_STEP_CASE.__args__, (
52        local_optimization_step, LOCAL_OPTIMIZATION_STEP_CASE.__args__
53    )
54
55    if local_optimizer is None and local_optimization_step in LOCAL_OPTIMIZATION_STEP_CASE.__args__[:2]:
56        raise Exception(
57            f"for local_optimization_step from {LOCAL_OPTIMIZATION_STEP_CASE.__args__[:2]} "
58            f"local_optimizer function mustn't be None"
59        )
60
61    def select_best(population: array2D, scores: array1D) -> Tuple[array2D, array1D]:
62        args = np.argsort(scores)
63        args = args[:round(args.size/select_best_of)]
64        return population[args], scores[args]
65
66    def local_opt(population: array2D, scores: array1D):
67        _pop, _score = zip(
68            *[
69                local_optimizer(population[i], scores[i]) for i in range(scores.size)
70            ]
71        )
72        return np.array(_pop), np.array(_score)
73
74    #def Create_population(func, start_generation, expected_size, #variable_boundaries):
75    #    
76    #    if not (start_generation['variables'] is None):
77    #        pop = start_generation['variables']
78    #        scores = start_generation['scores']
79    #        if scores is None:
80    #            scores = np.array([func(pop[i, :]) for i in range(pop.shape[0])])
81    #        return pop, scores
82
83    def process_population(population: array2D, scores: array1D):
84        if local_optimization_step == 'before_select':
85            pop, s = local_opt(population, scores)
86            return select_best(pop, s)
87
88        if local_optimization_step == 'after_select':
89            pop, s = select_best(population, scores)
90            return local_opt(pop, s)
91
92        #if local_optimization_step == 'never':
93        return select_best(population, scores)
94
95    return select_best_of, process_population
Arguments:
  • select_best_of: determines population size to select 1/select_best_of best part of start population. For example, for select_best_of = 4 and population_size = N there will be selected N best objects from 5N generated objects (if start_generation=None dictionary). If start_generation is not None dictionary, there will be selected best (start_generation) / N objects
  • local_optimization_step: when to perform local optimization
  • local_optimizer: the local optimization function (object array, its score) -> (modified array, its score)
Returns:

select_best_of, population modifier