Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #to specify target string, change 'Pool.new("Chunky Bacon")' at the bottom of the file
- class Pool
- attr_accessor :candidates
- def initialize(perfect = "hello world")
- @candidates = (1..8).map{Candidate.new(perfect.downcase.split(""))}
- end
- def evolve!
- @candidates = @candidates.sort_by{|c| c.fitness}.reverse
- size = @candidates.size
- #merge two low-indexed items and merge them
- @candidates = @candidates.map do
- #square root distribution
- a = (size / 2 - 1) - Math.sqrt(rand((size/2)**2)).to_i
- b = (size / 2 - 1) - Math.sqrt(rand((size/2)**2)).to_i
- parent_a = @candidates[a]
- parent_b = @candidates[b]
- parent_a.merge_with(parent_b)
- end
- @candidates = @candidates.sort_by{|c| c.fitness}.reverse
- puts candidates.map{|c| c.value.join}.join(" | ")
- sleep 0.03
- end
- def average_fitness
- sum_total = @candidates.inject(0){|sum, candy| sum += candy.fitness}
- return sum_total.to_f/@candidates.size
- end
- def evolve_until_solution
- count = 0
- until @candidates.first.solved?
- count += 1
- self.evolve!
- end
- #puts "Found correct solution after #{count} iterations!"
- return count
- end
- end
- class Candidate
- attr_accessor :value
- attr_accessor :perfect
- def initialize(perfect)
- @perfect = perfect
- @value = (1..@perfect.size).map{(('a'..'z').to_a << ' ')[rand(27)]}
- end
- def fitness
- fit = 0
- @value.each_with_index do |character, i|
- fit += 1 if character == @perfect[i]
- end
- return fit
- end
- def solved?
- self.fitness == @perfect.size
- end
- def merge_with(candidate)
- child = Candidate.new(@perfect)
- @value.each_with_index do |parent_a, i|
- parent_b = candidate.value[i]
- child.value[i] = (rand(2) == 0 ? parent_a : parent_b)
- end
- child.mutate!
- return child
- end
- def mutate!
- mutation_probability = 0.15 / Math.sqrt(@perfect.size)
- @value = @value.map do |character|
- if rand < mutation_probability
- (('a'..'z').to_a << ' ')[rand(27)]
- else
- character
- end
- end
- return self
- end
- end
- @p = Pool.new("Chunky Bacon")
- @p.candidates.each{|c| print c.value.join + " | "}
- puts ""
- @p.evolve_until_solution
- #total_iterations = 0
- #3.times do
- # total_iterations += Pool.new.evolve_until_solution
- #end
- #puts "Average iterations = #{total_iterations/10.0}"
Add Comment
Please, Sign In to add comment