Class: NEAT::Controller

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

Overview

Controller for all operations of RubyNEAT

This object contains all the specifications and details for evolving and evaluation of the RubyNEAT system. It is a type of “World”, if you will, for the entire enterprise.

Your application shall only have one Controller.

FIXME: The function hooks really should be able to take more FIXME: than one hook! we don’t need that functionality right FIXME: now. Also, the Controller ‘god’ object itself will need FIXME: to undergo some refactorization so that we can have many FIXME: of them for HyperNEAT, co-evolution, etc.

FIXME: An alternative approach would be to have demigod objects FIXME: where the controller would lord it over them all. Attention FIXME: must also be given to Rubinius and JRuby so that we can FIXME: run under multiple cores.

Defined Under Namespace

Classes: NeatSettings

Instance Attribute Summary collapse

Attributes inherited from NeatOb

#controller, #name

Instance Method Summary collapse

Methods inherited from NeatOb

attr_neat, log, #to_s

Constructor Details

#initialize(neural_inputs: nil, neural_outputs: nil, neural_hidden: nil, parameters: NeatSettings.new, &block) ⇒ Controller

  • neural_inputs – array of input classes

  • neural_outputs – array of output classes

  • parameters – NeatParameters object, or a path to a YAML file to create this.



496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
# File 'lib/rubyneat/rubyneat.rb', line 496

def initialize(neural_inputs: nil,
               neural_outputs: nil,
               neural_hidden: nil,
               parameters: NeatSettings.new,
                  &block)
  super(self)
  @gaussian = Distribution::Normal.rng
  @population_history = []
  @evolver = Evolver.new self
  @expressor = Expressor.new self

  @neuron_catalog = Neuron::neuron_types.clone
  @neural_inputs  = neural_inputs
  @neural_outputs = neural_outputs
  @neural_hidden  = neural_hidden

  # Default classes for population and operators, etc.
  @population_class = NEAT::Population
  @evaluator_class = NEAT::Evaluator
  @expressor_class = NEAT::Expressor
  @evolver_class = NEAT::Evolver

  # Handle the parameters parameter. :-)
  @parms = unless parameters.kind_of? String
             parameters
           else # load it from a file
             open(parameters, 'r') { |fd| YAML::load fd.read }
           end
  block.(self) unless block.nil?
end

Instance Attribute Details

#evaluatorObject

Returns the value of attribute evaluator.



335
336
337
# File 'lib/rubyneat/rubyneat.rb', line 335

def evaluator
  @evaluator
end

#evaluator_classObject

Returns the value of attribute evaluator_class.



335
336
337
# File 'lib/rubyneat/rubyneat.rb', line 335

def evaluator_class
  @evaluator_class
end

#evolverObject

Returns the value of attribute evolver.



336
337
338
# File 'lib/rubyneat/rubyneat.rb', line 336

def evolver
  @evolver
end

#evolver_classObject

Returns the value of attribute evolver_class.



336
337
338
# File 'lib/rubyneat/rubyneat.rb', line 336

def evolver_class
  @evolver_class
end

#expressorObject

Returns the value of attribute expressor.



334
335
336
# File 'lib/rubyneat/rubyneat.rb', line 334

def expressor
  @expressor
end

#expressor_classObject

Returns the value of attribute expressor_class.



334
335
336
# File 'lib/rubyneat/rubyneat.rb', line 334

def expressor_class
  @expressor_class
end

#generation_numObject (readonly)

Current generation count



319
320
321
# File 'lib/rubyneat/rubyneat.rb', line 319

def generation_num
  @generation_num
end

#logObject (readonly)

Logger object for all of RubyNEAT



369
370
371
# File 'lib/rubyneat/rubyneat.rb', line 369

def log
  @log
end

#neural_hiddenObject

Class map of named input and output neurons (each critter will have instantiations of these) name: InputNeuralClass (usually InputNeuron)



326
327
328
# File 'lib/rubyneat/rubyneat.rb', line 326

def neural_hidden
  @neural_hidden
end

#neural_inputsObject

Class map of named input and output neurons (each critter will have instantiations of these) name: InputNeuralClass (usually InputNeuron)



326
327
328
# File 'lib/rubyneat/rubyneat.rb', line 326

def neural_inputs
  @neural_inputs
end

#neural_outputsObject

Class map of named input and output neurons (each critter will have instantiations of these) name: InputNeuralClass (usually InputNeuron)



326
327
328
# File 'lib/rubyneat/rubyneat.rb', line 326

def neural_outputs
  @neural_outputs
end

#neuron_catalogObject

catalog of neurons classes to use { weight => nclass, … }



322
323
324
# File 'lib/rubyneat/rubyneat.rb', line 322

def neuron_catalog
  @neuron_catalog
end

#parmsObject

Parameters for evolution (NeatParameters)



329
330
331
# File 'lib/rubyneat/rubyneat.rb', line 329

def parms
  @parms
end

#populationObject (readonly)

population object and class specification



332
333
334
# File 'lib/rubyneat/rubyneat.rb', line 332

def population
  @population
end

#population_classObject (readonly)

population object and class specification



332
333
334
# File 'lib/rubyneat/rubyneat.rb', line 332

def population_class
  @population_class
end

#population_historyObject (readonly)

population object and class specification



332
333
334
# File 'lib/rubyneat/rubyneat.rb', line 332

def population_history
  @population_history
end

#seq_numObject (readonly)

current sequence number being evaluated



316
317
318
# File 'lib/rubyneat/rubyneat.rb', line 316

def seq_num
  @seq_num
end

Instance Method Details

#gaussianObject



528
# File 'lib/rubyneat/rubyneat.rb', line 528

def gaussian ; @gaussian.() ; end

#new_innovationObject



527
# File 'lib/rubyneat/rubyneat.rb', line 527

def new_innovation ; self.glob_innov_num += 1 ; end

#runObject

Run this evolution.



531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
# File 'lib/rubyneat/rubyneat.rb', line 531

def run
  pre_run_initialize
  (1..@parms.max_generations).each do |gen_number|
    @generation_num = gen_number # must be set first
    @population_history << unless @population.nil?
                             @population
                           else
                             @population = @population_class.new(self)
                           end
    @population.generation = gen_number
    @population_history.shift unless @population_history.size <= @parms.max_population_history
    @population.mutate!
    @population.express!

    ## Evaluate population
    @evaluator.ready_for_evaluation @population
    (@parms.start_sequence_at .. @parms.end_sequence_at).each do |snum|
      @seq_num = snum
      @population.evaluate!
    end

    @population.analyze!
    @population.speciate!

    $log.debug @population.dump_s unless self.verbosity < 3

    new_pop = @population.evolve

    ## Report hook for evaluation
    report_hooks(@population.report)

    ## Exit if fitness criteria is reached
    #FIXME handle this exit condition better!!!!!
    exit_neat if stop_on_fit_func_hook(@population.report.last[:fitness], self) unless stop_on_fit_func_none?

    ## Evolve population
    @population = new_pop

    ## Finish up this run
    end_run_hooks(self)
  end
end