177 lines
6.6 KiB
Plaintext
177 lines
6.6 KiB
Plaintext
Generations
|
|
|
|
# calculate number of offspring allowed per species
|
|
for each species,
|
|
identify the average and the min/max fitness values
|
|
add 1 to all of those numbers (for mathematical simplicity)
|
|
take the sum of the averages
|
|
for each species
|
|
divide the total by the species average
|
|
multiply that number by the target population size
|
|
subtract from it that number times stagnant generations count
|
|
store the floor()ed result as allowed offspring count
|
|
count the total offspring allocated above
|
|
if less than target population size
|
|
allocate remaining to most-fit species
|
|
for each species
|
|
multiply offspring by 10% to get the 'elitism' offspring count
|
|
if elitism less than 2, set it at 2
|
|
if this is more than the total offspring allowed, species dies
|
|
subtract the elitism count from the allowed count to get remaining
|
|
allocate 50% to be created via crossover
|
|
50% will include only some weights from less fit parent
|
|
50% will include one additional structural element, too
|
|
and the other 50% via mutation
|
|
all of which are weight adjusted by up to 10% per weight
|
|
65% of which are by weight adjustment only
|
|
20% add a new connection
|
|
10% split a current connection / add node
|
|
5% delete an existing connection
|
|
|
|
# identify rankings within species
|
|
for each species,
|
|
make a list of members sorted by fitness, descending
|
|
|
|
# identify dominance within species
|
|
# used to determine breeding priority
|
|
for each species
|
|
calculate sum of fitness values of all members of species
|
|
for each member of species
|
|
calculate fitness / sum of fitness
|
|
|
|
# elitism
|
|
take the first N networks from the sorted species member list
|
|
copy each one, verbatim, to the next generation
|
|
|
|
# mutation
|
|
for each species
|
|
calculate 'remaining' as number of mutation offspring allowed
|
|
for each member of the species, in fitness order (descending)
|
|
multiply its dominance value times allowed offspring
|
|
round() the number to the nearest integer.
|
|
if number is 0, round up to 1
|
|
if number is greater than remaining, reduce to remaining
|
|
while this number is > 0
|
|
create a new mutation of this organism
|
|
and copy it to the next generation
|
|
decrement the number, and the 'remaining' number
|
|
if 'remaining' is 0, exit loop
|
|
|
|
# to mutate a single organism
|
|
copy the organism to a new structure
|
|
give the new one a new ID
|
|
for each connection
|
|
assign a new weight that is +/- up to 10% of current value
|
|
save random() number
|
|
if random < delete threshold, delete a connection
|
|
else if < split threshold, split a connection
|
|
else if < add threshold, add a connection
|
|
|
|
# crossover
|
|
for each species
|
|
calculate 'remaining' as number of offspring allowed, times 2
|
|
for each member of the species, in fitness order (descending)
|
|
multiply its dominance value times allowed offspring
|
|
round() the number to the nearest integer.
|
|
if number is 0, round up to 1
|
|
if number is greater than remaining, reduce to remaining
|
|
push this member onto a list of breeders <number> times
|
|
randomize the list of breeders
|
|
while the list of breeders is not empty
|
|
pop the first entry off the front of the list
|
|
search the list for the first entry that is not the same
|
|
while the first entry is the same as the other entry
|
|
pop it off and push it on to the end
|
|
crossover these two to make a new one
|
|
|
|
# to crossover two specimens
|
|
copy the more fit parent's genome
|
|
for each connection in the more fit parent's genome
|
|
if a match occurs in less fit parent
|
|
50/50 chance of using the weight from the less fit parent
|
|
50/50 chance of selecting ONE structural element from the less
|
|
fit parent and copying it into the new genome
|
|
move the newly created offspring into the next generation
|
|
|
|
# speciation
|
|
-initially, each member belongs to the species of its parents.
|
|
-if two organisms have the same structure, they belong in the same
|
|
species, regardless of who their parents were.
|
|
|
|
for every member of the population
|
|
compose a string representing the structure of the network
|
|
store a hash entry with structure as key
|
|
store in the record
|
|
list of members
|
|
highest fitness value of any member
|
|
total fitness of all members
|
|
count of members
|
|
for each structure
|
|
calculate average fitness
|
|
sort the structures by highest average fitness
|
|
start with an empty species list
|
|
for each structure, while species count < max
|
|
form a new species with that structure as basis
|
|
sort the members by fitness, highest first
|
|
for the rest of the structures
|
|
identify the structure(s) that are most compatible with this one
|
|
if only one, add all members to that species
|
|
otherwise, assign each member to the compatible structure whose
|
|
average is closest to that of the new member
|
|
and update the average for that species
|
|
for each new species
|
|
build a list of records with:
|
|
new species (pointer),
|
|
old species name or proposed new name,
|
|
number of members from that old species in this new species
|
|
average fitness of those members
|
|
average fitness of new species
|
|
sort that master list by
|
|
average fitness of members voting for a particular assignment
|
|
average fitness of new species
|
|
number of members voting for name
|
|
go through the list of species name votes
|
|
if the proposed name is already taken, reject the vote
|
|
if the proposed species has already been given a name, reject
|
|
otherwise, assign that name to that species
|
|
go through the list of species, in fitness order, descending
|
|
if the species doesn't have a name, give it a new one
|
|
give every member the name of their new species, if different
|
|
|
|
|
|
|
|
offspring priority per topology
|
|
1st place network copied verbatim - elite
|
|
1st elite with randomly 'adjusted' weights
|
|
1st elite with 'average' crossover with 2nd place
|
|
1st elite with 'random' crossover with 2nd place
|
|
2nd place network copied verbatim
|
|
2nd elite with randomly adjusted weights
|
|
1st elite with 'average' crossover with random other
|
|
2nd elite with 'average' crossover with random other
|
|
1st elite with 'random' crossover with random other
|
|
2nd elite with 'random' crossover with random other
|
|
all new weights
|
|
|
|
if after allocating offspring, there remain open slots
|
|
one of
|
|
75% - add a new connection
|
|
20% - split a node
|
|
5% - delete a connection
|
|
|
|
as topologies optimize, their improvement slows
|
|
when it ceases to improve, the investment in it decreases
|
|
stagnation penalty incremented
|
|
when an improvement is made, cut the penalty in half
|
|
when the investment drops below threshold, the elite is 'archived'
|
|
and further investment in it ceases
|
|
if a mutation produces this same topology again,
|
|
treat the event as an improvement
|
|
cut stagnation penalty in half
|
|
include archived elite and new member as gene pool
|
|
|
|
as the investment in a topology decreases,
|
|
the more resources are available for more promising avenues
|
|
|
|
instead of 'species' we will call it 'topology'
|