Source file unity-csharp/nature-of-code/genetic-algorithm-text/TextPopulationManager.cs from the GDnD code examples. Download raw file

// GDnD wiki example
// Demonstrates: Population loop for a beginner Unity genetic algorithm
// Related pages: [[genetic-algorithms]], [[overview-unity-nature-of-code-examples]]
 
using UnityEngine;
 
public class TextPopulationManager : MonoBehaviour
{
    [SerializeField] private string target = "HELLO UNITY";
    [SerializeField] private int populationSize = 100;
    [SerializeField, Range(0f, 0.2f)] private float mutationRate = 0.01f;
 
    private DNA[] population;
    private int generation;
 
    private void Start()
    {
        population = new DNA[populationSize];
 
        for (int i = 0; i < population.Length; i++)
            population[i] = new DNA(target.Length);
    }
 
    private void Update()
    {
        EvolveOneGeneration();
    }
 
    private void EvolveOneGeneration()
    {
        foreach (DNA dna in population)
            dna.Evaluate(target);
 
        DNA bestCurrent = GetBest();
        DNA[] next = new DNA[population.Length];
 
        for (int i = 0; i < next.Length; i++)
        {
            DNA parentA = PickParent();
            DNA parentB = PickParent();
            DNA child = parentA.Crossover(parentB);
            child.Mutate(mutationRate);
            next[i] = child;
        }
 
        population = next;
        generation++;
 
        Debug.Log($"Generation {generation}: {bestCurrent.Text}");
    }
 
    private DNA PickParent()
    {
        float bestFitness = GetBest().Fitness;
 
        if (bestFitness <= 0f)
            return population[Random.Range(0, population.Length)];
 
        while (true)
        {
            DNA candidate = population[Random.Range(0, population.Length)];
            if (Random.value < candidate.Fitness)
                return candidate;
        }
    }
 
    private DNA GetBest()
    {
        DNA best = population[0];
 
        for (int i = 1; i < population.Length; i++)
            if (population[i].Fitness > best.Fitness)
                best = population[i];
 
        return best;
    }
}