// Use the temp population to get the next gerneration using crossover and partner selection public static List <Organism> generateNextGen(List <Organism> gen) { List <int> gene = new List <int>(); List <int> crossPoitns = new List <int>(); List <Organism> nextGen = new List <Organism>(); if (elitism) { Organism elite = new Organism(GENES); foreach (Organism org in gen) { if (org.fitness + org.numberOfdecptives > elite.fitness + elite.numberOfdecptives) { elite = org; } } nextGen.Add(elite); } //Cross over first for (var pop = nextGen.Count; pop < POPULATION; pop++) { // Get best partner for organism var parentB = getPartner(gen, pop); nextGen.Add(new Organism(GENES)); if (!weightedCrossover) { while (crossPoitns.Count < numOfCrossPoints) { var point = GetRandomNumber(0, GENES); if (!crossPoitns.Contains(point)) { crossPoitns.Add(point); } } } else if (weightedCrossover && numOfCrossPoints == 1) { float fitnessA = gen[pop].fitness + (gen[pop].numberOfdecptives * 10); float fitnessB = gen[parentB].fitness + (gen[parentB].numberOfdecptives * 10); float com = fitnessA + fitnessB; float cross = (fitnessA / com); cross = cross * GENES; crossPoitns.Add((int)cross); } crossPoitns.Add(0); crossPoitns.Sort(); // This is the cross over algorithm uses random cross point. // Test use of different number of cross points // Maybe add weighted cross over or min differenc between cross points // Add ability for multiple cross over. // Should cross points change for each cross over or stay the same for each generation var endPoint = 0; var parent = 0; if (!uniformCrossover && !halfUniformCrossover) { for (var b = 0; b < crossPoitns.Count; b++) { endPoint = b + 1 < crossPoitns.Count ? crossPoitns[b + 1] : GENES; if (parent == 0) { gene = gen[pop].spliceGenes(crossPoitns[b], endPoint); nextGen[pop].addGenes(gene, crossPoitns[b], endPoint); parent = 1; } else if (parent == 1) { gene = gen[parentB].spliceGenes(crossPoitns[b], endPoint); nextGen[pop].addGenes(gene, crossPoitns[b], endPoint); parent = 0; } } nextGen[pop] = mutate(nextGen[pop]); crossPoitns.Clear(); } else if (uniformCrossover) { var end = 0; var start = 0; for (var g = 0; g < ALLELES; g++) { var rand = GetRandomNumber(1, 10); if (rand < 5) { end += alleleSizes[g]; var genes = gen[parent].spliceGenes(start, end); nextGen[pop].addGenes(genes, start, end); } else { end += alleleSizes[g]; var genes = gen[parentB].spliceGenes(start, end); nextGen[pop].addGenes(genes, start, end); } start = end; } nextGen[pop].fitness = 0; nextGen[pop].numberOfdecptives = 0; nextGen[pop] = mutate(nextGen[pop]); crossPoitns.Clear(); } else if (halfUniformCrossover) { var toSwap = getHammingDistance(gen[pop], gen[parentB]) / 2; nextGen[pop].genes = gen[pop].genes; var swaped = 0; List <int> changed = new List <int>(); while (swaped != toSwap) { var rand = GetRandomNumber(0, GENES - 1); if (!changed.Contains(rand)) { changed.Add(rand); if (gen[pop].genes[rand] != gen[parentB].genes[rand]) { nextGen[pop].genes.SetValue(gen[parentB].genes[rand], rand); swaped++; } } } nextGen[pop].fitness = 0; nextGen[pop].numberOfdecptives = 0; nextGen[pop] = mutate(nextGen[pop]); crossPoitns.Clear(); } } if (!useEpistasis) { checkForIdeal(nextGen); } return(nextGen); }