Class: NEAT::Evolver::CritterOp
- Defined in:
- lib/rubyneat/evolver.rb
Overview
A set of Critter Genotype operators.
Instance Attribute Summary
Attributes inherited from NeatOb
Instance Method Summary collapse
-
#add_gene!(crit) ⇒ Object
Add a gene to the genome Unlike adding a new neuron, adding a new gene could result in a circular dependency.
-
#add_neuron!(crit) ⇒ Object
Add a neuron to given critter Here, we add a neuron by randomly picking a gene, and split it into two genes with an intervening neuron.
-
#disable_gene!(crit) ⇒ Object
Pick an enabled gene at random and disable it.
-
#initialize(evol) ⇒ CritterOp
constructor
A new instance of CritterOp.
-
#reenable_gene!(crit) ⇒ Object
Pick a disabled gene at random and reenable it.
Methods inherited from NeatOb
Constructor Details
#initialize(evol) ⇒ CritterOp
Returns a new instance of CritterOp.
255 256 257 258 259 |
# File 'lib/rubyneat/evolver.rb', line 255 def initialize(evol) super evol.controller @evolver = evol @npop = evol.npop end |
Instance Method Details
#add_gene!(crit) ⇒ Object
Add a gene to the genome
Unlike adding a new neuron, adding a new gene could result in a circular dependency. If so, and if recurrency is switched off, we must detect this condition and switch off the offending neurons.
Obviously, this might result in a loss of functionality, but oh well.
An easy and obvious check is to make sure we don’t accept any inputs from output neurons, and we don’t do any outputs to input neurons.
Constructs for handling recurrency are present in Expressor.
291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/rubyneat/evolver.rb', line 291 def add_gene!(crit) n1 = crit.genotype.neurons.values.sample # input n2 = crit.genotype.neurons.values.sample # output # Sanity checks! unless n1 == n2 or n1.output? or n2.input? gene = Critter::Genotype::Gene[crit.genotype, n1.name, n2.name, NEAT::controller.gaussian] crit.genotype.add_genes gene log.debug "add_gene! Added gene #{gene}(#{n1.name} -> #{n2.name}) to #{crit}" end end |
#add_neuron!(crit) ⇒ Object
Add a neuron to given critter
Here, we add a neuron by randomly picking a gene, and split it into two genes with an intervening neuron. The old gene is not replaced, but disabled. 2 new genes are created along with the new neuron.
266 267 268 269 270 271 272 273 274 275 |
# File 'lib/rubyneat/evolver.rb', line 266 def add_neuron!(crit) gene = crit.genotype.genes.values.sample neu = controller.neural_hidden.values.sample.new(controller) g1 = Critter::Genotype::Gene[crit.genotype, gene.in_neuron, neu.name, gene.weight] g2 = Critter::Genotype::Gene[crit.genotype, neu.name, gene.out_neuron, gene.weight] gene.enabled = false crit.genotype.add_neurons neu crit.genotype.add_genes g1, g2 log.debug "add_neuron!: neu #{neu}, g1 #{g1}, g2 #{g2}" end |
#disable_gene!(crit) ⇒ Object
Pick an enabled gene at random and disable it.
304 305 306 307 |
# File 'lib/rubyneat/evolver.rb', line 304 def disable_gene!(crit) gene = crit.genotype.genes.values.reject{|gene| gene.disabled? }.sample gene.enabled = false unless gene.nil? end |
#reenable_gene!(crit) ⇒ Object
Pick a disabled gene at random and reenable it.
310 311 312 313 |
# File 'lib/rubyneat/evolver.rb', line 310 def reenable_gene!(crit) gene = crit.genotype.genes.values.reject{|gene| gene.enabled? }.sample gene.enabled = true unless gene.nil? end |