pygad Module¶
This section of the documentation discusses the pygad module.
With the pygad module, you can create, run, save, and load instances of the genetic algorithm. It solves both single-objective and multi-objective optimization problems.
pygad.GA Class¶
The pygad module has a class named GA for building the genetic algorithm. This section explains the class constructor, its methods, functions, and attributes.
__init__()¶
To create an instance of the pygad.GA class, the constructor accepts several parameters. These let you adjust the genetic algorithm for different types of applications.
The pygad.GA class constructor supports the parameters below, grouped by purpose. Click a parameter to expand its full description.
Population and Generations¶
Fitness Function¶
Genes: Values and Types¶
Parent Selection¶
Keeping Solutions¶
Crossover¶
Mutation¶
Lifecycle Callbacks¶
Saving and Logging¶
Performance and Reproducibility¶
You do not have to set all of these parameters when you create an instance of the GA class. The most important one is fitness_func, which defines the fitness function.
It is OK to set the value of any of the 2 parameters init_range_low and init_range_high to be equal, higher, or lower than the other parameter (i.e. init_range_low is not needed to be lower than init_range_high). The same holds for the random_mutation_min_val and random_mutation_max_val parameters.
If both the mutation_type and crossover_type parameters are None, then the genetic algorithm cannot evolve at all. As a result, it cannot find a solution better than the best solution in the initial population.
The parameters are validated by calling the validate_parameters() method of the utils.validation.Validation class inside the constructor. If any parameter is not correct, an exception is raised and the valid_parameters attribute is set to False.
Extended Classes¶
To keep the library modular and structured, the code is split into several scripts, where each script has one or more classes. Each class has its own purpose.
Here is the list of scripts and the classes that the pygad.GA class extends:
utils/engine.py:utils.engine.GAEngine: Runs the GA loop and owns the run-time lifecycle helpers.
utils/validation.pyutils.validation.Validation: Validates every constructor parameter and dispatchesparent_selection_type/crossover_type/mutation_typeto the right method.
utils/parent_selection.pyutils.parent_selection.ParentSelection: All built-in parent selection operators, includingnsga2_selection,tournament_selection_nsga2,nsga3_selection, andtournament_selection_nsga3.
utils/crossover.pyutils.crossover.Crossover: Built-in crossover operators.
utils/mutation.pyutils.mutation.Mutation: Built-in mutation operators.
utils/nsga.pyutils.nsga.NSGA: Building blocks shared by NSGA-II and NSGA-III (non_dominated_sorting,get_non_dominated_set).
utils/nsga2.pyutils.nsga2.NSGA2: NSGA-II specific primitives (crowding_distance,sort_solutions_nsga2).
utils/nsga3.pyutils.nsga3.NSGA3: NSGA-III algorithm primitives (reference points, ideal point, extreme points, intercepts, normalization, association, niching).
utils/report.pyutils.report.Report: Builds a PDF report of the run (generate_report).
helper/unique.pyhelper.unique.Unique: Routines that resolve duplicate genes inside a solution.
helper/misc.pyhelper.misc.Helper: Generic helpers used across the library (population dtype handling, per-gene value generation, constraint sampling, lifecycle summary).
visualize/plot.pyvisualize.plot.Plot: All plot methods. Seepygad.visualize.
Since the pygad.GA class extends such classes, the attributes and methods inside them can be retrieved by instances of the pygad.GA class.
Class Attributes¶
supported_int_types: A list of the supported types for the integer numbers.supported_float_types: A list of the supported types for the floating-point numbers.supported_int_float_types: A list of the supported types for all numbers. It just concatenates the previous 2 lists.
Other Instance Attributes & Methods¶
All the parameters and functions passed to the pygad.GA class constructor are used as class attributes and methods in the instances of the pygad.GA class. In addition to such attributes, there are other attributes and methods added to the instances of the pygad.GA class.
The
GAclass gains the attributes of its parent classes via inheritance, making them accessible through theGAobject even if they are defined externally to its specific class body.
Names that begin with an underscore (for example
_bootstrap_nsga3_reference_points) are internal helpers. They are listed below for completeness but are not part of the stable API; do not rely on their signature staying the same across releases.
Lifecycle¶
Attributes¶
generations_completed: Number of the last completed generation.run_completed: Set toTrueonly after therun()method completes gracefully.valid_parameters: Set toTruewhen all the parameters passed in theGAclass constructor are valid.run_start_time: Monotonic clock value captured right before the generation loop starts. Internal.logger: Logger object from theloggingmodule. Supported in PyGAD 3.0.0.
Methods¶
run(): Runs the generation loop. The main entry point.run_loop_head(best_solution_fitness): Per-generation pre-loop bookkeeping. Internal; called from insiderun(). Added in PyGAD 3.3.1.run_select_parents(call_on_parents=True): Select parents and callon_parentswhen defined. Internal; called from insiderun(). Passcall_on_parents=Falsewhen refreshing the parent set at the end ofrun(). Added in PyGAD 3.3.1.run_crossover(): Apply crossover and callon_crossoverwhen defined. Internal. Added in PyGAD 3.3.1.run_mutation(): Apply mutation and callon_mutationwhen defined. Internal. Added in PyGAD 3.3.1.run_update_population(): Replaceself.populationwith the crossed-over and mutated offspring. Internal. Added in PyGAD 3.3.1.summary(...): Prints a Keras-like summary of the PyGAD lifecycle. Added in PyGAD 2.19.0. See Print Lifecycle Summary.
Population and Initialization¶
Attributes¶
population: A NumPy array that initially holds the initial population and is later updated after each generation.initial_population: Frozen copy of the initial population, set afterinitialize_populationruns.pop_size: A(sol_per_pop, num_genes)tuple describing the population shape.gene_type_single:Truewhen every gene shares the same dtype;Falsewhengene_typeis a list/tuple/numpy.ndarray. Added in PyGAD 2.14.0.gene_space_unpacked: Unpacked version ofgene_space. For example,range(1, 5)becomes[1, 2, 3, 4];{'low': 2, 'high': 4}becomes a finite sample. Added in PyGAD 3.1.0.
Methods¶
initialize_population(allow_duplicate_genes, gene_type, gene_constraint): Build the initial population, apply gene types and constraints, resolve duplicates when not allowed.initialize_parents_array(shape): Allocate an empty parents (or offspring) array with the right dtype.change_population_dtype_and_round(population): Cast a 2D population to the dtype encoded inself.gene_typeand round non-integer genes.change_gene_dtype_and_round(gene_index, gene_value): Same as above, but for a single gene value.round_genes(solutions): Round genes in a 2D array according toself.gene_typeprecision.get_initial_population_range(gene_index): Return the[init_range_low, init_range_high]window for a specific gene.get_random_mutation_range(gene_index): Return the[random_mutation_min_val, random_mutation_max_val]window for a specific gene.get_gene_dtype(gene_index): Return the(type, precision)pair for a specific gene.generate_gene_value(...): Sample a single gene value from the gene space or from the configured range.generate_gene_value_from_space(...): Sample a single gene value fromgene_space.generate_gene_value_randomly(...): Sample a single gene value from the configured numeric range.
Fitness¶
Attributes¶
last_generation_fitness: Fitness values of the solutions in the last generation. Added in PyGAD 2.12.0.previous_generation_fitness: Fitness of the population one step beforelast_generation_fitness. Used to skip re-evaluating solutions PyGAD has already seen. Added in PyGAD 2.16.2.best_solutions_fitness: List of best-solution fitness per generation.best_solutions: A NumPy array of the best solution per generation. Only populated whensave_best_solutions=True.best_solutions_fitness: Fitness for every entry inbest_solutions.solutions: All visited solutions whensave_solutions=True.solutions_fitness: Fitness for every entry insolutions.best_solution_generation: Generation at which the best fitness was reached.-1untilrun()completes.
Methods¶
cal_pop_fitness(): Compute the fitness of every solution in the current population, reusing previously calculated values where possible.best_solution(pop_fitness=None): Return the best solution, its fitness, and its population index.adaptive_mutation_population_fitness(offspring): Average fitness used by adaptive mutation to split solutions into low / high quality.
Parent Selection (general)¶
Attributes¶
last_generation_parents: Parents selected in the last generation. Added in PyGAD 2.12.0.last_generation_parents_indices: Indices of the selected parents inself.population. Added in PyGAD 2.15.0.
Methods¶
select_parents(fitness, num_parents): Active parent-selection method. Bound during validation according toparent_selection_type.steady_state_selection(fitness, num_parents): Steady-state selection.rank_selection(fitness, num_parents): Rank-based selection.random_selection(fitness, num_parents): Random selection.tournament_selection(fitness, num_parents): K-tournament selection.roulette_wheel_selection(fitness, num_parents): Roulette-wheel selection.stochastic_universal_selection(fitness, num_parents): SUS selection.wheel_cumulative_probs(probs, num_parents): Build the[start, end)ranges used by RWS and SUS.
Multi-Objective Optimization (NSGA-II)¶
Attributes¶
pareto_fronts: List of the Pareto fronts of the last generation when running a multi-objective problem. Each front is a NumPy array of(population_index, fitness_vector)pairs. Added in PyGAD 3.2.0.
Methods¶
non_dominated_sorting(fitness): Sort the population into Pareto fronts. Defined inutils.nsga.NSGAand shared with NSGA-III.get_non_dominated_set(curr_solutions): Split the current set of solutions into a dominated and non-dominated subset. Defined inutils.nsga.NSGA.crowding_distance(pareto_front, fitness): Per-solution crowding distance inside a Pareto front. Defined inutils.nsga2.NSGA2.sort_solutions_nsga2(fitness, find_best_solution=False): Sort population indices best-to-worst using Pareto fronts and crowding distance for MOO; descending fitness for SOO. Defined inutils.nsga2.NSGA2.nsga2_selection(fitness, num_parents): NSGA-II parent selection. Defined inutils.parent_selection.ParentSelection.tournament_selection_nsga2(fitness, num_parents): K-tournament with non-dominated rank + crowding distance as tiebreakers. Defined inutils.parent_selection.ParentSelection.
Multi-Objective Optimization (NSGA-III)¶
Attributes¶
nsga3_num_divisions: Stored value of thensga3_num_divisionsconstructor parameter. Used when building the reference grid.nsga3_reference_points: Structured grid of reference points on the unit simplex. A 2D NumPy array of shape(n_points, num_objectives)where each row sums to 1. Built once before the generation loop starts (_bootstrap_nsga3_reference_points). Re-used for every generation.
Methods (algorithm primitives in utils.nsga3.NSGA3)¶
nsga3_generate_reference_points(num_objectives, num_divisions): Build the Das-Dennis grid.nsga3_compute_ideal_point(fitness): Best fitness per objective across the input rows (column max under maximization).nsga3_find_extreme_points(fitness, ideal_point, epsilon=NSGA3_ASF_EPSILON): For each objective, find the row that best represents the corner of that axis using the ASF.nsga3_compute_intercepts(extreme_points, ideal_point, fallback_fitness): Fit a hyperplane through the extreme points and return per-axis intercepts. Falls back to the nadir on singular systems.nsga3_normalize_fitness(fitness, ideal_point, intercepts): Scale each fitness row to the unit hypercube and clip outliers to[0, 1].nsga3_associate_to_reference_points(normalized, reference_points): For every normalized row, find the closest reference line and the perpendicular distance to it.nsga3_niching_select(critical_front_indices, critical_front_associations, critical_front_distances, accepted_associations, num_reference_points, num_to_select): Niching loop that picks survivors from the critical front to preserve diversity across reference points.
Methods (selection in utils.parent_selection.ParentSelection)¶
nsga3_selection(fitness, num_parents): NSGA-III parent selection.tournament_selection_nsga3(fitness, num_parents): K-tournament with niche count + perpendicular distance as tiebreakers._nsga3_pick_critical_front_survivors(...): Run normalization and niching onP_next ∪ critical_frontand return the picked survivors. Internal._nsga3_pick_tournament_winner(...): Decide the winner of one K-tournament round under NSGA-III rules. Internal._nsga3_build_parents(final_indices, num_parents): Copy the chosen rows out of the population into a new parents array. Internal.
Methods (bootstrap and population growth in utils.engine.GAEngine)¶
_bootstrap_nsga3_reference_points(): Build the reference-point grid once, right after the first fitness evaluation. Calls_nsga3_grow_populationwhensol_per_popis smaller than the reference count._nsga3_grow_population(required_size, num_objectives): Append random solutions toself.population, updatesol_per_pop/pop_size/num_offspring, re-evaluate fitness._nsga3_generate_extra_random_solutions(count): Buildcountrandom solutions respecting the gene space, init range, gene type, gene constraints, andallow_duplicate_genesrules._nsga3_generate_single_random_gene(gene_idx, partial_solution): Sample a single gene value using initial-population settings (not mutation settings)._nsga3_apply_gene_constraints(population): Enforcegene_constrainton the new rows._nsga3_resolve_duplicate_genes(population): Resolve duplicate genes in the new rows whenallow_duplicate_genes=False.
Module-level helpers (in pygad.utils.nsga3)¶
NSGA3_ASF_EPSILON: Off-axis weight used by the ASF insidensga3_find_extreme_points.NSGA3_INTERCEPT_NEAR_ZERO: Threshold under which an intercept gap is treated as zero._nsga3_pick_target_reference_point(niche_counts, critical_front_associations, remaining_positions): Choose the next reference point for the niching loop. Internal._nsga3_pick_candidate_at_reference(candidates_at_target, critical_front_distances, niche_count_at_target): Choose a candidate at a given reference point. Internal._nsga3_enumerate_compositions(num_objectives, num_divisions): Yield every non-negative integer tuple summing tonum_divisions. Internal.
Module-level helpers (in pygad.utils.parent_selection)¶
_nsga3_validate_multi_objective_fitness(fitness, supported_int_float_types, method_name): Raise when the GA was set to NSGA-III but the fitness function returned scalars._nsga3_accumulate_fronts(pareto_fronts, num_parents): Walk the Pareto fronts and split them into the accepted set + the critical front.
Crossover¶
Attributes¶
last_generation_offspring_crossover: Offspring after crossover. Added in PyGAD 2.12.0.
Methods¶
crossover(): Active crossover operator. Bound during validation according tocrossover_type.single_point_crossover(parents, offspring_size): Single-point crossover.two_points_crossover(parents, offspring_size): Two-point crossover.uniform_crossover(parents, offspring_size): Uniform crossover.scattered_crossover(parents, offspring_size): Scattered crossover.sbx_crossover(parents, offspring_size): Simulated binary crossover. Usesself.sbx_crossover_eta.
Mutation¶
Attributes¶
last_generation_offspring_mutation: Offspring after mutation. Added in PyGAD 2.12.0.last_generation_offspring_mutation_indices: Indices of mutated offspring insideself.population.
Methods¶
mutation(): Active mutation operator. Bound during validation according tomutation_type.random_mutation(offspring): Random mutation (replaces or adds a uniform random value).swap_mutation(offspring): Swap mutation.inversion_mutation(offspring): Inversion mutation.scramble_mutation(offspring): Scramble mutation.adaptive_mutation(offspring): Adaptive mutation. Usesadaptive_mutation_population_fitness.polynomial_mutation(offspring): Polynomial mutation. Usesself.polynomial_mutation_eta.mutation_change_gene_dtype_and_round(...): Round and re-cast a mutated gene to the configured dtype/precision.
Elitism¶
Attributes¶
last_generation_elitism: Elitism solutions from the last generation. Added in PyGAD 2.18.0.last_generation_elitism_indices: Population indices oflast_generation_elitism. Added in PyGAD 2.19.0.
Gene Constraints and Duplicate Resolution¶
Methods¶
validate_gene_constraint_callable_output(selected_values, values): Sanity-check the return value of a user-definedgene_constraint.filter_gene_values_by_constraint(values, solution, gene_idx): Rungene_constraint[gene_idx]and return the filtered list.get_valid_gene_constraint_values(...): Sample candidate values until one satisfies the gene constraint.solve_duplicate_genes_randomly(...): Resolve duplicate genes by sampling new values from the random range.solve_duplicate_genes_by_space(...): Resolve duplicate genes by sampling new values fromgene_space.solve_duplicates_deeply(...): Slow, exhaustive fallback for duplicate resolution.unique_int_gene_from_range(...): Pick an integer gene that does not already appear in the solution.unique_float_gene_from_range(...): Pick a float gene that does not already appear in the solution.unique_gene_by_space(...): Pick a unique value fromgene_space.unique_genes_by_space(...): Pick unique values for several genes fromgene_space.select_unique_value(...): Sample one value uniformly at random from a list of candidates.find_two_duplicates(solution): Locate the first pair of duplicated indices in a solution.unpack_gene_space(...): Materialize the unpackedgene_space(used to buildgene_space_unpacked).
Saving, Loading, and Reporting¶
Methods¶
save(filename): Pickle the GA instance to disk (usescloudpickle).generate_report(filename, ...): Build a PDF report of the run. Seegenerate_report()below.push_to_vilvik(...): Optional convenience wrapper around the Vilvik SDK.
Note that the attributes with names starting with last_generation_ are updated after each generation.
The next sections discuss the methods available in the pygad.GA class.
save()¶
The save() method in the pygad.GA class saves the genetic algorithm instance as a pickled object.
Accepts the following parameter:
filename: Name of the file to save the instance. No extension is needed.
generate_report()¶
Builds a PDF report of the current GA run. It bundles the configuration table, a run-summary table, the best solution, and every applicable plot. Requires the optional report extra:
pip install pygad[report]
Call it after run() finishes. A minimal example:
ga_instance.run()
ga_instance.generate_report("my_run") # writes my_run.pdf next to the script
Parameters:
filename(str, required): Output path..pdfis appended automatically if missing.title(strorNone, defaultNone): Title shown on the first page. Defaults to"PyGAD run report".sections(iterable ofstrorNone, defaultNone): Sections to include and their order. Valid entries are"title","configuration","run_summary","best_solution","plots", and"notes". WhenNone, every section is included in their default order.include_plots(iterable ofstr,"all", orNone, defaultNone): Plots to embed under the"plots"section.Noneor"all"auto-selects every plot whose preconditions are met by this run. Pass a list of plot method names to include only those.figure_size_inches((float, float), default(7.0, 4.5)): Width and height (in inches) used when each plot is drawn for the report.notes(strorNone, defaultNone): Free-form text rendered in the optional"notes"section.page_size(str, default"letter"): Either"letter"or"A4".
The report skips any plot whose preconditions are not met. For example, plot_pareto_front_curve is included only for multi-objective runs with 2 or 3 objectives; plot_non_dominated_hypervolume is included only when save_solutions=True is set on the GA. A full example lives at examples/example_generate_report.py.
The title page shows the PyGAD logo. The image ships with the package, so it works without network access. If the image file is missing, the report is built without it.
Functions in pygad¶
Besides the methods available in the pygad.GA class, this section discusses the functions available in pygad. Up to this time, there is only a single function named load().
pygad.load()¶
Reads a saved instance of the genetic algorithm. This is not a method but a function that is indented under the pygad module. So, it could be called by the pygad module as follows: pygad.load(filename).
Accepts the following parameter:
filename: Name of the file holding the saved instance of the genetic algorithm. No extension is needed.
Returns the genetic algorithm instance.
Using PyGAD¶
A step-by-step walkthrough to build and run the genetic algorithm.
How a generation runs and where each callback is called.
Examples¶
This section gives the complete code of some examples that use pygad. Each subsection builds a different example.
Clustering¶
For a 2-cluster problem, the code is available here. For a 3-cluster problem, the code is here. The 2 examples are using artificial samples.
Soon a tutorial will be published at Paperspace to explain how clustering works using the genetic algorithm with examples in PyGAD.
CoinTex Game Playing using PyGAD¶
The code is available at the CoinTex GitHub project. CoinTex is an Android game written in Python using the Kivy framework. Find CoinTex at Google Play: https://play.google.com/store/apps/details?id=coin.tex.cointexreactfast
Check this Paperspace tutorial for how the genetic algorithm plays CoinTex: https://blog.paperspace.com/building-agent-for-cointex-using-genetic-algorithm. Check also this YouTube video showing the genetic algorithm while playing CoinTex.