Skip to content

Instantly share code, notes, and snippets.

@hfaulds
Created September 30, 2011 21:33
Show Gist options
  • Select an option

  • Save hfaulds/1255029 to your computer and use it in GitHub Desktop.

Select an option

Save hfaulds/1255029 to your computer and use it in GitHub Desktop.
1 class Population
2 def initialize(population_size, target)
3 @target = target
4
5 @population = []
6 population_size.times do
7 @population.push Individual.create_random(target, target.length)
8 end
9 end
10
11 def next_generation
12 target_length = @population.length
13 cull_population
14 repopulate(target_length).first.score
15 end
16
17 def cull_population
18 order_population
19 @population.each_index do |index|
20 if should_be_culled?(index)
21 @population.delete_at(index)
22 end
23 end
24 end
25
26 def repopulate(target_length)
27 order_population
28 growth = target_length - @population.length
29 babies = []
30 growth.times do
31 mate_a = find_mate(@population)
32 mate_b = find_mate_for(mate_a)
33 babies << mate_a.mate_with(mate_b)
34 end
35 @population += babies
36 end
37
38 def should_be_culled?(index)
39 rand(@population.length) <= index
40 end
41
42 def should_mate(index)
43 rand(@population.length) <= index
44 end
45
46 def find_mate(population)
47 while true do
48 population.each_index do |index|
49 if should_mate(index)
50 return population[index]
51 end
52 end
53 end
54 end
55
56 def find_mate_for(individual)
57 rest_of_pop = []
58 @population.each do |ind|
59 if ind != individual
60 rest_of_pop << ind
61 end
62 end
63 find_mate(rest_of_pop)
64 end
65
66 def order_population
67 @population.sort! do |a,b,|
68 a.score <=> b.score
69 end
70 end
71
72 def log
73 puts "-----"
74 @population.each do |individual|
75 puts individual.to_s
76 end
77 end
78
79 def log_best
80 puts @population.first.to_s
81 end
82 end
83
84 class Individual
85 def initialize(target, reproduction_system)
86 @target = target
87 @reproduction_system = reproduction_system
88 end
89
90 def self.create_random(target, output_length)
91 Individual.new(target, ReproductionSystem.create_random(output_length))
92 end
93
94 def score
95 score = 0
96 @reproduction_system.genes.each_index do |index|
97 score += (@target[index] - @reproduction_system.genes[index]).abs
98 end
99 score
100 end
101
102 def mate_with(mate)
103 @reproduction_system.mate_with(mate)
104 end
105
106 def be_mated_with(genetic_code)
107 Individual.new(@target, @reproduction_system.be_mated_with(genetic_code))
108 end
109
110 def to_s
111 @reproduction_system.to_s + " : " + score.to_s
112 end
113 end
114
115 class ReproductionSystem
116 attr_reader :genes
117 def initialize(genes)
118 @genes = genes
119 end
120
121 def self.random_gene_part
122 32 + rand(94)
123 end
124
125 def self.create_random(output_length)
126 genes = []
127 output_length.times do
128 genes.push(random_gene_part)
129 end
130 ReproductionSystem.new(genes)
131 end
132
133 def to_s
134 out = ''
135 @genes.each do |part|
136 out += part.chr
137 end
138 out
139 end
140
141 def mate_with(mate)
142 mate.be_mated_with(@genes)
143 end
144
145 def be_mated_with(genetic_code)
146 length = @genes.length
147 a_half = genetic_code.slice(0, length/2)
148 b_half = @genes.slice(length/2,length-1)
149 genes = a_half + b_half
150 genes[rand(length)] = ReproductionSystem.random_gene_part
151
152 ReproductionSystem.new(genes)
153 end
154 end
155
156 population = Population.new(100, "Hello World")
157 population.order_population
158 population.log
159 i=0
160 while(population.next_generation>0) do
161 puts "generation " + (i+=1).to_s
162 population.log_best
163 end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment