Class: Ai4r::GeneticAlgorithm::Chromosome
- Inherits:
-
Object
- Object
- Ai4r::GeneticAlgorithm::Chromosome
- Defined in:
- lib/ai4r/genetic_algorithm/genetic_algorithm.rb
Overview
A Chromosome is a representation of an individual solution for a specific problem. You will have to redifine the Chromosome representation for each particular problem, along with its fitness, mutate, reproduce, and seed methods.
Instance Attribute Summary collapse
-
#data ⇒ Object
Returns the value of attribute data.
-
#normalized_fitness ⇒ Object
Returns the value of attribute normalized_fitness.
Class Method Summary collapse
-
.mutate(chromosome) ⇒ Object
mutation method is used to maintain genetic diversity from one generation of a population of chromosomes to the next.
-
.reproduce(a, b) ⇒ Object
Reproduction method is used to combine two chromosomes (solutions) into a single new chromosome.
-
.seed ⇒ Object
Initializes an individual solution (chromosome) for the initial population.
- .set_cost_matrix(costs) ⇒ Object
Instance Method Summary collapse
-
#fitness ⇒ Object
The fitness method quantifies the optimality of a solution (that is, a chromosome) in a genetic algorithm so that that particular chromosome may be ranked against all the other chromosomes.
-
#initialize(data) ⇒ Chromosome
constructor
A new instance of Chromosome.
Constructor Details
#initialize(data) ⇒ Chromosome
Returns a new instance of Chromosome.
165 166 167 |
# File 'lib/ai4r/genetic_algorithm/genetic_algorithm.rb', line 165 def initialize(data) @data = data end |
Instance Attribute Details
#data ⇒ Object
Returns the value of attribute data.
162 163 164 |
# File 'lib/ai4r/genetic_algorithm/genetic_algorithm.rb', line 162 def data @data end |
#normalized_fitness ⇒ Object
Returns the value of attribute normalized_fitness.
163 164 165 |
# File 'lib/ai4r/genetic_algorithm/genetic_algorithm.rb', line 163 def normalized_fitness @normalized_fitness end |
Class Method Details
.mutate(chromosome) ⇒ Object
mutation method is used to maintain genetic diversity from one generation of a population of chromosomes to the next. It is analogous to biological mutation.
The purpose of mutation in GAs is to allow the algorithm to avoid local minima by preventing the population of chromosomes from becoming too similar to each other, thus slowing or even stopping evolution.
Calling the mutate function will “probably” slightly change a chromosome randomly.
This implementation of “mutation” will (probably) reverse the order of 2 consecutive randome nodes (e.g. from [ 0, 1, 2, 4] to [0, 2, 1, 4]) if:
((1 - chromosome.normalized_fitness) * 0.4)
204 205 206 207 208 209 210 211 212 |
# File 'lib/ai4r/genetic_algorithm/genetic_algorithm.rb', line 204 def self.mutate(chromosome) if chromosome.normalized_fitness && rand < ((1 - chromosome.normalized_fitness) * 0.3) data = chromosome.data index = rand(data.length-1) data[index], data[index+1] = data[index+1], data[index] chromosome.data = data @fitness = nil end end |
.reproduce(a, b) ⇒ Object
Reproduction method is used to combine two chromosomes (solutions) into a single new chromosome. There are several ways to combine two chromosomes: One-point crossover, Two-point crossover, “Cut and splice”, edge recombination, and more.
The method is usually dependant of the problem domain. In this case, we have implemented edge recombination, wich is the most used reproduction algorithm for the Travelling salesman problem.
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/ai4r/genetic_algorithm/genetic_algorithm.rb', line 222 def self.reproduce(a, b) data_size = @@costs[0].length available = [] 0.upto(data_size-1) { |n| available << n } token = a.data[0] spawn = [token] available.delete(token) while available.length > 0 do #Select next if token != b.data.last && available.include?(b.data[b.data.index(token)+1]) next_token = b.data[b.data.index(token)+1] elsif token != a.data.last && available.include?(a.data[a.data.index(token)+1]) next_token = a.data[a.data.index(token)+1] else next_token = available[rand(available.length)] end #Add to spawn token = next_token available.delete(token) spawn << next_token a, b = b, a if rand < 0.4 end return Chromosome.new(spawn) end |
.seed ⇒ Object
Initializes an individual solution (chromosome) for the initial population. Usually the chromosome is generated randomly, but you can use some problem domain knowledge, to generate a (probably) better initial solution.
251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/ai4r/genetic_algorithm/genetic_algorithm.rb', line 251 def self.seed data_size = @@costs[0].length available = [] 0.upto(data_size-1) { |n| available << n } seed = [] while available.length > 0 do index = rand(available.length) seed << available.delete_at(index) end return Chromosome.new(seed) end |
.set_cost_matrix(costs) ⇒ Object
263 264 265 |
# File 'lib/ai4r/genetic_algorithm/genetic_algorithm.rb', line 263 def self.set_cost_matrix(costs) @@costs = costs end |
Instance Method Details
#fitness ⇒ Object
The fitness method quantifies the optimality of a solution (that is, a chromosome) in a genetic algorithm so that that particular chromosome may be ranked against all the other chromosomes.
Optimal chromosomes, or at least chromosomes which are more optimal, are allowed to breed and mix their datasets by any of several techniques, producing a new generation that will (hopefully) be even better.
176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/ai4r/genetic_algorithm/genetic_algorithm.rb', line 176 def fitness return @fitness if @fitness last_token = @data[0] cost = 0 @data[1..-1].each do |token| cost += @@costs[last_token][token] last_token = token end @fitness = -1 * cost return @fitness end |