ResetAndKill() { m_dTotFitAdj = 0; m_dAvFitAdj = 0; // Purge the species that doesn't improve for (int i = m_vecSpecies.Count - 1; i >= 0; i--) { CSpecies species = m_vecSpecies[i]; species.Purge(); if (species.GensNoImprovement() > _params.NumGensAllowedNoImprovement && species.BestFitness() < m_dBestEverFitness) { m_vecSpecies.RemoveAt(i); Debug.Log("killed species " + species.ID()); } } for (int i = 0; i < m_Population.Count; i++) { CGenome genome = m_Population[i]; genome.DeletePhenotype(); } }
Epoch(Dictionary <int, float> fitnessScores) { if (fitnessScores.Count != m_Population.Count) { Debug.LogError("scores and genomes mismatch error. (" + fitnessScores.Count + " / " + m_Population.Count + ")"); return(null); } ResetAndKill(); for (int i = 0; i < m_Population.Count; i++) { CGenome genome = m_Population[i]; genome.SetFitness(fitnessScores[genome.ID()]); } SortAndRecord(); SpeciateGenomes(); CalculateSpawnLevels(); Debug.Log("best fitness last gen: " + m_Population[0].Fitness()); List <CGenome> newPopulation = new List <CGenome> (); int numSpawned = SpawnLeaders(newPopulation); for (int i = 0; i < m_vecSpecies.Count; i++) { CSpecies species = m_vecSpecies[i]; numSpawned = SpawnOffspring(species, numSpawned, newPopulation); } /* * Tournament selection is used over the entire population if due * to a underflow of the species amount to spawn the offspring * doesn't fill the entire population additional children needs to * created. */ if (numSpawned < _params.NumGenomesToSpawn) { int numMoreToSpawn = _params.NumGenomesToSpawn - numSpawned; while (numMoreToSpawn-- > 0) { CGenome baby = new CGenome(TournamentSelection(m_PopSize / 5)); baby.SetID(++nextGenomeID); newPopulation.Add(baby); } } m_Population = newPopulation; m_iGeneration++; return(CreatePhenotypes()); }
SpawnLeaders(List <CGenome> newPopulation) { for (int i = 0; i < m_vecSpecies.Count; i++) { CSpecies species = m_vecSpecies[i]; CGenome baby = species.Leader(); Debug.Log("spawning leader (" + baby.Fitness() + "): " + baby.ID() + " for " + species.ID()); newPopulation.Add(baby); } return(newPopulation.Count); }
CalculateSpawnLevels() { for (int i = 0; i < m_Population.Count; i++) { CGenome genome = m_Population[i]; float toSpawn = 0; if (m_dAvFitAdj > 0) { toSpawn = genome.GetAdjustedFitness() / m_dAvFitAdj; } genome.SetAmountToSpawn(toSpawn); } for (int i = 0; i < m_vecSpecies.Count; i++) { CSpecies species = m_vecSpecies[i]; species.CalculateSpawnAmount(); } }
SpawnOffspring(CSpecies species, int numSpawned, List <CGenome> newPopulation) { CGenome baby = null; /* * Prevent overflowing the total number of genomes spawned per population. */ if (numSpawned < _params.NumGenomesToSpawn) { // Exclude the leader from numToSpawn. int numToSpawn = Mathf.RoundToInt(species.NumToSpawn()) - 1; numToSpawn = Mathf.Min(numToSpawn, _params.NumGenomesToSpawn - numSpawned); Debug.Log("spawning " + numToSpawn + " num indivudals for species " + species.ID() + ", best fitness: " + species.BestFitness()); while (numToSpawn-- > 0) { /* * Unless we have >2 members in the species crossover * can't be performed. */ if (species.NumMembers() == 1) { baby = new CGenome(species.Spawn()); } else { CGenome mum = species.Spawn(); if (Random.value < _params.CrossoverRate) { CGenome dad = species.Spawn(); int numAttempts = 5; // try to select a genome which is not the same as mum while (mum.ID() == dad.ID() && numAttempts-- > 0) { dad = species.Spawn(); } if (mum.ID() != dad.ID()) { baby = Crossover(mum, dad); } else { if (Random.value < 0.5f) { baby = new CGenome(dad); } else { baby = new CGenome(mum); } } } else { baby = new CGenome(mum); } } if (baby == null) { continue; } baby.SetID(++nextGenomeID); MutateBaby(baby); //EDIT me baby.SortGenes(); newPopulation.Add(baby); if (numSpawned++ >= _params.NumGenomesToSpawn) { numToSpawn = 0; break; } } } return(numSpawned); }
SpeciateGenomes() { bool addedToSpecies = false; for (int i = 0; i < m_Population.Count; i++) { CGenome genome = m_Population[i]; float bestCompatability = 1000; CSpecies bestSpecies = null; for (int j = 0; j < m_vecSpecies.Count; j++) { CSpecies species = m_vecSpecies[j]; float compatibility = genome.GetCompatibilityScore(species.Leader()); // if this individual is similar to this species leader add to species if (compatibility < bestCompatability) { bestCompatability = compatibility; bestSpecies = species; } } if (bestCompatability <= _params.CompatibilityThreshold) { bestSpecies.AddMember(genome); genome.SetSpecies(bestSpecies.ID()); addedToSpecies = true; } if (!addedToSpecies) { // we have not found a compatible species so a new one will be created m_vecSpecies.Add(new CSpecies(genome, nextSpeciesID++)); } addedToSpecies = false; } /* * Adjust the fitness for all members of the every species to take * into account fitness sharing and age of species. */ for (int i = 0; i < m_vecSpecies.Count; i++) { CSpecies species = m_vecSpecies[i]; species.AdjustFitnesses(); } /* * Calculate new adjusted total and average fitness for the population. */ for (int i = 0; i < m_Population.Count; i++) { CGenome genome = m_Population[i]; m_dTotFitAdj += genome.GetAdjustedFitness(); } m_dAvFitAdj = m_dTotFitAdj / m_Population.Count; }