Guest User

Untitled

a guest
Jul 20th, 2018
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.34 KB | None | 0 0
  1. #to specify target string, change 'Pool.new("Chunky Bacon")' at the bottom of the file
  2.  
  3.  
  4. class Pool
  5. attr_accessor :candidates
  6.  
  7. def initialize(perfect = "hello world")
  8. @candidates = (1..8).map{Candidate.new(perfect.downcase.split(""))}
  9. end
  10.  
  11. def evolve!
  12. @candidates = @candidates.sort_by{|c| c.fitness}.reverse
  13. size = @candidates.size
  14. #merge two low-indexed items and merge them
  15. @candidates = @candidates.map do
  16. #square root distribution
  17. a = (size / 2 - 1) - Math.sqrt(rand((size/2)**2)).to_i
  18. b = (size / 2 - 1) - Math.sqrt(rand((size/2)**2)).to_i
  19. parent_a = @candidates[a]
  20. parent_b = @candidates[b]
  21. parent_a.merge_with(parent_b)
  22. end
  23. @candidates = @candidates.sort_by{|c| c.fitness}.reverse
  24. puts candidates.map{|c| c.value.join}.join(" | ")
  25. sleep 0.03
  26. end
  27.  
  28. def average_fitness
  29. sum_total = @candidates.inject(0){|sum, candy| sum += candy.fitness}
  30. return sum_total.to_f/@candidates.size
  31. end
  32.  
  33. def evolve_until_solution
  34. count = 0
  35. until @candidates.first.solved?
  36. count += 1
  37. self.evolve!
  38. end
  39. #puts "Found correct solution after #{count} iterations!"
  40. return count
  41. end
  42.  
  43. end
  44.  
  45.  
  46.  
  47. class Candidate
  48. attr_accessor :value
  49. attr_accessor :perfect
  50.  
  51. def initialize(perfect)
  52. @perfect = perfect
  53. @value = (1..@perfect.size).map{(('a'..'z').to_a << ' ')[rand(27)]}
  54. end
  55.  
  56. def fitness
  57. fit = 0
  58. @value.each_with_index do |character, i|
  59. fit += 1 if character == @perfect[i]
  60. end
  61. return fit
  62. end
  63.  
  64. def solved?
  65. self.fitness == @perfect.size
  66. end
  67.  
  68. def merge_with(candidate)
  69. child = Candidate.new(@perfect)
  70. @value.each_with_index do |parent_a, i|
  71. parent_b = candidate.value[i]
  72. child.value[i] = (rand(2) == 0 ? parent_a : parent_b)
  73. end
  74. child.mutate!
  75. return child
  76. end
  77.  
  78. def mutate!
  79. mutation_probability = 0.15 / Math.sqrt(@perfect.size)
  80. @value = @value.map do |character|
  81. if rand < mutation_probability
  82. (('a'..'z').to_a << ' ')[rand(27)]
  83. else
  84. character
  85. end
  86. end
  87. return self
  88. end
  89. end
  90.  
  91.  
  92.  
  93. @p = Pool.new("Chunky Bacon")
  94. @p.candidates.each{|c| print c.value.join + " | "}
  95. puts ""
  96. @p.evolve_until_solution
  97. #total_iterations = 0
  98. #3.times do
  99. # total_iterations += Pool.new.evolve_until_solution
  100. #end
  101.  
  102. #puts "Average iterations = #{total_iterations/10.0}"
Add Comment
Please, Sign In to add comment