Example #1
0
    public List <MapIndividual> EvolveTestChunkOnRight(List <MapIndividual> pop = null)
    {
        List <MapIndividual> population;

        if (pop == null)
        {
            population = createRightPopulation();
        }
        else
        {
            population = pop;
        }

        // Evolve over generations
        int numberOfChildren = (int)((1 - elitism) * (float)population.Count);

        MapIndividual[] children = new MapIndividual[numberOfChildren];

        for (int i = 0; i < 1; i++)
        {
            // Sort population
            population.Sort((x, y) => x.Fitness.CompareTo(y.Fitness));

            // Crossover
            for (int ci = 0; ci < numberOfChildren; ci++)
            {
                // Pick parents
                var parent1 = pickParentFromPopulation(population);
                var parent2 = pickParentFromPopulation(population);
                // Crossover parents
                MapIndividual newChild = crossover(parent1, parent2);
                children[ci] = newChild;
            }

            for (int ci = 0; ci < numberOfChildren; ci++)
            {
                population[ci] = children[ci];
            }

            // Mutation
            mutatePopulation(population);
        }

        // Update world matrix with best individual
        MapIndividual bestIndividual = population[0];

        foreach (MapIndividual individual in population)
        {
            if (individual.GetFitness() > bestIndividual.GetFitness())
            {
                bestIndividual = individual;
            }
        }

        population.Sort((x, y) => x.Fitness.CompareTo(y.Fitness));

        return(population);
    }
Example #2
0
    internal MapIndividual CrossoverWith(MapIndividual parent2)
    {
        Random random          = new Random();
        int    mutableXRange   = this.GenerationTail.GlobalX - this.GenerationHead.GlobalX + 1;
        int    leftCrossLimit  = (mutableXRange / 3);
        int    rightCrossLimit = mutableXRange - (mutableXRange / 3);

        MapIndividual leftParent  = random.Next(1) == 0 ? this : parent2;
        MapIndividual rightParent = leftParent == this ? parent2 : this;

        int maxTries = rightCrossLimit - leftCrossLimit + 1;
        int tries    = 0;
        int originalCrossoverXPoint = random.Next(leftCrossLimit, rightCrossLimit);
        int crossoverXPoint         = originalCrossoverXPoint;

        GeneColumn leftParentCrossPoint  = leftParent.GenerationHead.SeekNthColumn(crossoverXPoint);
        GeneColumn rightParentCrossPoint = rightParent.GenerationHead.SeekNthColumn(crossoverXPoint);

        int lowestDiff = Mathf.Abs(leftParentCrossPoint.GroundHeight - rightParentCrossPoint.GroundHeight);
        // Make sure gene combination creates a valid individual
        int crossoverJump = 1;

        while (tries < maxTries && !IsCrossOverXValid(leftParentCrossPoint, rightParentCrossPoint))
        {
            leftParentCrossPoint  = leftParentCrossPoint.SeekNthColumn(crossoverJump);
            rightParentCrossPoint = rightParentCrossPoint.SeekNthColumn(crossoverJump);
            if (leftParentCrossPoint.GlobalX - leftParent.GenerationHead.GlobalX > rightCrossLimit)
            {
                leftParentCrossPoint  = leftParent.GenerationHead.SeekNthColumn(leftCrossLimit);
                rightParentCrossPoint = rightParent.GenerationHead.SeekNthColumn(leftCrossLimit);
            }
            tries++;
        }

        // Here we start cloning the child genes from the left parent
        GeneColumn parentIterator = leftParent.Head;                                      // Used to iterate over left parent
        GeneColumn childHead      = new GeneColumn(parentIterator);                       // This head will be returned in the end
        GeneColumn childIterator  = new GeneColumn(parentIterator.Next, childHead, null); // To actually iterate, this is used

        childHead.Next = childIterator;
        parentIterator = parentIterator.Next; // Pointing now to the second column
        // Now, starting from the 3rd column now, iterate until the crossover point is reached
        for (parentIterator = parentIterator.Next; parentIterator != leftParentCrossPoint; parentIterator = parentIterator.Next)
        {
            // We need to clone the parent's genes, but link to the child neighbor columns.
            GeneColumn nextChildColumn = new GeneColumn(parentIterator, childIterator, null);
            childIterator.Next = nextChildColumn;
            childIterator      = nextChildColumn;
        }

        // Copy right parent genetic code to child, starting from crossover point.
        for (parentIterator = rightParentCrossPoint; parentIterator != null; parentIterator = parentIterator.Next)
        {
            GeneColumn nextChildColumn = new GeneColumn(parentIterator, childIterator, null);
            childIterator.Next = nextChildColumn;
            childIterator      = nextChildColumn;
        }
        // Finally, create an individual from the child genetic code!
        MapIndividual childIndividual = new MapIndividual(childHead);

        return(childIndividual);
    }
Example #3
0
 private MapIndividual crossover(MapIndividual parent1, MapIndividual parent2)
 {
     return(parent1.CrossoverWith(parent2));
 }
