Class: Algorithmically::Evolutionary::Genetic
- Inherits:
-
Object
- Object
- Algorithmically::Evolutionary::Genetic
- Defined in:
- lib/Algorithmically/Evolutionary/genetic.rb
Instance Method Summary collapse
- #binary_tournament(pop) ⇒ Object
- #crossover(parent1, parent2, rate) ⇒ Object
-
#initialize(max_gens, num_bits, pop_size, p_crossover) ⇒ Genetic
constructor
A new instance of Genetic.
- #onemax(bitstring) ⇒ Object
- #point_mutation(bitstring, rate = 1.0/bitstring.size) ⇒ Object
- #random_bitstring(num_bits) ⇒ Object
- #reproduce(selected, pop_size, p_cross, p_mutation) ⇒ Object
- #search(max_gens, num_bits, pop_size, p_crossover, p_mutation) ⇒ Object
Constructor Details
#initialize(max_gens, num_bits, pop_size, p_crossover) ⇒ Genetic
Returns a new instance of Genetic.
6 7 8 9 10 |
# File 'lib/Algorithmically/Evolutionary/genetic.rb', line 6 def initialize(max_gens, num_bits, pop_size, p_crossover) p_mutation = 1.0/num_bits best = search(max_gens, num_bits, pop_size, p_crossover, p_mutation) puts "done! Solution: f=#{best[:fitness]}, s=#{best[:bitstring]}" end |
Instance Method Details
#binary_tournament(pop) ⇒ Object
22 23 24 25 26 |
# File 'lib/Algorithmically/Evolutionary/genetic.rb', line 22 def binary_tournament(pop) i, j = rand(pop.size), rand(pop.size) j = rand(pop.size) if j==i (pop[i][:fitness] > pop[j][:fitness]) ? pop[i] : pop[j] end |
#crossover(parent1, parent2, rate) ⇒ Object
37 38 39 40 41 |
# File 'lib/Algorithmically/Evolutionary/genetic.rb', line 37 def crossover(parent1, parent2, rate) ""+parent1 if rand()>=rate point = 1 + rand(parent1.size-2) parent1[0...point]+parent2[point...(parent1.size)] end |
#onemax(bitstring) ⇒ Object
12 13 14 15 16 |
# File 'lib/Algorithmically/Evolutionary/genetic.rb', line 12 def onemax(bitstring) sum = 0 bitstring.size.times { |i| sum+=1 if bitstring[i].chr=='1' } sum end |
#point_mutation(bitstring, rate = 1.0/bitstring.size) ⇒ Object
28 29 30 31 32 33 34 35 |
# File 'lib/Algorithmically/Evolutionary/genetic.rb', line 28 def point_mutation(bitstring, rate=1.0/bitstring.size) child = "" bitstring.size.times do |i| bit = bitstring[i].chr child << ((rand()<rate) ? ((bit=='1') ? "0" : "1") : bit) end child end |
#random_bitstring(num_bits) ⇒ Object
18 19 20 |
# File 'lib/Algorithmically/Evolutionary/genetic.rb', line 18 def random_bitstring(num_bits) (0...num_bits).inject("") { |s, i| s<<((rand<0.5) ? "1" : "0") } end |
#reproduce(selected, pop_size, p_cross, p_mutation) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/Algorithmically/Evolutionary/genetic.rb', line 43 def reproduce(selected, pop_size, p_cross, p_mutation) children = [] selected.each_with_index do |p1, i| p2 = (i.modulo(2)==0) ? selected[i+1] : selected[i-1] p2 = selected[0] if i == selected.size-1 child = {} child[:bitstring] = crossover(p1[:bitstring], p2[:bitstring], p_cross) child[:bitstring] = point_mutation(child[:bitstring], p_mutation) children << child children.size >= pop_size end children end |
#search(max_gens, num_bits, pop_size, p_crossover, p_mutation) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/Algorithmically/Evolutionary/genetic.rb', line 57 def search(max_gens, num_bits, pop_size, p_crossover, p_mutation) population = Array.new(pop_size) do |i| {:bitstring => random_bitstring(num_bits)} end population.each { |c| c[:fitness] = onemax(c[:bitstring]) } best = population.sort { |x, y| y[:fitness] <=> x[:fitness] }.first max_gens.times do |gen| selected = Array.new(pop_size) { |i| binary_tournament(population) } children = reproduce(selected, pop_size, p_crossover, p_mutation) children.each { |c| c[:fitness] = onemax(c[:bitstring]) } children.sort! { |x, y| y[:fitness] <=> x[:fitness] } best = children.first if children.first[:fitness] >= best[:fitness] population = children puts " > gen #{gen}, best: #{best[:fitness]}, #{best[:bitstring]}" break best[:fitness] == num_bits end best end |