Package: baumeva
BaumEvA - Bauman Evolution AlgorithmBaumEvA is an advanced genetic algorithm crafted in Python. It's designed to work with both binary and combinatorial data types, providing a comprehensive suite of tools for optimization and search tasks. Baumeva offers a variety of selection, crossover, mutation, and parent selection mechanisms.InstallationTo install the BaumEvA, run the following command:pipinstallbaumevaUsageQuickstartYou can start with classBinaryGAwhich already equipped with predefined methods: tournament selection, one-point crossover and simple mutation. This class alows users to engage with binary genetic algorithm effortlessly.frombaumevaimportBinaryGAimportmathdeffunc_grivanka(value_list):res_sum=0res_mpl=1fori,valueinenumerate(value_list):res_sum+=(value*value)/4000res_mpl*=math.cos(value/math.sqrt(i+1))returnres_sum-res_mpl+1This simple function is used to evaluate the solution. In this case we are looking for the minimum of the grivank function.# simple method for use GAbinary_ga=BinaryGA(num_generations=100,num_individ=100,gens=((-16,16,0.01),(-16,16,0.01)),obj_function=func_grivanka,obj_value=0,is_gray=True,mutation_lvl=0.35,early_stop=None)ga_data=binary_ga.optimize()Thenum_generationsspecifies the total number of generations.Thenum_individspecifies the total number of individuals in a population.Thegensspecifies the range and precision for each gene in the binary representation. Tuple contains minimum value for the gene, maximum value for the gene, precision for the gene's value (the step).
In the example given gens=((-16, 16, 0.01), (-16, 16, 0.01)) signifies two genes, both ranging from -16 to 16 with a step of 0.01.BinaryGAworks not with real numbers but with binary representation.Theobj_functionspecifies the objective function that evaluates the object score of each individual.Theobj_valuedefines the target or optimal value the algorithm aims to achieve or get as close as possible to.Theis_grayuses gray code to convert to binary representation, default: False.Themutation_lvlis probability of mutation of each bit; float or string value, default: 'normal' meaning a probability equal to 1/s, where s is the length of the binary string.Theearly_stopdetermines the number of generations N. If the best individual is not updated within N generations in a row, then the algorithm stops; int or None, default: 10.You can get the best solution callingga_data.best_solution.There are also special class for combinatory genetic algorithm -CombinatoryGA. The only difference isgensparameter. For example: (0, 9, 10), 0 - first categorical value,
9 - last categorical value, step between categorical is 1 (const), 10 - number of categorical
values in every individ.Categorical Genetic Algorithm example usageFor optimization in categorical parameter space you should utilizeCategoricalGA. Example ofCategoricalGAusage described below.frombaumevaimportCategoricalGAimportstringdefcat_gens_generator(dim:int)->list:gens_params=[]for_inrange(dim):gens_params.append([iforiinstring.ascii_lowercase[:10]])returngens_paramsdeffunc_uni_value(value_list):returnlen(set(value_list))**2-1categorical_ga=CategoricalGA(num_generations=100,num_individ=300,gens=cat_gens_generator(10),obj_function=func_uni_value,obj_value=0,mutation_lvl=0.1,tournament_size=10,early_stop=None)ga_data=categorical_ga.optimize()Constructor ofCategoricalGAhave the same set of arguments asBinaryGAexcept ofis_gray.
Note that if you want to create some or all genes as list of values you should uselist, nottuple. For example["a", "b", "c", "d"]should be list. If you'd like to use standard range of values to define gene usetuple, for example(1, 10, 1)for numbers from 1 to 10.Conditional optimizationFor conditional optimization tasks you can use same classesBinaryGA,CombinatoryGAwith two additional parameters:penalty,conditions.Thepenaltyis penalty function, subclass ofBasePenalty(), initialization before
initialization subclass ofBaseFitness(), used for conditional optimization.Theconditionsis list of conditionals, 3 value can be use: 'optimize', '<=', '!='Example conditional optimization task:frombaumevaimportBinaryGAfrombaumeva.gaimportDynamicPenaltydefparabola_conditions(x:list)->tuple:res=-x[0]*x[0]+9condition_1=-x[0]-3condition_2=x[0]+3returnres,condition_1,condition_2bin_ga_conditions=BinaryGA(num_generations=100,num_individ=100,gens=((-5,5,0.001),),obj_function=parabola_conditions,obj_value=0,penalty=DynamicPenalty(),conditions=['optimize','<=','!='],is_gray=True,mutation_lvl=0.35,early_stop=None)ga_data_conditions=bin_ga_conditions.optimize()There is object functionparabola_conditions, which return 3 values. Theresis value for optimization, thecondition_1is value less or equal 0, thecondition_2is value not equal 0. So we haveconditions=['optimize', '<=', '!=']and useDynamicPenalty().Advanced UsageAdditionally, BaumEva offers a modular approach for those who desire more customization. By directly declaring specific classes, you can handpick from a wide range of mutation, selection and crossover methods, crafting a customized genetic algorithm.fromrandomimportshufflefrombaumeva.gaimportGaData,OrderCatPopulation,HyperbolaFitness,TournamentSelection,OrderCrossover,SwapMutation,NewGenerationdeffunc_word(word:list)->float:obj_word='ALGORITHM'res=0foridx,litterinenumerate(word):iflitter!=obj_word[idx]:res+=1returnresinput_population_size=100input_word=list("ALGORITHM")in_pop=[]foriinrange(input_population_size):shuffle(input_word)in_pop.append(input_word.copy())defprint_result(data:dict)->None:print("Best result: ")forkeyindata.keys():print(f"{key}:{data[key]}")ga_data=GaData(num_generations=100,early_stop=60)ocp=OrderCatPopulation()ocp.set_params(num_individ=input_population_size,gens=(0,8,9),input_population=in_pop)ocp.fill()ga_data.population=ocpfitness_func=HyperbolaFitness(obj_function=func_word,obj_value=0)fitness_func.execute(ga_data)ga_data.update()selection=TournamentSelection(tournament_size=6)crossover=OrderCrossover()mutation=SwapMutation(0.35)new_generation=NewGeneration('best')foriinrange(ga_data.num_generations):selection.execute(ga_data)crossover.execute(ga_data)mutation.execute(ga_data)new_generation.execute(ga_data)fitness_func.execute(ga_data)ga_data.update()ifga_data.num_generation_no_improve>=ga_data.early_stop:print(f'Early stopping:{i}generation')breakifga_data.best_solution['obj_score']==0:print(f'Goal achieved:{i}generation')breakprint(f"Result:{ga_data.best_solution}")This example demonstrates the use of the BaumEvA library to search for the word "ALGORITHM" using a combination genetic algorithm.Collector UsageAnother way of use of the library is the "collector mode", which allows to collect a customized GA, just like the "advanced mode", but at the same time it is much easier to use.frombaumevaimportCollectorGAfrombaumeva.gaimportBinaryPopulation,HyperbolaFitness,TournamentSelection,OnePointCrossover,\BinStringMutation,NewGenerationdefgenerate_gens_params(one_gen:list,num_gens:int)->list:gens_params=[]for_inrange(num_gens):gens_params.append(one_gen)returngens_paramsdefone_max(gens:list)->float:returnsum(gens)/len(gens)my_ga=CollectorGA(fitness=HyperbolaFitness(obj_function=one_max,obj_value=1),selection=TournamentSelection(5),crossover=OnePointCrossover(),mutation=BinStringMutation(0.15),new_generation=NewGeneration('best'))my_ga.set_population(population=BinaryPopulation,num_individ=100,num_generations=100,gens=generate_gens_params([0,1,1],30),early_stop=35)my_ga.optimize()This example demonstrates the optimization of function one_max() using elements of binary genetic algorithm.Components Used:GaData: Class for holding and managing data related to a genetic algorithm run.OrderCatPopulation: Class for representing ordered categorical population in a genetic algorithm. In this case we set the first population manually usingin_pop- a list consisting of words anagrams to 'ALGORITHM'.HyperbolaFitness: Class for calculating fitness value using the hyperbola approach. Object function is levenstein distance between the evolved string and the target string 'ALGORITHM'.TournamentSelection: Selection method used, which operates on tournament-based selection logic.OrderCrossover: The crossover mechanism used in the genetic algorithm.InversionMutation: Mutation method, introducing randomness in the population.NewGeneration: Utility for generating new population members based on chosen criteria.How it works:The genetic algorithm data parameters are initialized, and the initial population is set and filled.The fitness of each individual in the population is calculated based on it`s distance from the target word 'ALGORITHM'.In each generation:The tournament-based selection method is applied.Pairs of individuals undergo crossover using the order-based crossover mechanism.Mutation is applied to individuals with some probability.A new generation is created based on the best individuals.Fitness is recalculated for the new generation.The genetic algorithm either runs for a predefined number of generations or stops early if there hasn't been an improvement in the population fitness for a specified number of generations.The result is the closest approximation found to the word 'algorithm'.DocumentationStill in progress. For now, you can read brief description of the library classes.BinaryGAClass for perform binary genetic algorithm.
Supports the following parameters:num_generations (int)- number of generations;num_individ (int)- number of individuals in generation (size of population);gens (tuple)- controls the gens type;obj_function (Callable)- object function with 1 or 2 arguments, my_func(gens: list) or
my_func(input_data: Any, gens: list);obj_value (int | float, default: None)- if object value exists, GA will optimize to the value,
else GA will optimize to min;input_data (Any, default: None)- argument for object function, you can pass any additional information to object function;penalty (class PenaltyFunction, default: None)- subclass of PenaltyFunction(), used for conditional optimization;conditions (list of strings (optimizer and conditionals), default: None.)-  3 value can be use: 'optimize', '<=', '!=';is_gray (bool, default: False)- ability to use gray code instead of binary representation;children_percent (float, default: 0.95)- percent of children in new generation;early_stop (int, default: 10)- early stopping criteria, number of generation without improve;input_population (list[list], default: None)- first generation from user to improve ga work;tournament_size (int, default: 3)- size of tournament in selection;mutation_lvl (str | float, default: 'normal')- mutation probability, can accept float value or string: 'weak', 'normal', 'strong';transfer_parents (str, default: "best")- type of transfer parents: "best" or "random".CombinatoryGA and CategoricalGAClass for perform combinatory genetic algorithm (categorical order combinations without repetitions).
Supports all above parameters exceptis_gray.GaDataClass for holding and managing data related to a genetic algorithm run. Supports the following parameters:num_generations (int)- number of generations;children_percent (float, default: 0.95)- percent of children in new generation;early_stop (int, default: 10)- early stopping criteria, number of generation without improve.Attributes:idx_generation (int)- index of the current generation;num_generation_no_improve (int)- number of consecutive generations with no improvement;population (BasePopulation)- current population of individuals;parents (BasePopulation)- selected parent individuals for crossover;children (BasePopulation)- offspring individuals produced by crossover;historical_best (list)- list of historical best scores for each generation;historical_mediocre (list)- list of historical average scores for each generation;historical_worst (list)- list of historical worst scores for each generation;best_solution (dict)- dictionary representing the best individual solution found so far;gen_pool (tuple)- in case of categorical GA is tuple of possible values for each gene.NewGenerationClass for creating a new generation of individuals in a genetic algorithm. Supports the following parameter:transfer_parents (str, default: 'best')- strategy for transferring certain amount of parents to the next generation. Can be 'best' or 'random'.DynamicPenaltyClass for creating and calculating penalty for conditional optimization.Only 2 types of conditional:g(x) <= 0orh(x) != 0.Example:my_obj_func(x1,x2):returnx1**2+x2**2,1-x1+x2,x1+x2dp=DynamicPenalty()HyperbolaFitness(obj_function=my_func,obj_value=0,penalty=dp,conditions=['optimize','<=','!='])HyperbolaFitnessClass for calculating fitness value using the hyperbola approach. Supports the following parameters:obj_function (Callable)- object function with 1 or 2 arguments, my_func(gens: list) or
my_func(input_data: Any, gens: list);obj_value (int | float, default: None)- if object value exists, GA will optimize to the value,
else GA will optimize to min;input_data (Any, default: None)- argument for object function, you can pass any additional information to object function;penalty (class BasePenalty, default: None)- subclass of BasePenalty(), used for conditional optimization;conditions: (list of strings, default: None)- 3 value can be use: 'optimize', '<=', '!='.Classes for populationsBinaryPopulation()BinaryGrayPopulation()CatPopulation()OrderCatPopulation()All classes support the following parameters:num_individ (int)- number of individuals in generation (size of population);gens (tuple)- controls the gens type;input_population (list[list], default: None)- optional input population to be used for initialization.Classes for selection methodsFor all types GA:BalancedSelection()RankedSelection()TournamentSelection() - supportstournament_sizeparameter with default value - 3.Classes for crossover methodsFor binary and categorical GA:OnePointCrossover()TwoPointCrossover()UniformCrossover()For combinatory GA:OrderCrossover()Classes for mutation methodsFor binary GA:BinStringMutation()For combinatory GA:InversionMutation()MovementMutation()ShiftMutation()SwapMutation()For categorical GA:CategoricalMutation()This classes support one parameter -mutation_lvl. Can be string ('weak', 'normal', 'strong') or a float from 0 to 1. Default value - 'normal'.Random seedFor random seed usebaumeva.generator.rnd_seed = numberbefore GA implementation, wherenumberis any integer value.LicenseThe BaumEvA library is distributed under the MIT License. See theLICENSEfile for more information.ContributionContributions are welcome! If you encounter any issues or have suggestions for improvements, please open an issue on theGitHub repository.ContactFor any inquiries or questions, you can reach out to the author via email atvatutu@gmail.com.