예제 #1
0
 public GeneSequence Clone()
 {
     var geneSequence = new GeneSequence(Genes.ToArray(), Strategy)
         {
             Fitness = Fitness
         };
     if (_stringGenes !=null)
     {
         geneSequence._stringGenes = _stringGenes;
     }
     return geneSequence;
 }
예제 #2
0
 private void PrintBest(int generation, GeneSequence geneSequence)
 {
     DisplayGenes(1 + generation, geneSequence.Fitness.Value, geneSequence.GetStringGenes(), geneSequence.Strategy.Description);
 }
예제 #3
0
 private static int FitnessSort(GeneSequence x, GeneSequence y)
 {
     int result = x.Fitness.Value.CompareTo(y.Fitness.Value);
     if (result == 0)
     {
         result = y.Generation.CompareTo(x.Generation);
     }
     return result;
 }
예제 #4
0
        public GeneSequence GetBestGenetically(int numberOfGenesToUse, string possibleGenes, Func<string, FitnessResult> calcFitness)
        {
            int seed = _randomSeed != 0 ? _randomSeed : (int)DateTime.Now.Ticks;
            Console.WriteLine("using random seed: " + seed);
            _random = new Random(seed);

            var popAlpha = new List<GeneSequence>(GaPopsize);
            var popBeta = new List<GeneSequence>(GaPopsize);

            Func<char> getRandomGene = () => possibleGenes[_random.Next(possibleGenes.Length)];

            InitPopulation(UseHillClimbing ? NumberOfGenesInUnitOfMeaning : numberOfGenesToUse, popAlpha, popBeta, getRandomGene);
            var population = popAlpha;
            var spare = popBeta;
            var previousBests = new List<GeneSequence>
                {
                    population.First()
                };
            previousBests[0].Fitness = calcFitness(previousBests[0].GetStringGenes());
            int generation = 0;

            var generationsBetweenImprovments = Enumerable.Repeat(_gaMaxGenerationsWithoutImprovement, 20).ToList();

            if (UseHillClimbing)
            {
                int failureToImproveCount = 0;
                var bestEver = new GeneSequence(new char[] { }, null)
                    {
                        Fitness = new FitnessResult{Value = UInt32.MaxValue}
                    };
                for (int i = NumberOfGenesInUnitOfMeaning; i < numberOfGenesToUse - 1; i += NumberOfGenesInUnitOfMeaning)
                {
                    GetBestGenetically(OnlyPermuteNewGenesWhileHillClimbing ? i - NumberOfGenesInUnitOfMeaning : 0, i, getRandomGene, previousBests, population, spare, calcFitness, generationsBetweenImprovments, ref generation);
                    var incrementalBest = previousBests.First();
                    if (incrementalBest.Fitness.Value < bestEver.Fitness.Value)
                    {
                        bestEver = incrementalBest.Clone();
                        failureToImproveCount = 0;
                    }
                    else
                    {
                        failureToImproveCount++;
                        if (incrementalBest.Fitness.Value > bestEver.Fitness.Value * 1.05m || failureToImproveCount >= 5)
                        {
                            Console.WriteLine("Fitness appears to be getting worse, returning best result: fitness " + bestEver.Fitness.Value + " in generation " + bestEver.Generation);
                            return bestEver;
                        }
                    }
                    var parents = previousBests.ToList();
                    population.Clear();
                    spare.Clear();

                    previousBests.Clear();
                    for (int j = 0; j < GaPopsize; j++)
                    {
                        var random = _randomStrategy.Generate(null, NumberOfGenesInUnitOfMeaning, getRandomGene, NumberOfGenesInUnitOfMeaning, _slidingMutationRate, _random.Next, 0);
                        var newChild = new GeneSequence(parents[j % parents.Count].Genes.Concat(random.Genes).ToArray(), _mutationStrategy)
                            {
                                Fitness = GeneSequence.DefaultFitness
                            };

                        population.Add(newChild);
                        spare.Add(newChild.Clone());
                    }
                    previousBests.AddRange(population.Select(x =>
                        {
                            x.Fitness = calcFitness(x.GetStringGenes());
                            return x;
                        }).Where(x => x.Fitness.Value < incrementalBest.Fitness.Value));
                    if (previousBests.Count < 100)
                    {
                        previousBests.AddRange(population.OrderBy(x => x.Fitness.Value).Take(100 - previousBests.Count));
                    }
                    SortByFitness(previousBests);
                    int count = 1 + (i / NumberOfGenesInUnitOfMeaning);
                    Console.WriteLine("> " + count);
                    if (previousBests[0].Fitness.Value < incrementalBest.Fitness.Value)
                    {
                        PrintBest(generation, previousBests[0]);
                    }
                }
                return bestEver;
            }

            GetBestGenetically(0, numberOfGenesToUse, getRandomGene, previousBests, population, spare, calcFitness, generationsBetweenImprovments, ref generation);
            var best = previousBests.First();
            return best;
        }