43 lines
1.8 KiB
Python
43 lines
1.8 KiB
Python
import random
|
||
from typing import Callable
|
||
|
||
from .chromosome import Chromosome, InitFunc, init_full, init_grow
|
||
|
||
type Population = list[Chromosome]
|
||
|
||
|
||
def ramped_initialization(
|
||
population_size: int,
|
||
depths: list[int],
|
||
make_chromosome: Callable[[InitFunc], Chromosome],
|
||
) -> Population:
|
||
"""Комбинация методов grow и full инициализации хромосом для инициализации начальной
|
||
популяции.
|
||
|
||
Начальная популяция генерируется так, чтобы в нее входили деревья с разной
|
||
максимальной длиной примерно поровну. Для каждой глубины первая половина деревьев
|
||
генерируется полным методом, а вторая – растущей инициализацией.
|
||
"""
|
||
population: Population = []
|
||
per_depth = population_size / len(depths)
|
||
|
||
for depth in depths:
|
||
n_full = int(per_depth / 2)
|
||
n_grow = int(per_depth / 2)
|
||
|
||
population.extend(
|
||
make_chromosome(lambda c: init_full(c, depth)) for _ in range(n_full)
|
||
)
|
||
population.extend(
|
||
make_chromosome(lambda c: init_grow(c, depth)) for _ in range(n_grow)
|
||
)
|
||
|
||
# Из-за округления хромосом может оказаться меньше заданного количества,
|
||
# поэтому дозаполняем остаток популяции случайными хромосомами
|
||
while len(population) < population_size:
|
||
depth = random.choice(depths)
|
||
init_func = init_full if random.random() < 0.5 else init_grow
|
||
population.append(make_chromosome(lambda c: init_func(c, depth)))
|
||
|
||
return population
|