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

#log, log, #to_s

Constructor Details

- (CritterOp) initialize(evol)

Returns a new instance of CritterOp



254
255
256
257
258
# File 'lib/rubyneat/evolver.rb', line 254

def initialize(evol)
  super evol.controller
  @evolver = evol
  @npop = evol.npop
end

Instance Method Details

- (Object) add_gene!(crit)

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.



290
291
292
293
294
295
296
297
298
299
300
# File 'lib/rubyneat/evolver.rb', line 290

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

- (Object) add_neuron!(crit)

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.



265
266
267
268
269
270
271
272
273
274
# File 'lib/rubyneat/evolver.rb', line 265

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

- (Object) disable_gene!(crit)

Pick an enabled gene at random and disable it.



303
304
305
306
# File 'lib/rubyneat/evolver.rb', line 303

def disable_gene!(crit)
  gene = crit.genotype.genes.values.reject{|gene| gene.disabled? }.sample
  gene.enabled = false unless gene.nil?
end

- (Object) reenable_gene!(crit)

Pick a disabled gene at random and reenable it.



309
310
311
312
# File 'lib/rubyneat/evolver.rb', line 309

def reenable_gene!(crit)
  gene = crit.genotype.genes.values.reject{|gene| gene.enabled? }.sample
  gene.enabled = true unless gene.nil?
end