📄 population.cs
字号:
using System;
using System.Collections;
using GEPAlgorithm;
namespace GeneticAlgorithm
{
/// <summary>
/// Summary description for Population.
/// </summary>
public class Population
{
public const int kLength = 10;
int nCrossover = kLength/2;
const int kInitialPopulation = 1000;
const int kPopulationLimit = 1000;
const int kMin = 0;
const int kMax = 7;
const float kMutationFrequency = 0.10f;
const float kDeathFitness = 0.00f;
const float kReproductionFitness = 0.0f;
ArrayList Scores = new ArrayList();
ArrayList Genomes = new ArrayList();
ArrayList GenomeReproducers = new ArrayList();
ArrayList GenomeResults = new ArrayList();
ArrayList GenomeFamily = new ArrayList();
int CurrentPopulation = kInitialPopulation;
int Generation = 1;
bool Best2 = true;
public Population()
{
//
// TODO: Add constructor logic here
//
for (int i = 0; i < kInitialPopulation; i++)
{
EquationGenome aGenome = new EquationGenome(kLength, kMin, kMax);
int nCrossOver = EquationGenome.TheSeed.Next(1, (int)aGenome.Length);
aGenome.SetCrossoverPoint(nCrossover);
aGenome.CalculateFitness();
Genomes.Add(aGenome);
}
}
private void Mutate(Genome aGene)
{
if (EquationGenome.TheSeed.Next(100) < (int)(kMutationFrequency * 100.0))
{
aGene.Mutate();
}
}
public void NextGeneration()
{
// increment the generation;
Generation++;
// check who can die
for (int i = 0; i < Genomes.Count; i++)
{
if (((Genome)Genomes[i]).CanDie(kDeathFitness))
{
Genomes.RemoveAt(i);
i--;
}
}
// determine who can reproduce
GenomeReproducers.Clear();
GenomeResults.Clear();
for (int i = 0; i < Genomes.Count; i++)
{
if (((Genome)Genomes[i]).CanReproduce(kReproductionFitness))
{
GenomeReproducers.Add(Genomes[i]);
}
}
// do the crossover of the genes and add them to the population
DoCrossover(GenomeReproducers);
Genomes = (ArrayList)GenomeResults.Clone();
// mutate a few genes in the new population
for (int i = 0; i < Genomes.Count; i++)
{
Mutate((Genome)Genomes[i]);
}
// calculate fitness of all the genes
for (int i = 0; i < Genomes.Count; i++)
{
((Genome)Genomes[i]).CalculateFitness();
}
// Genomes.Sort();
// kill all the genes above the population limit
if (Genomes.Count > kPopulationLimit)
Genomes.RemoveRange(kPopulationLimit, Genomes.Count - kPopulationLimit);
CurrentPopulation = Genomes.Count;
}
public void CalculateFitnessForAll(ArrayList genes)
{
foreach(EquationGenome lg in genes)
{
lg.CalculateFitness();
}
}
public void DoCrossover(ArrayList genes)
{
ArrayList GeneMoms = new ArrayList();
ArrayList GeneDads = new ArrayList();
for (int i = 0; i < genes.Count; i++)
{
// randomly pick the moms and dad's
if (EquationGenome.TheSeed.Next(100) % 2 > 0)
{
GeneMoms.Add(genes[i]);
}
else
{
GeneDads.Add(genes[i]);
}
}
// now make them equal
if (GeneMoms.Count > GeneDads.Count)
{
while (GeneMoms.Count > GeneDads.Count)
{
GeneDads.Add(GeneMoms[GeneMoms.Count - 1]);
GeneMoms.RemoveAt(GeneMoms.Count - 1);
}
if (GeneDads.Count > GeneMoms.Count)
{
GeneDads.RemoveAt(GeneDads.Count - 1); // make sure they are equal
}
}
else
{
while (GeneDads.Count > GeneMoms.Count)
{
GeneMoms.Add(GeneDads[GeneDads.Count - 1]);
GeneDads.RemoveAt(GeneDads.Count - 1);
}
if (GeneMoms.Count > GeneDads.Count)
{
GeneMoms.RemoveAt(GeneMoms.Count - 1); // make sure they are equal
}
}
// now cross them over and add them according to fitness
for (int i = 0; i < GeneDads.Count; i ++)
{
// pick best 2 from parent and children
EquationGenome babyGene1 = (EquationGenome)((EquationGenome)GeneDads[i]).Crossover((EquationGenome)GeneMoms[i]);
EquationGenome babyGene2 = (EquationGenome)((EquationGenome)GeneMoms[i]).Crossover((EquationGenome)GeneDads[i]);
GenomeFamily.Clear();
GenomeFamily.Add(GeneDads[i]);
GenomeFamily.Add(GeneMoms[i]);
GenomeFamily.Add(babyGene1);
GenomeFamily.Add(babyGene2);
for (int j = 0; j < 4; j++)
{
CheckForUndefinedFitness((Genome)GenomeFamily[j]);
}
CalculateFitnessForAll(GenomeFamily);
GenomeFamily.Sort();
if (Best2 == true)
{
// if Best2 is true, add top fitness genes
GenomeResults.Add(GenomeFamily[0]);
GenomeResults.Add(GenomeFamily[1]);
}
else
{
GenomeResults.Add(babyGene1);
GenomeResults.Add(babyGene2);
}
}
}
public void CheckForUndefinedFitness(Genome g)
{
if (float.IsNaN(g.CurrentFitness))
g.CurrentFitness = 0.01f;
}
public void WriteNextGeneration()
{
// just write the top 20
Console.WriteLine("Generation {0}\n", Generation);
for (int i = 0; i < CurrentPopulation ; i++)
{
Console.WriteLine(((Genome)Genomes[i]).ToString());
}
Console.WriteLine("Hit the enter key to continue...\n");
Console.ReadLine();
}
public bool Converged()
{
int histogram = 0;
for (int i=1; i < Scores.Count; i++)
{
if ((int)(((float)Scores[i])*10000) == (int)(((float)Scores[i-1])*10000))
{
histogram++;
}
else
{
histogram = 0;
}
}
if (histogram > 5)
return true;
return false;
}
public void WriteNextGenerationBest()
{
Genomes.Sort();
if (Genomes.Count > 0)
{
Console.WriteLine(((Genome)Genomes[0]).ToString());
Scores.Add(((EquationGenome)Genomes[0]).CurrentFitness); // add top score;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -