Question: That's what I have so far. As I see from the output, my parameters are not enough to constraint mutation to my needs. Sometimes no one gene is changed, sometimes more than one. import pygad import numpy as np def divider(ga_instance): return np.max(np.sum(ga_instance.population, axis=1)) def on_start(ga_instance): print("on_start()") print(f'Начальная популяция:\n {ga_instance.population}') def fitness_function(ga_instance, solution, _): return np.sum(solution) / divider(ga_instance) def on_fitness(ga_instance, population_fitness): print(f'\non_fitness()') print(f'Делитель: {divider(ga_instance)}') for idx, (instance, fitness) in enumerate(zip(ga_instance.population, ga_instance.last_generation_fitness)): print(f'{idx}. {instance}: {fitness}') def on_parents(ga_instance, selected_parents): print("\non_parents()") print(f'Выбранные индексы родителей: {ga_instance.last_generation_parents_indices}') print(f'Выбранные родители:\n {ga_instance.last_generation_parents}') def on_crossover(ga_instance, offspring_crossover): print("\non_crossover()") print(f'Результат кроссинговера:\n {ga_instance.last_generation_offspring_crossover}') def on_mutation(ga_instance, offspring_mutation): print("\non_mutation()") print(f'Результат мутации:\n {ga_instance.last_generation_offspring_mutation}') def on_generation(ga_instance): print(f"\non_generation()") print("Выведенное поколение:\n ", ga_instance.population) sol = ga_instance.best_solution() print(f"Лучшее решение: {sol[0]} : {sol[1]}") ga_instance = pygad.GA( num_generations=1, num_parents_mating=2, fitness_func=fitness_function, gene_type=int, init_range_low=0, init_range_high=2, sol_per_pop=10, num_genes=8, crossover_type='single_point', parent_selection_type="rws", mutation_type="inversion", mutation_num_genes=1, on_start=on_start, on_fitness=on_fitness, on_parents=on_parents, on_crossover=on_crossover, on_mutation=on_mutation, on_generation=on_generation, ) ga_instance.run()  More details for stackoverflow algorithm: sdfgdsfdddddddddddfffffffffadsgadfgdafgdasgadsgdsagdsagdsagadsgdsagdsagdsag.

Answer: Inversion mutation inverts the order of subset of the genes. It does not invert the value of the genes from 0 to 1. That is if you have a chromosome like abcd, then inversion mutation inverts the genes to be dcba. To apply a mutation operator that flips the genes from 0 to 1 and from 1 to 0, use this code. It creates a new function flip_mutation() to flip the bits. import pygad import numpy as np def divider(ga_instance): return np.max(np.sum(ga_instance.population, axis=1)) def on_start(ga_instance): print("on_start()") print(f'Начальная популяция:\n {ga_instance.population}') def fitness_function(ga_instance, solution, _): return np.sum(solution) / divider(ga_instance) def on_fitness(ga_instance, population_fitness): print(f'\non_fitness()') print(f'Делитель: {divider(ga_instance)}') for idx, (instance, fitness) in enumerate(zip(ga_instance.population, ga_instance.last_generation_fitness)): print(f'{idx}. {instance}: {fitness}') def on_parents(ga_instance, selected_parents): print("\non_parents()") print(f'Выбранные индексы родителей: {ga_instance.last_generation_parents_indices}') print(f'Выбранные родители:\n {ga_instance.last_generation_parents}') def on_crossover(ga_instance, offspring_crossover): print("\non_crossover()") print(f'Результат кроссинговера:\n {ga_instance.last_generation_offspring_crossover}') def on_mutation(ga_instance, offspring_mutation): print("\non_mutation()") print(f'Результат мутации:\n {ga_instance.last_generation_offspring_mutation}') def on_generation(ga_instance): print(f"\non_generation()") print("Выведенное поколение:\n ", ga_instance.population) sol = ga_instance.best_solution() print(f"Лучшее решение: {sol[0]} : {sol[1]}") def flip_mutation(offspring, ga_instance): for idx in range(offspring.shape[0]): mutation_gene1 = np.random.randint(low=0, high=np.ceil(offspring.shape[1]/2 + 1), size=1)[0] if offspring[idx, mutation_gene1] == 1: offspring[idx, mutation_gene1] = 0 else: offspring[idx, mutation_gene1] = 1 return offspring ga_instance = pygad.GA( num_generations=1, num_parents_mating=2, fitness_func=fitness_function, gene_type=int, init_range_low=0, init_range_high=2, sol_per_pop=10, num_genes=8, crossover_type='single_point', parent_selection_type="rws", mutation_type=flip_mutation, mutation_num_genes=1, on_start=on_start, on_fitness=on_fitness, on_parents=on_parents, on_crossover=on_crossover, on_mutation=on_mutation, on_generation=on_generation, ) ga_instance.run()