private void crossover(Chromosone chromosoneA, Chromosone chromosoneB, CROSSOVERTYPE type) { if (!shouldCombine) { return; } switch (type) { case CROSSOVERTYPE.DUAL: int pointA = NeuralNet.Random.Next(0, chromosoneA.Genes.Count); int pointB = NeuralNet.Random.Next(0, chromosoneA.Genes.Count); int temp = pointA; pointA = pointA < pointB ? pointA : pointB; pointB = temp > pointB ? temp : pointB; // assert A is smaller than B var copyOfA = new List <Gene>(chromosoneA.Genes); var copyOfB = new List <Gene>(chromosoneB.Genes); chromosoneA.Genes.Clear(); chromosoneB.Genes.Clear(); chromosoneA.Genes.AddRange(new List <Gene>(copyOfA.GetRange(0, pointA))); chromosoneA.Genes.AddRange(new List <Gene>(copyOfB.GetRange(pointA, pointB - pointA))); chromosoneA.Genes.AddRange(new List <Gene>(copyOfA.GetRange(pointB, copyOfA.Count - pointB))); chromosoneB.Genes.AddRange(new List <Gene>(copyOfB.GetRange(0, pointA))); chromosoneB.Genes.AddRange(new List <Gene>(copyOfA.GetRange(pointA, pointB - pointA))); chromosoneB.Genes.AddRange(new List <Gene>(copyOfB.GetRange(pointB, copyOfB.Count - pointB))); break; default: crossover(chromosoneA, chromosoneB, CROSSOVERTYPE.DUAL); // Should never happen break; } }
private void mutate(Chromosone chrom) { chrom.Genes.ForEach(gene => { if (!shouldMutate) { return; } gene.generateRandom(); }); }
public void Train(List <DataSet> dataSets, int numEpochs, int numGenerations) { List <Chromosone> bestInEpoch = new List <Chromosone>(); for (int epoch = 0; epoch < numEpochs; epoch++) { string debugStr = ""; debugStr += ("**********NEW EPOCH (" + epoch + ")*************\n"); //population.individuals.ForEach(chrom => debugStr += chrom.Genes.Count + ", "); Debug.Log(debugStr); // Generate genes population.regenerate(); for (int generation = 0; generation < numGenerations; generation++) { debugStr = ""; debugStr += ("**********NEW GENERATION (" + generation + ")*************\n"); //population.individuals.ForEach(chrom => debugStr += chrom.Genes.Count + ", "); Debug.Log(debugStr); population.individuals.ForEach(chrom => chrom.resetFitness()); dataSets.ForEach(ds => { for (int individual = 0; individual < population.individuals.Count; individual++) { // Set weights to genes updateWeights(population.individuals[individual].getWeights()); ForwardPropagate(ds.Values); // Calculate fitness // TODO: Only calculates last dataset technically, should be nested, dataset => evolve => new dataset population.individuals[individual].calculateFitness(OutputLayer.Select(neuron => neuron.Value).ToArray(), ds.Targets, dataSets.Count); } // Evolve population.evolve(); }); } // Save best individual bestInEpoch.Add(Population.getBest(population.individuals, false)); string outputStr = ""; var descendingPopulation = new List <Chromosone>(new List <Chromosone>(population.individuals).OrderByDescending(chrom => chrom.Fitness)); descendingPopulation.ForEach(chrom => outputStr += chrom.Fitness + ", "); Debug.Log(outputStr + "\nBest in epoch: " + bestInEpoch.Last().Fitness); } // Get best individual from the epochs Chromosone bestOverall = Population.getBest(bestInEpoch, false); updateWeights(bestOverall.getWeights()); Debug.Log("Best overall: " + bestOverall.Fitness); }
public void evolve() { Population childPopulation = new Population(0, 0, mutationRate); while (childPopulation.individuals.Count < individuals.Count) { // Selection Chromosone chromA = Selection(SELECTIONTYPE.TOURNAMENT); Chromosone chromB = Selection(SELECTIONTYPE.TOURNAMENT); // Cross over crossover(chromA, chromB, CROSSOVERTYPE.DUAL); // Mutations mutate(chromA); mutate(chromB); // Add new individuals childPopulation.individuals.Add(chromA); childPopulation.individuals.Add(chromB); } individuals = new List <Chromosone>(childPopulation.individuals); // NOPE SHALLOW COPY! }
public Chromosone(Chromosone other) { Genes = new List <Gene>(other.Genes); Fitness = other.Fitness; }