Class: NEAT::Evolver::CritterOp

Inherits:
NeatOb
  • Object
show all
Defined in:
lib/rubyneat/evolver.rb

Overview

A set of Critter Genotype operators.

Instance Attribute Summary

Attributes inherited from NeatOb

#controller, #name

Instance Method Summary collapse

Methods inherited from NeatOb

attr_neat, log, #log, #to_s

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