Пример #1
0
    public MutationInformation MutatePopulation(Population pop, float mutationScaleFactor, bool multipleMutationsPerGenomeAllowed, float reductionFactor)
    {
        MutationInformation info = new MutationInformation();

        WeightMutatedGenomes.Clear();
        TopologyMutatedGenomes.Clear();

        int previousUniqueNewNodeMutations       = NewNodeMutations.Count;
        int previousUniqueNewConnectionMutations = NewConnectionMutations.Count;

        float topologyMutationChancePerGenome = BaseTopologyMutationChancePerGenome * mutationScaleFactor;
        float weightMutationChancePerGenome   = BaseWeightMutationChancePerGenome * mutationScaleFactor;

        foreach (Genome g in pop.Subjects.Where(x => !x.ImmuneToMutation).Select(s => s.Genome))
        {
            MutateGenome(g, topologyMutationChancePerGenome, weightMutationChancePerGenome, multipleMutationsPerGenomeAllowed, reductionFactor, info);
        }

        info.NumNewUniqueConnectionsMutations  = NewConnectionMutations.Count - previousUniqueNewConnectionMutations;
        info.NumNewUniqueNodeMutations         = NewNodeMutations.Count - previousUniqueNewNodeMutations;
        info.MultipleMutationsPerGenomeAllowed = multipleMutationsPerGenomeAllowed;
        info.WeightMutationChancePerGenome     = weightMutationChancePerGenome;
        info.TopologyMutationChancePerGenome   = topologyMutationChancePerGenome;
        info.MutationChanceScaleFactor         = mutationScaleFactor;
        info.NumTopologyMutatedGenomes         = TopologyMutatedGenomes.Count;
        info.NumWeightMutatedGenomes           = WeightMutatedGenomes.Count;

        return(info);
    }
Пример #2
0
 public Parameters(int popSize, EncodingInformation encoding, SelectionInformation selection,
                   CrossoverInformation crossover, MutationInformation mutation, StoppingInformation stopping)
 {
     _populationSize = popSize;
     _encodingInfo   = encoding;
     _selectionInfo  = selection;
     _crossoverInfo  = crossover;
     _mutationInfo   = mutation;
     _stoppingInfo   = stopping;
 }
Пример #3
0
    public void MutateWeight(Genome g, MutationInformation info)
    {
        double rng = Random.NextDouble();

        if (rng <= ReplaceChance)
        {
            ReplaceWeight(g);
            if (info != null)
            {
                info.NumReplaceMutations++;
            }
        }
        else if (rng <= ReplaceChance + ShiftChance)
        {
            ShiftWeight(g);
            if (info != null)
            {
                info.NumShiftMutations++;
            }
        }
        else if (rng <= ReplaceChance + ShiftChance + ScaleChance)
        {
            ScaleWeight(g);
            if (info != null)
            {
                info.NumScaleMutations++;
            }
        }
        else if (rng <= ReplaceChance + ShiftChance + ScaleChance + InvertChance)
        {
            InvertWeight(g);
            if (info != null)
            {
                info.NumInvertMutations++;
            }
        }
        else if (rng <= ReplaceChance + ShiftChance + ScaleChance + InvertChance + SwapChance)
        {
            if (CanSwapWeights(g))
            {
                SwapWeights(g);
                if (info != null)
                {
                    info.NumSwapMutations++;
                }
            }
            else
            {
                MutateWeight(g, info);  // Try Again
            }
        }
    }
Пример #4
0
        private void InitGA()
        {
            popSize = Settings.s0;
            noGen   = Settings.ngen;

            EncodingInformation enc = new EncodingInformation(n, EncodingType.RealValued);

            for (int i = 0; i < n; i++)
            {
                enc.MinValues[i] = Settings.minval;
                enc.MaxValues[i] = Settings.maxval;
            }

            SelectionInformation sel = new SelectionInformation
            {
                Type           = SelectionType.Tournament,
                TournamentSize = 2,
                Elitism        = 1
            };

            CrossoverInformation cro = new CrossoverInformation
            {
                Type        = CrossoverType.ArithmeticInteger,
                Probability = 0.9
            };

            MutationInformation mut = new MutationInformation
            {
                Type = MutationType.Gaussian,
                StandardDeviation = Settings.sigma,
                Probability       = Settings.pm
            };

            StoppingInformation stop = new StoppingInformation
            {
                Type           = StoppingType.Generations,
                MaxGenerations = noGen
            };

            _parameters = new Parameters(popSize, enc, sel, cro, mut, stop);
        }
