diff --git a/search.py b/search.py index 68b77a5a8..d136c0135 100644 --- a/search.py +++ b/search.py @@ -702,20 +702,11 @@ def genetic_search(problem, fitness_fn, ngen=1000, pmut=0.1, n=20): return genetic_algorithm(states[:n], problem.value, ngen, pmut) -def genetic_algorithm(population, fitness_fn, gene_pool=[0, 1], f_thres=None, ngen=1000, pmut=0.1): # noqa +def genetic_algorithm(population, fitness_fn, gene_pool=[0, 1], f_thres=None, ngen=1000, pmut=0.1): """[Figure 4.8]""" for i in range(ngen): - new_population = [] - random_selection = selection_chances(fitness_fn, population) - for j in range(len(population)): - x = random_selection() - y = random_selection() - child = reproduce(x, y) - if random.uniform(0, 1) < pmut: - child = mutate(child, gene_pool) - new_population.append(child) - - population = new_population + population = [mutate(recombine(*select(2, population, fitness_fn)), gene_pool, pmut) + for i in range(len(population))] if f_thres: fittest_individual = argmax(population, key=fitness_fn) @@ -739,18 +730,22 @@ def init_population(pop_number, gene_pool, state_length): return population -def selection_chances(fitness_fn, population): +def select(r, population, fitness_fn): fitnesses = map(fitness_fn, population) - return weighted_sampler(population, fitnesses) + sampler = weighted_sampler(population, fitnesses) + return [sampler() for i in range(r)] -def reproduce(x, y): +def recombine(x, y): n = len(x) - c = random.randrange(1, n) + c = random.randrange(0, n) return x[:c] + y[c:] -def mutate(x, gene_pool): +def mutate(x, gene_pool, pmut): + if random.uniform(0, 1) >= pmut: + return x + n = len(x) g = len(gene_pool) c = random.randrange(0, n)