diff --git a/src/crossover/crossover_methods.py b/src/crossover/crossover_methods.py index 8bb6a00..578f0b0 100644 --- a/src/crossover/crossover_methods.py +++ b/src/crossover/crossover_methods.py @@ -1,6 +1,6 @@ import random -def append_to_next_population(population_method): +def _append_to_next_population(population_method): """Appends the new chromosomes to the next population. Also modifies the input to include the mating pool. """ @@ -11,7 +11,7 @@ def append_to_next_population(population_method): ) -def check_weight(individual_method): +def _check_weight(individual_method): """Checks if the weight is between 0 and 1 before running. Exception may occur when using ga.adapt, which will catch the error and try again with valid weight. @@ -27,7 +27,7 @@ def check_weight(individual_method): return new_method -def genes_to_chromosome(individual_method): +def _genes_to_chromosome(individual_method): """Converts a collection of genes into a chromosome. Note: Will recreate the gene list if given gene list. Built-in methods do not construct gene lists @@ -40,7 +40,7 @@ def genes_to_chromosome(individual_method): ) -def values_to_genes(individual_method): +def _values_to_genes(individual_method): """Converts a collection of values into genes. Returns a generator of genes to avoid storing a new list. """ @@ -55,18 +55,18 @@ def values_to_genes(individual_method): class Crossover_Methods: - # Private method decorators, see above. - _append_to_next_population = append_to_next_population - _check_weight = check_weight - _genes_to_chromosome = genes_to_chromosome - _values_to_genes = values_to_genes + # Allowing access to decorators when importing class + _append_to_next_population = _append_to_next_population + _check_weight = _check_weight + _genes_to_chromosome = _genes_to_chromosome + _values_to_genes = _values_to_genes class Population: """Methods for selecting chromosomes to crossover.""" - @append_to_next_population + @_append_to_next_population def sequential_selection(ga, mating_pool): """Select sequential pairs from the mating pool. Every parent is paired with the previous parent. @@ -82,7 +82,7 @@ class Crossover_Methods: ) - @append_to_next_population + @_append_to_next_population def random_selection(ga, mating_pool): """Select random pairs from the mating pool. Every parent is paired with a random parent. @@ -101,8 +101,8 @@ class Crossover_Methods: """Methods for crossing parents.""" - @check_weight - @genes_to_chromosome + @_check_weight + @_genes_to_chromosome def single_point(ga, parent_1, parent_2, weight = 0.5): """Cross two parents by swapping genes at one random point.""" @@ -124,15 +124,15 @@ class Crossover_Methods: return parent_2[:-swap_index] + parent_1[-swap_index:] - @check_weight - @genes_to_chromosome + @_check_weight + @_genes_to_chromosome def multi_point(ga, parent_1, parent_2, weight = 0.5): """Cross two parents by swapping genes at multiple points.""" pass - @check_weight - @genes_to_chromosome + @_check_weight + @_genes_to_chromosome def uniform(ga, parent_1, parent_2, weight = 0.5): """Cross two parents by swapping all genes randomly.""" @@ -143,8 +143,8 @@ class Crossover_Methods: class Arithmetic: """Crossover methods for numerical genes.""" - @genes_to_chromosome - @values_to_genes + @_genes_to_chromosome + @_values_to_genes def average(ga, parent_1, parent_2, weight = 0.5): """Cross two parents by taking the average of the genes.""" @@ -161,8 +161,8 @@ class Crossover_Methods: yield value - @genes_to_chromosome - @values_to_genes + @_genes_to_chromosome + @_values_to_genes def extrapolate(ga, parent_1, parent_2, weight = 0.5): """Cross two parents by extrapolating towards the first parent. @@ -182,9 +182,9 @@ class Crossover_Methods: yield value - @check_weight - @genes_to_chromosome - @values_to_genes + @_check_weight + @_genes_to_chromosome + @_values_to_genes def random(ga, parent_1, parent_2, weight = 0.5): """Cross two parents by taking a random integer or float value between each of the genes.""" diff --git a/src/mutation/mutation_methods.py b/src/mutation/mutation_methods.py index fb3acf0..594f750 100644 --- a/src/mutation/mutation_methods.py +++ b/src/mutation/mutation_methods.py @@ -1,7 +1,7 @@ import random from math import ceil -def check_chromosome_mutation_rate(population_method): +def _check_chromosome_mutation_rate(population_method): """Checks if the chromosome mutation rate is a float between 0 and 1 before running.""" def new_method(ga): @@ -18,7 +18,7 @@ def check_chromosome_mutation_rate(population_method): return new_method -def check_gene_mutation_rate(individual_method): +def _check_gene_mutation_rate(individual_method): """Checks if the gene mutation rate is a float between 0 and 1 before running.""" def new_method(ga, index): @@ -35,7 +35,7 @@ def check_gene_mutation_rate(individual_method): return new_method -def reset_fitness(individual_method): +def _reset_fitness(individual_method): """Resets the fitness value of the chromosome.""" def new_method(ga, chromosome): @@ -45,7 +45,7 @@ def reset_fitness(individual_method): return new_method -def loop_random_selections(population_method): +def _loop_random_selections(population_method): """Runs the population method until enough chromosomes are mutated. Provides the indexes of selected chromosomes to mutate using random.sample to get all indexes fast. @@ -63,7 +63,7 @@ def loop_random_selections(population_method): return new_method -def loop_random_mutations(individual_method): +def _loop_random_mutations(individual_method): """Runs the individual method until enough genes are mutated on the indexed chromosome. """ @@ -83,27 +83,26 @@ def loop_random_mutations(individual_method): class Mutation_Methods: - # Private method decorators, see above. - _check_chromosome_mutation_rate = check_chromosome_mutation_rate - _check_gene_mutation_rate = check_gene_mutation_rate - _reset_fitness = reset_fitness - _loop_random_selections = loop_random_selections - _loop_random_mutations = loop_random_mutations + _check_chromosome_mutation_rate = _check_chromosome_mutation_rate + _check_gene_mutation_rate = _check_gene_mutation_rate + _reset_fitness = _reset_fitness + _loop_random_selections = _loop_random_selections + _loop_random_mutations = _loop_random_mutations class Population: """Methods for selecting chromosomes to mutate""" - @check_chromosome_mutation_rate - @loop_random_selections + @_check_chromosome_mutation_rate + @_loop_random_selections def random_selection(ga, index): """Selects random chromosomes.""" ga.mutation_individual_impl(ga, ga.population[index]) - @check_chromosome_mutation_rate - @loop_random_selections + @_check_chromosome_mutation_rate + @_loop_random_selections def random_avoid_best(ga, index): """Selects random chromosomes while avoiding the best chromosomes. (Elitism)""" @@ -114,9 +113,9 @@ class Mutation_Methods: class Individual: """Methods for mutating a single chromosome.""" - @check_gene_mutation_rate - @reset_fitness - @loop_random_mutations + @_check_gene_mutation_rate + @_reset_fitness + @_loop_random_mutations def individual_genes(ga, chromosome, index): """Mutates a random gene in the chromosome.""" @@ -137,9 +136,9 @@ class Mutation_Methods: """Methods for mutating a chromosome by numerically modifying the genes.""" - @check_gene_mutation_rate - @reset_fitness - @loop_random_mutations + @_check_gene_mutation_rate + @_reset_fitness + @_loop_random_mutations def reflect_genes(ga, chromosome, index): """Reflects genes against the best chromosome.""" @@ -152,9 +151,9 @@ class Mutation_Methods: """Methods for mutating a chromosome by changing the order of the genes.""" - @check_gene_mutation_rate - @reset_fitness - @loop_random_mutations + @_check_gene_mutation_rate + @_reset_fitness + @_loop_random_mutations def swap_genes(ga, chromosome, index): """Swaps two random genes in the chromosome.""" diff --git a/src/parent_selection/parent_selection_methods.py b/src/parent_selection/parent_selection_methods.py index 08ab105..2542d86 100644 --- a/src/parent_selection/parent_selection_methods.py +++ b/src/parent_selection/parent_selection_methods.py @@ -1,6 +1,6 @@ import random -def check_selection_probability(selection_method): +def _check_selection_probability(selection_method): """Raises an exception if the selection_probability is not between 0 and 1. Otherwise runs the selection method. @@ -15,7 +15,7 @@ def check_selection_probability(selection_method): return new_method -def check_positive_fitness(selection_method): +def _check_positive_fitness(selection_method): """Raises an exception if the population contains a chromosome with negative fitness. Otherwise runs the selection method. @@ -30,7 +30,7 @@ def check_positive_fitness(selection_method): return new_method -def ensure_sorted(selection_method): +def _ensure_sorted(selection_method): """Sorts the population by fitness and then runs the selection method. """ @@ -42,7 +42,7 @@ def ensure_sorted(selection_method): return new_method -def compute_parent_amount(selection_method): +def _compute_parent_amount(selection_method): """Computes the amount of parents needed to be selected, and passes it as another argument for the method. @@ -57,11 +57,11 @@ def compute_parent_amount(selection_method): class Parent_Selection: - # Private method decorators, see above. - _check_selection_probability = check_selection_probability - _check_positive_fitness = check_positive_fitness - _ensure_sorted = ensure_sorted - _compute_parent_amount = compute_parent_amount + # Allowing access to decorators when importing class + _check_selection_probability = _check_selection_probability + _check_positive_fitness = _check_positive_fitness + _ensure_sorted = _ensure_sorted + _compute_parent_amount = _compute_parent_amount class Rank: @@ -69,9 +69,9 @@ class Parent_Selection: i.e. the n-th best chromosome has a fixed probability of being selected, regardless of their chances""" - @check_selection_probability - @ensure_sorted - @compute_parent_amount + @_check_selection_probability + @_ensure_sorted + @_compute_parent_amount def tournament(ga, parent_amount): """ Will make tournaments of size tournament_size and choose the winner (best fitness) @@ -108,9 +108,9 @@ class Parent_Selection: return - @check_selection_probability - @ensure_sorted - @compute_parent_amount + @_check_selection_probability + @_ensure_sorted + @_compute_parent_amount def stochastic(ga, parent_amount): """ Selects parents using the same probability approach as tournament selection, @@ -133,10 +133,10 @@ class Parent_Selection: class Fitness: - @check_selection_probability - @ensure_sorted - @check_positive_fitness - @compute_parent_amount + @_check_selection_probability + @_ensure_sorted + @_check_positive_fitness + @_compute_parent_amount def roulette(ga, parent_amount): """Roulette selection works based off of how strong the fitness is of the chromosomes in the population. The stronger the fitness the higher the probability @@ -175,9 +175,9 @@ class Parent_Selection: break - @check_selection_probability - @ensure_sorted - @compute_parent_amount + @_check_selection_probability + @_ensure_sorted + @_compute_parent_amount def stochastic(ga, parent_amount): """ Selects parents using the same probability approach as roulette selection, diff --git a/src/survivor_selection/survivor_selection_methods.py b/src/survivor_selection/survivor_selection_methods.py index d4c9a65..2ba1972 100644 --- a/src/survivor_selection/survivor_selection_methods.py +++ b/src/survivor_selection/survivor_selection_methods.py @@ -1,6 +1,6 @@ import random -def append_to_next_population(survivor_method): +def _append_to_next_population(survivor_method): """Appends the selected chromosomes to the next population.""" return lambda ga:\ @@ -10,11 +10,11 @@ def append_to_next_population(survivor_method): class Survivor_Selection: """Survivor selection determines which individuals should be brought to the next generation""" - # Private method decorator, see above. - _append_to_next_population = append_to_next_population + # Allowing access to decorators when importing class + _append_to_next_population = _append_to_next_population - @append_to_next_population + @_append_to_next_population def fill_in_best(ga): """Fills in the next population with the best chromosomes from the last population""" @@ -22,7 +22,7 @@ class Survivor_Selection: return ga.population[:needed_amount] - @append_to_next_population + @_append_to_next_population def fill_in_random(ga): """Fills in the next population with random chromosomes from the last population""" @@ -30,7 +30,7 @@ class Survivor_Selection: return random.sample(ga.population, needed_amount) - @append_to_next_population + @_append_to_next_population def fill_in_parents_then_random(ga): """Fills in the next population with all parents followed by random chromosomes from the last population""" diff --git a/src/termination_point/termination_methods.py b/src/termination_point/termination_methods.py index 920f82a..0cdb3fb 100644 --- a/src/termination_point/termination_methods.py +++ b/src/termination_point/termination_methods.py @@ -1,4 +1,4 @@ -def add_by_fitness_goal(termination_impl): +def _add_by_fitness_goal(termination_impl): """Adds termination by fitness goal to the method.""" def new_method(ga): @@ -20,7 +20,7 @@ def add_by_fitness_goal(termination_impl): return new_method -def add_by_generation_goal(termination_impl): +def _add_by_generation_goal(termination_impl): """Adds termination by generation goal to the method.""" def new_method(ga): @@ -35,7 +35,7 @@ def add_by_generation_goal(termination_impl): return new_method -def add_by_tolerance_goal(termination_impl): +def _add_by_tolerance_goal(termination_impl): """Adds termination by tolerance goal to the method.""" def new_method(ga): @@ -59,15 +59,15 @@ def add_by_tolerance_goal(termination_impl): class Termination_Methods: """Example functions that can be used to terminate the the algorithms loop""" - # Private method decorators, see above. - _add_by_fitness_goal = add_by_fitness_goal - _add_by_generation_goal = add_by_generation_goal - _add_by_tolerance_goal = add_by_tolerance_goal + # Allowing access to decorators when importing class + _add_by_fitness_goal = _add_by_fitness_goal + _add_by_generation_goal = _add_by_generation_goal + _add_by_tolerance_goal = _add_by_tolerance_goal - @add_by_fitness_goal - @add_by_generation_goal - @add_by_tolerance_goal + @_add_by_fitness_goal + @_add_by_generation_goal + @_add_by_tolerance_goal def fitness_generation_tolerance(ga): """Terminate GA when any of the - fitness,