Program Links

Ruby program to replicate evolution of pattern detector neurons through natural selection. 

=begin
Program to replicate evolution of pattern detector neurons through natural selection.
An initial Trigger stimulus consisting of three arbitrary stimuli generates a presumably
adaptive behavior. Four examples of the Trigger and 12 other random stimuli are presented
to 10 animals, each with a brain consisting of a single neuron which receives input from
an initially random subset of 16 stimulus neurons. The output is assigned an adaptability
score and the animals/neuron with the highest score is cloned in a new “generation” of
animals. The process is repeated until some neuron fires if and only if the stimulus is
presented. That neuron is “saved” (in evoBrain), the process is repeated ten times,
producing a population of 10 animals with a functioning (albeit varied) reflex. That
population is subject to further evolution to a modified stimulus in a “World” without
modifiable synapses and compared to the result in a world with modifiable synapses. The
program must be run twice, setting the World parameter by hand in line 30.
=end
require ‘matrix’
class Matrix
def []=(i, j, x)
@rows[i][j] = x
end
end #code to allow putting individual elements in matix at i,j
Sims=9
Encounters=15 # total number of stimulii presented to organism in a “lifetime”
Stimmax=15
Behavmax=9
BestFitns=28 # value of fitness with best descriminator
Thrsh=70 # Thrsh=threshold for neuronal firing. Same as in labled learning
Dk=0.8
Psp=0.6
TriggerValues=Array[0,4,8,12]
evoBrain = Matrix.build(10,16) { 0 }
for epoch in (3..4)
if epoch == 3 then trigger=Matrix.column_vector([1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0])
world = 0
else trigger=Matrix.column_vector([1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0])
world = 0 # MUST 1 FOR WORLD WITH MODIFIABLE SYNAPSES
brain = evoBrain
end # if epoch
generationsAverage=0
srand(1985) # seed a repeatable string of random numbers
for sim in (0..Sims)
stimulus=Matrix.column_vector([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])
bestBrain=Matrix.column_vector([0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1])
fitness=Matrix.row_vector([0,0,0,0,0,0,0,0,0,0])
def learn(ix, brain, stimulus)
for j in (0..Stimmax)
if stimulus[j,0]>0 and brain[ix,j]>0 then brain[ix,j]+=((24-brain[ix,j])Psp+0.4).round end end # for j end # learn # Build brain/population brain = Matrix.build(10,16) { 0 } for i in (0..Behavmax) for j in (0..Stimmax) if rand >= 0.55 then brain[i,j] = rand(3..24) end end # j end #i generations=0 # BEGIN MAIN PROGRAM while fitness[0,0] < BestFitns do fitness=Matrix.row_vector([0,0,0,0,0,0,0,0,0,0]) # to hold value of fitness for e in (0..Encounters) # show stimuli to animals multiple times over their life # Generate Stimulus otherstim=Matrix.column_vector([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) if TriggerValues.include?(e) then stimulus=trigger t=1 else t=0 for j in (0..15) # generate a random otherstim if rand < 0.25 then otherstim[j,0] = 1 end # if rand end # j stimulus=otherstim end # if tiggerValues # Generate Behavior behavior=brainstimulus
for i in (0..Behavmax) #fire iff stimulus pattern matches detector
if world==1
if behavior[i,0] >= Thrsh and t == 1 then fitness[0,i]+= 4
learn(i, brain, stimulus) end #tp
if behavior[i,0] >= Thrsh and t == 0 then fitness[0,i]-= 2
learn(i, brain, stimulus) end #fp
else
if behavior[i,0] >= Thrsh and t == 1 then fitness[0,i]+= 4 end
if behavior[i,0] >= Thrsh and t == 0 then fitness[0,i]-= 2 end
end # if world
if behavior[i,0] < Thrsh and t == 1 then fitness[0,i]-= 1 end #fn if behavior[i,0] < Thrsh and t == 0 then fitness[0,i]+= 1 end #tn end # for i stimulus=Matrix.column_vector([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) otherstim=Matrix.column_vector([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) end # for e # REPRODUCE: replicate highest fitness animal, replace lowest, add variation to all bestFitness=fitness.max bestAnimal=fitness.find_index(fitness.max) thebestAnimal=bestAnimal[1,1] thebestAnimal=thebestAnimal[0] worstFitness=fitness.min worstAnimal=fitness.find_index(fitness.min) theworstAnimal=worstAnimal[1,1] theworstAnimal=theworstAnimal[0] for j in (0..Stimmax) bestBrain[j,0]=brain[thebestAnimal,j] # make bestBrain here, replace in brain below end #j for j in (0..Stimmax) brain[0,j]=bestBrain[j,0] if theworstAnimal!= 0 then if rand > 0.55 then brain[theworstAnimal,j] = rand(3..24)
else brain[theworstAnimal,j] = 0 end # if rand
end # if twA
end #j
# add variation each generation to one connection per neuron
for i in (1..Behavmax) #Start at 1 to allow first generation descent w/o modification
j=rand(0..Stimmax)
if brain[i,j] == 0 then brain[i,j] = rand(3..24)
else brain[i,j] = 0 end #if
end # i
generations+=1
end # while g
puts “Generations = #{generations}”
generationsAverage += generations
for j in (0..Stimmax)
evoBrain[sim,j]=brain[0,j]
end #j
end #for sims
generationsAverage = generationsAverage / (Sims + 1)
puts “Average number of generations = #{generationsAverage}”
# fitness.to_a.each {|r| puts r.inspect}
brain.to_a.each {|r| puts r.inspect}
end # epoch
puts “End of Epoch #{epoch}”
evoBrain.to_a.each {|r| puts r.inspect}