Пример #5
0
 public EvolutionInformation(int generation, int evolutionTime, bool mutationImmunityForTakeOvers, MutationInformation mutationInfo, int numBestSubjectsTakenOver, int numRandomSubjectsTakenOver, int numOffsprings, int numSubjectsCheckedForAdoption, int numImmuneToMutationSubjects, int numPreviousSpecies, int numEliminatedSpecies, int numEmptySpecies, int numNewSpecies, int numSpecies, float compThreshhold, float maxFitness, float averageFitness, int limit, int gensBelowLimit)
 {
     Generation    = generation;
     EvolutionTime = evolutionTime;
     MutationImmunityForTakeOvers = mutationImmunityForTakeOvers;
     MutationInfo                  = mutationInfo;
     NumBestSubjectsTakenOver      = numBestSubjectsTakenOver;
     NumRandomSubjectsTakenOver    = numRandomSubjectsTakenOver;
     NumOffsprings                 = numOffsprings;
     NumSubjectsCheckedForAdoption = numSubjectsCheckedForAdoption;
     NumImmuneToMutationSubjects   = numImmuneToMutationSubjects;
     NumPreviousSpecies            = numPreviousSpecies;
     NumEliminatedSpecies          = numEliminatedSpecies;
     NumEmptySpecies               = numEmptySpecies;
     NumNewSpecies                 = numNewSpecies;
     NumSpecies = numSpecies;
     CompatibilityThreshhold = compThreshhold;
     MaxFitness            = maxFitness;
     AverageFitness        = averageFitness;
     RankLimit             = limit;
     GensAllowedBelowLimit = gensBelowLimit;
 }
Пример #6
0
    public void MutateTopology(Genome g, MutationInformation info, List <NewNodeMutation> newNodeMutations, List <NewConnectionMutation> newConnectionMutations)
    {
        int possibleNewNodeMutations       = FindCandidateConnectionsForNewNode(g).Count;
        int possibleNewConnectionMutations = FindCandidateConnections(g).Count;
        int allPossibleMutations           = possibleNewNodeMutations + possibleNewConnectionMutations;

        float addNewNodeChance = (float)possibleNewNodeMutations / (float)allPossibleMutations;

        double rng = Random.NextDouble();

        if (rng <= addNewNodeChance)
        {
            NewNodeMutation mutation = AddNode(g, newNodeMutations);
            if (newNodeMutations.Where(x => x.SplittedConnectionId == mutation.SplittedConnectionId).Count() == 0)
            {
                newNodeMutations.Add(mutation);
            }
            if (info != null)
            {
                info.NumNewNodeMutations++;
            }
        }
        else
        {
            NewConnectionMutation mutation = AddConnection(g, newConnectionMutations);
            if (newConnectionMutations.Where(x =>
                                             (x.FromNodeId == mutation.FromNodeId && x.ToNodeId == mutation.ToNodeId) ||
                                             (x.FromNodeId == mutation.ToNodeId && x.ToNodeId == mutation.FromNodeId)
                                             ).Count() == 0)
            {
                newConnectionMutations.Add(mutation);
            }
            if (info != null)
            {
                info.NumNewConnectionsMutations++;
            }
        }
    }
Пример #7
0
    /// <summary>
    /// Runs the mutation alogorithm through a genome with the given parameters.
    /// </summary>
    private void MutateGenome(Genome g, float topologyMutationChancePerGenome, float weightMutationChancePerGenome, bool multipleMutationsPerGenomeAllowed, float reducationFactor, MutationInformation info)
    {
        // If the genome has no connections, it can only mutate topology
        if (g.EnabledConnections.Count() == 0)
        {
            topologyMutationChancePerGenome += weightMutationChancePerGenome;
            weightMutationChancePerGenome    = 0;
        }

        double rng = Random.NextDouble();

        int numMutations = 0;

        while (rng <= ((topologyMutationChancePerGenome + weightMutationChancePerGenome) * (Math.Pow(1 - reducationFactor, numMutations))))
        {
            if (rng <= topologyMutationChancePerGenome)
            {
                TopologyMutatedGenomes.Add(g);
                TopologyMutator.MutateTopology(g, info, NewNodeMutations, NewConnectionMutations);
            }
            else
            {
                WeightMutatedGenomes.Add(g);
                WeightMutator.MutateWeight(g, info);
            }
            numMutations++;
            rng = multipleMutationsPerGenomeAllowed ? Random.NextDouble() : 1; // Allows for multiple mutations per genome
        }
    }
