DNA GenerateNewDNA() { currentDNA.CalculateFitness(transform.position, playerLastKnownPosition); List <DNA> dna = AI.dnaLegacy[currentDegRegion, currentRangeRegion]; // Remove less fit dna if (dna.Count == size) { int lessFitIndex = 0; float minFitness = 1000000f; for (int i = 0; i < dna.Count; i++) { if (minFitness > dna[i].fitness) { lessFitIndex = i; minFitness = dna[i].fitness; } } if (currentDNA.fitness > lessFitIndex) { dna[lessFitIndex] = currentDNA; } } else { dna.Add(currentDNA); } AI.dnaLegacy[currentDegRegion, currentRangeRegion] = dna; FindRegion(); dna = AI.dnaLegacy[currentDegRegion, currentRangeRegion]; // Mating List <DNA> matingPool = new List <DNA>(); for (int i = 0; i < dna.Count; i++) { for (int j = 0; j < dna[i].fitness; j++) { matingPool.Add(dna[i]); } } float mutationRate = 0.1f; float prob = Random.Range(0.0f, 1.0f); Debug.Log("Prob: " + prob); if (matingPool.Count >= 2 && prob > mutationRate) { int indexA = Random.Range(0, matingPool.Count - 1); DNA parentA = matingPool[indexA]; int indexB = Random.Range(0, matingPool.Count - 1); DNA parentB = matingPool[indexB]; Debug.Log("Before crossover"); return(Crossover(parentA, parentB)); } else { return(new DNA(transform.position, playerLastKnownPosition)); } }
// Generates new population after the individuals in the first population is setup public void NewGeneration() { if (population.Count <= 0) { return; } // Calculates the total sum of the fitness in the population to be used when choosing a parent CalculatePopulationFitness(); // Sorts the population from highest fitness to lowest population.Sort(compareDNA); newPopulation.Clear(); //Debug.Log(population[0].fitness); // Iterates through the population and either adds individuals through elitism or the result of crossover for (int i = 0; i < population.Count; i++) { // Takes x amount of the fittest individuals and directly adds them to the new population if (i < elitism) { newPopulation.Add(population[i]); } else { // Chooses two parents from the population by having their fitness divided by the fitness sum to create their probability DNA parent1 = ChooseParent(); DNA parent2 = ChooseParent(); // A child of the two parents are made through crossover so there is a 50/50 split between the genes of the parents DNA child = parent1.Crossover(parent2); // Mutation is applied with a 1% to all genes to change by a small amount and is necessary to introduce variance child.Mutation(); // The fitness of the child is calculated based on the target DNA child.fitness = child.CalculateFitness(gameManager.targetDNA); // Data analyzer all new fitness // bestFitness.Add(child.fitness); // The child is added to the new generation newPopulation.Add(child); } } // New generation replaces old generation List <DNA> tempList = population; population = newPopulation; newPopulation = tempList; // Generation counter is incremented generation++; }
public void GenerationsPassed() { if (initialize) { gameManager.SetTargetDNA(); for (int i = 0; i < populationSize; i++) { DNA dna = new DNA(); dna.RandomDNA(); dna.CalculateFitness(gameManager.targetDNA); population.Add(dna); } population.Sort(compareDNA); population[0].fitness = Mathf.Round(population[0].fitness); // Add best gene of first generation bestGenes.Add(population[0]); generation++; for (int i = 0; i < generationsPassed - 1; i++) { NewGeneration(); population.Sort(compareDNA); // Add best gene of first generation bestGenes.Add(population[0]); } saveManager.Save(population[0], generation); saveManager.LoadSave(); initialize = false; } else { gameManager.SetTargetDNA(); for (int i = 0; i < generationsPassed; i++) { NewGeneration(); population.Sort(compareDNA); // Add best gene of first generation bestGenes.Add(population[0]); } // GenerationCheck(); saveManager.Save(population[0], generation); saveManager.LoadSave(); } //for (int i = 0; i < bestGenes.Count; i++) //{ // Debug.Log(bestGenes[i].fitness); //} }