From d2d91c4e3f1403577fff4ca9a31e609d96bbda30 Mon Sep 17 00:00:00 2001 From: Thomas Countz Date: Mon, 31 Jul 2023 10:47:14 +0200 Subject: [PATCH] remove genetic_material from configuration --- README.md | 3 +-- examples/lazy_dog/lazy_dog_example.rb | 7 +++---- examples/traveling_salesperson/salesperson_example.rb | 1 - lib/petri_dish/configuration.rb | 6 ------ spec/world_spec.rb | 1 - 5 files changed, 4 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 26be317..2c7cdd3 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ The high-level steps of an evolutionary algorithm are: Petri Dish is built around a few key classes: `Configuration`, `Member`, `Metadata`, and `World`. -- `Configuration`: This class provides a way to configure the behavior of the evolutionary algorithm. It exposes various parameters like `population_size`, `mutation_rate`, `genetic_material`, and several callback functions that can be used to customize the evolution process. +- `Configuration`: This class provides a way to configure the behavior of the evolutionary algorithm. It exposes various parameters like `population_size`, `mutation_rate`, and several callback functions that can be used to customize the evolution process. - `Member`: This class represents an individual in the population. It has a set of genes and a fitness value, which is computed by a fitness function provided in the configuration. @@ -42,7 +42,6 @@ The `Configuration` class in Petri Dish allows you to customize various aspects | `logger` | An object that responds to `:info` for logging purposes | `Logger` | | `population_size` | The number of individuals in the population | `Integer` | | `mutation_rate` | The chance that a gene will change during mutation (between 0 and 1, inclusive) | `Float` | -| `genetic_material` | An array of possible gene values | `Array[untyped]` | | `elitism_rate` | The proportion of the population preserved through elitism (between 0 and 1, inclusive) | `Float` | | `max_generations` | The maximum number of generations to run the evolution for | `Integer` | | `parents_selection_function` | A function used to select parents for crossover | `Proc[Array[Member], Array[Member]]` | diff --git a/examples/lazy_dog/lazy_dog_example.rb b/examples/lazy_dog/lazy_dog_example.rb index 11aa253..e7d592c 100644 --- a/examples/lazy_dog/lazy_dog_example.rb +++ b/examples/lazy_dog/lazy_dog_example.rb @@ -31,11 +31,11 @@ def random_midpoint_crossover_function(configuration) end end -def random_mutation_function(configuration) +def random_mutation_function(configuration, genetic_material) ->(member) do mutated_genes = member.genes.map do |gene| if rand < configuration.mutation_rate - configuration.genetic_material.sample + genetic_material.sample else gene end @@ -49,11 +49,10 @@ def random_mutation_function(configuration) config.max_generations = 5000 config.population_size = 250 config.mutation_rate = 0.005 - config.genetic_material = genetic_material config.parents_selection_function = twenty_percent_tournament_function(config) config.fitness_function = exponential_fitness_function(target_genes) config.crossover_function = random_midpoint_crossover_function(config) - config.mutation_function = random_mutation_function(config) + config.mutation_function = random_mutation_function(config, genetic_material) config.end_condition_function = genes_match_target_end_condition_function(target_genes) config.highest_fitness_callback = ->(member) { puts "Highest fitness: #{member.fitness} (#{member})" } end diff --git a/examples/traveling_salesperson/salesperson_example.rb b/examples/traveling_salesperson/salesperson_example.rb index f7630ba..f84e94b 100644 --- a/examples/traveling_salesperson/salesperson_example.rb +++ b/examples/traveling_salesperson/salesperson_example.rb @@ -117,7 +117,6 @@ def hash config.max_generations = 100 config.population_size = 100 config.mutation_rate = 0.01 - config.genetic_material = GENETIC_MATERIAL config.mutation_function = swap_mutation_function(config) config.fitness_function = fitness_function config.parents_selection_function = twenty_percent_tournament(config) diff --git a/lib/petri_dish/configuration.rb b/lib/petri_dish/configuration.rb index f6d7fbc..f0367f5 100644 --- a/lib/petri_dish/configuration.rb +++ b/lib/petri_dish/configuration.rb @@ -3,7 +3,6 @@ class Configuration attr_accessor :logger, :population_size, :mutation_rate, - :genetic_material, :elitism_rate, :max_generations, :parents_selection_function, @@ -28,7 +27,6 @@ def initialize @population_size = default_population_size @mutation_rate = default_mutation_rate @elitism_rate = default_elitism_rate - @genetic_material = default_genetic_material @fitness_function = default_fitness_function @parents_selection_function = default_parents_selection_function @crossover_function = default_crossover_function @@ -46,7 +44,6 @@ def validate! raise ArgumentError, "population_size must be greater than 0" unless population_size > 0 raise ArgumentError, "mutation_rate must be between 0 and 1" unless mutation_rate >= 0 && mutation_rate <= 1 raise ArgumentError, "elitism_rate must be between 0 and 1" unless elitism_rate >= 0 && elitism_rate <= 1 - raise ArgumentError, "genetic_material must be an Array" unless genetic_material.is_a?(Array) raise ArgumentError, "fitness_function must respond to :call" unless fitness_function.respond_to?(:call) raise ArgumentError, "parents_selection_function must respond to :call" unless parents_selection_function.respond_to?(:call) raise ArgumentError, "crossover_function must respond to :call" unless crossover_function.respond_to?(:call) @@ -64,7 +61,6 @@ def reset! @population_size = default_population_size @mutation_rate = default_mutation_rate @elitism_rate = default_elitism_rate - @genetic_material = default_genetic_material @fitness_function = default_fitness_function @parents_selection_function = default_parents_selection_function @crossover_function = default_crossover_function @@ -92,8 +88,6 @@ def default_mutation_rate = 0.005 def default_elitism_rate = 0.00 - def default_genetic_material = [] - def default_fitness_function = ->(_member) { raise ArgumentError, "fitness_function must be set" } def default_parents_selection_function = ->(_members) { raise ArgumentError, "parents_selection_function must be set" } diff --git a/spec/world_spec.rb b/spec/world_spec.rb index 595e949..739072b 100644 --- a/spec/world_spec.rb +++ b/spec/world_spec.rb @@ -15,7 +15,6 @@ allow(configuration).to receive(:population_size).and_return(1) allow(configuration).to receive(:mutation_rate).and_return(0.005) allow(configuration).to receive(:elitism_rate).and_return(0.00) - allow(configuration).to receive(:genetic_material).and_return([]) allow(configuration).to receive(:parents_selection_function).and_return(->(_members) { double(PetriDish::Member, fitness: 0.1) }) allow(configuration).to receive(:crossover_function).and_return(->(_members) { double(PetriDish::Member, fitness: 0.1) }) allow(configuration).to receive(:mutation_function).and_return(->(_member) { double(PetriDish::Member, fitness: 0.1) })