From 629d42478e98e83ec43205e86b475f3414e0cda0 Mon Sep 17 00:00:00 2001 From: Larry Diehl Date: Sat, 8 Nov 2008 01:35:43 -0500 Subject: [PATCH] Added point mutation --- examples/increment_cubed.rb | 4 ++-- examples/polynomial.rb | 6 +++--- lib/population.rb | 2 +- lib/program.rb | 16 +++++----------- spec/program/mutate_spec.rb | 10 +++++----- 5 files changed, 16 insertions(+), 22 deletions(-) diff --git a/examples/increment_cubed.rb b/examples/increment_cubed.rb index 7698a58..fa9486b 100644 --- a/examples/increment_cubed.rb +++ b/examples/increment_cubed.rb @@ -25,9 +25,9 @@ def cases(num, value) :generations_limit => 500, :fitness_cases => cases(6, 1), :error_function => lambda{|cases| cases.inject{|x, y| x.abs + y.abs } }, - :elitism_percent => 0.3, + :elitism_percent => 0.4, :crossover_percent => 0.5, - :mutation_percent => 0.0 + :mutation_percent => 0.1 }) population.evolve! diff --git a/examples/polynomial.rb b/examples/polynomial.rb index 3fae455..416f815 100644 --- a/examples/polynomial.rb +++ b/examples/polynomial.rb @@ -25,9 +25,9 @@ def cases(num, value) :generations_limit => 500, :fitness_cases => cases(6, 1), :error_function => lambda{|cases| cases.inject{|x, y| x.abs + y.abs } }, - :elitism_percent => 0.3, - :crossover_percent => 0.6, - :mutation_percent => 0.0 + :elitism_percent => 0.4, + :crossover_percent => 0.5, + :mutation_percent => 0.1 }) population.evolve! diff --git a/lib/population.rb b/lib/population.rb index 553af3b..8da9c25 100644 --- a/lib/population.rb +++ b/lib/population.rb @@ -56,7 +56,7 @@ def evolve_generation! elsif number_of_crossovers > 0 && number_of_crossovers -= 1 select_program.crossover(select_program) elsif number_of_mutations > 0 && number_of_mutations -= 1 - select_program.mutate(Program.randomized(rand(size_limit).next, instructions)) + select_program.mutate(instructions, size_limit) elsif number_of_reproductions > 0 && number_of_reproductions -= 1 select_program.reproduce else diff --git a/lib/program.rb b/lib/program.rb index 46f463a..79dcb02 100644 --- a/lib/program.rb +++ b/lib/program.rb @@ -34,10 +34,12 @@ def crossover(mate) self.random_subset + mate.random_subset end - def mutate(mutation) + def mutate(instructions, size_limit) result = self.dup - result[rand(result.size)] = mutation - result.flatten + result.each_with_index do |inst, index| + result[index] = instructions[rand(instructions.size)] if rand < (1.5 / (size_limit*0.5)) + end + result end def +(program) @@ -51,13 +53,5 @@ def random_slice def random_subset self.slice( rand(self.size), rand(self.size) + 1 ) end - - def slice_left - self.slice( 0, rand(self.size).next ) - end - - def slice_right - self.slice( -rand(self.size).next, self.size ) - end end end \ No newline at end of file diff --git a/spec/program/mutate_spec.rb b/spec/program/mutate_spec.rb index a6f1f42..d13103f 100644 --- a/spec/program/mutate_spec.rb +++ b/spec/program/mutate_spec.rb @@ -5,20 +5,20 @@ module Revolve describe Program, "#mutate" do before do @parent = Program.new(1, 2, 3, 4, 5) - @mutation = Program.new("one", "two", "three", "four", "five") - @child = @parent.mutate(@mutation) + @instructions = [1337] + @child = @parent.mutate(@instructions, 20) end it "should produce a new Program" do @child.should be_kind_of(Program) end - it "should be of length equal to the sum of the program - 1 and its mutation" do - @child.length.should == 9 + it "should be of length equal to the original program" do + @child.length.should == 5 end it "should only contain instructions from either program or mutation" do - @child.each{|instruction| (@parent + @mutation).should include(instruction) } + @child.each{|instruction| (@parent + @instructions).should include(instruction) } end end