Пример #8
0
    public EvolutionInformation EvolveGeneration()
    {
        DateTime       startTimeStamp     = DateTime.Now;
        DateTime       stamp              = DateTime.Now;
        List <Subject> newSubjects        = new List <Subject>();
        int            numPreviousSpecies = Species.Count;

        // Calculate fitness & rank of each subject and species
        GetFitness();
        float averageFitness = Subjects.Average(x => x.Genome.Fitness);
        float maxFitness     = Subjects.Max(x => x.Genome.Fitness);

        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Get Fitness");
        }

        // Eliminate species without improvement for too long
        int numEliminatedSpecies = EliminateBadSpecies(RankNeededToSurvive, GenerationsBelowRankAllowed);

        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Eliminate Bad Species");
        }

        // Take a random representative for each existing species
        CreateSpeciesRepresentatives();
        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Create Representatives");
        }

        int numSubjectsImmuneToMutations = 0;
        // Take over best subjects of each species
        int numBestSubjects = TakeOverBestSubjects(newSubjects, TakeOverBestRatio, AreTakeOversImmuneToMutation);

        if (AreTakeOversImmuneToMutation)
        {
            numSubjectsImmuneToMutations += numBestSubjects;
        }
        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Take over Best Subjects");
        }

        // Take over random lucky subjects of each species
        int numRandomSubjects = TakeOverRandomSubjects(newSubjects, TakeOverRandomRatio, AreTakeOversImmuneToMutation);

        if (AreTakeOversImmuneToMutation)
        {
            numSubjectsImmuneToMutations += numRandomSubjects;
        }
        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Take over Random Subjects");
        }

        // Evaluate which species is allowed to produce how many offsprings
        int numOffsprings = Size - numBestSubjects - numRandomSubjects;

        CalculateOffspringNumberPerSpecies(numOffsprings);
        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Calculate Offspring numbers");
        }

        // Create offsprings with a chance to automatically have the same species as its parents
        List <Subject> toSpeciate = CreateOffsprings(newSubjects);
        int            numSubjectsCheckedForAdoption = toSpeciate.Count;

        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Create Offsprings");
        }

        // Moves subjects from the newSubjects list to the Subjects list (that it also clears)
        ReplaceSubjects(newSubjects);
        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Replace Subjects");
        }

        // Mutate the genomes in all subjects that are not marked immuneToMutation according to chances in the mutatealgorithm
        MutationInformation mutationInfo = MutateAlgorithm.MutatePopulation(this, CurrentMutationChanceScaleFactor, MultipleMutationsPerGenomeAllowed, MutationChanceReductionFactorPerMutation);

        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Mutate Population");
        }

        // Speciate all subjects that haven't gotten a species yet
        int numNewSpecies = Speciator.Speciate(toSpeciate, Species);

        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Speciate unspeciated Subjects");
        }

        // Fill species with new subjects
        foreach (Species s in Species)
        {
            s.Subjects.Clear();
        }
        foreach (Subject subject in Subjects)
        {
            subject.Genome.Species.Subjects.Add(subject);
        }
        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Replace Subjects in Species");
        }

        // Remove empty species
        List <Species> emptySpecies = new List <Species>();

        foreach (Species species in Species)
        {
            if (species.Subjects.Count == 0)
            {
                emptySpecies.Add(species);
            }
        }
        foreach (Species remove in emptySpecies)
        {
            Species.Remove(remove);
        }
        int numEmptySpecies = emptySpecies.Count;

        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Remove empty Species");
        }

        // Go to next generation
        Generation++;
        if (CurrentMutationChanceScaleFactor > MinMutationChanceFactor)
        {
            CurrentMutationChanceScaleFactor -= MutationChanceFactorReductionPerGeneration;
        }

        // Name the subjects
        for (int i = 0; i < Subjects.Count; i++)
        {
            if (String.IsNullOrEmpty(Subjects[i].Name))
            {
                Subjects[i].Name = Generation + "-" + Subjects[i].Genome.Species.Id + "-" + i;
            }
        }

        if (Subjects.Count != Species.Sum(x => x.Subjects.Count))
        {
            throw new Exception("SPECIATION FAILED. The number of subjects in the species does not match the number of subjects in the population.");
        }

        // Create the evolution information object
        int evolutionTime         = (int)((DateTime.Now - startTimeStamp).TotalMilliseconds);
        EvolutionInformation info = new EvolutionInformation(Generation, evolutionTime,
                                                             AreTakeOversImmuneToMutation, mutationInfo, numBestSubjects, numRandomSubjects, numOffsprings,
                                                             numSubjectsCheckedForAdoption, numSubjectsImmuneToMutations,
                                                             numPreviousSpecies, numEliminatedSpecies, numEmptySpecies, numNewSpecies, Species.Count, SpeciesCompatiblityThreshhold,
                                                             maxFitness, averageFitness,
                                                             RankNeededToSurvive, GenerationsBelowRankAllowed);

        Debug.Log(info.ToString());

        // Reset the species fitness values
        //foreach (Species s in Species) s.CalculateFitnessValues();

        return(info);
    }