Example #4
0
    public void GenerateChunksOnRight(int numChunks)
    {
        for (int chunkIndex = 0; chunkIndex < numChunks; chunkIndex++)
        {
            List <MapIndividual> population = createRightPopulation();

            // Evolve over generations
            int             numberOfChildren = (int)((1 - elitism) * (float)population.Count);
            MapIndividual[] children         = new MapIndividual[numberOfChildren];

            for (int i = 0; i < maxIterations; i++)
            {
                // Sort population
                population.Sort((x, y) => x.Fitness.CompareTo(y.Fitness));

                // Crossover
                for (int ci = 0; ci < numberOfChildren; ci++)
                {
                    // Pick parents
                    var parent1 = pickParentFromPopulation(population);
                    var parent2 = pickParentFromPopulation(population);
                    // Crossover parents
                    MapIndividual newChild = crossover(parent1, parent2);
                    children[ci] = newChild;
                }

                for (int ci = 0; ci < numberOfChildren; ci++)
                {
                    population[ci] = children[ci];
                }

                // Mutation
                mutatePopulation(population);
            }

            // Update world matrix with best individual
            MapIndividual bestIndividual = population[0];
            foreach (MapIndividual individual in population)
            {
                if (individual.GetFitness() > bestIndividual.GetFitness())
                {
                    bestIndividual = individual;
                }
            }

            // Force playability of individual
            //bestIndividual.forcePlayability();

            // Make best individual genes unmutable
            for (GeneColumn iterator = bestIndividual.GenerationHead;
                 iterator != null && iterator.IsMutable;
                 iterator = iterator.Next)
            {
                iterator.IsMutable = false;
            }

            GlobalTail.Next = bestIndividual.GenerationHead;
            bestIndividual.GenerationHead.Previous = GlobalTail;
            GlobalTail = bestIndividual.GenerationTail;
        }
    }
Example #5
0
    public void StartTest(RTLLog log = null)
    {
        File   testData = new File();
        string fileName = "test.csv";

        if (testData.FileExists(fileName))
        {
            testData.Open(fileName, File.ModeFlags.ReadWrite);
            testData.GetCsvLine();
            while (!testData.EofReached())
            {
                Int32.TryParse(testData.GetCsvLine()[0], out int tId);
                if (this.TestId <= tId)
                {
                    this.TestId++;
                }
            }
        }
        else
        {
            testData.Open(fileName, File.ModeFlags.Write);
            testData.StoreCsvLine(GenerationResult.GetHeaderStringArray());
        }
        if (log != null)
        {
            log.LogLine($"Initiating test id {this.TestId} with config: popSize {this.PopulationSize}, mutRate {MutationRate}, elitism {Elitism}, maxIterations {MaxIterations}.");
        }
        // First generation of this test batch
        // Start timer to track ellapsed time per generation
        var    watch    = System.Diagnostics.Stopwatch.StartNew();
        double duration = 0;
        // the code that you want to measure comes here
        int genNumber = 0;
        List <MapIndividual> population              = Generator.EvolveTestChunkOnRight();
        MapIndividual        bestIndividual          = population[population.Count - 1];
        GenerationResult     currentGenerationResult = new GenerationResult {
            TestId                    = this.TestId,
            BestFitness               = bestIndividual.Fitness,
            GenerationNumber          = genNumber,
            FivePercentBestFitnessAvg = getFivePercentAvg(population),
            IsBestPlayable            = bestIndividual.IsPlayable,
            FitnessAverage            = getFitnessAverage(population),
            FitnessMedian             = getFitnessMedian(population),
            PopulationSize            = this.PopulationSize,
            GenChunkSize              = this.GenChunkSize,
            MutationRate              = this.MutationRate,
            Elitism                   = this.Elitism,
        };

        watch.Stop();
        currentGenerationResult.ExecutionTimeMs = watch.ElapsedMilliseconds;
        testData.StoreCsvLine(currentGenerationResult.GetCsvStringArray());

        for (genNumber = genNumber + 1; genNumber <= MaxIterations; genNumber++)
        {
            watch                   = System.Diagnostics.Stopwatch.StartNew();
            population              = Generator.EvolveTestChunkOnRight(population);
            bestIndividual          = population[population.Count - 1];
            currentGenerationResult = new GenerationResult {
                TestId                    = this.TestId,
                BestFitness               = bestIndividual.Fitness,
                GenerationNumber          = genNumber,
                FivePercentBestFitnessAvg = getFivePercentAvg(population),
                IsBestPlayable            = bestIndividual.IsPlayable,
                FitnessAverage            = getFitnessAverage(population),
                FitnessMedian             = getFitnessMedian(population),
                PopulationSize            = this.PopulationSize,
                GenChunkSize              = this.GenChunkSize,
                MutationRate              = this.MutationRate,
                Elitism                   = this.Elitism,
            };
            watch.Stop();
            currentGenerationResult.ExecutionTimeMs = watch.ElapsedMilliseconds;
            duration += watch.ElapsedMilliseconds;
            testData.StoreCsvLine(currentGenerationResult.GetCsvStringArray());
        }
        // Close file at the end of this test
        testData.Close();
        TimeSpan t = TimeSpan.FromMilliseconds(duration);
        string   durationString = string.Format("{0:D2}h:{1:D2}m:{2:D2}s:{3:D3}ms",
                                                t.Hours, t.Minutes, t.Seconds, t.Milliseconds);

        if (log != null)
        {
            log.LogLine($"Done with test {this.TestId} in {durationString}!");
        }
    }