Exemplo n.º 1
0
        public void ReCalculateFitness(ref IWeightedList <ConcreteSpecimen> population)
        {
            var minimum = double.PositiveInfinity;
            var maximum = double.NegativeInfinity;

            foreach (var item in population)
            {
                // We are searching for global minimum.
                // Maybe the number of global minimum is infinite.
                var functionValue = FitnessFunction(item.Item.X);
                if (functionValue < minimum)
                {
                    minimum = functionValue;
                }

                if (functionValue > maximum)
                {
                    maximum = functionValue;
                }

                item.Weight = functionValue;
            }

            var diff = maximum - minimum + 1; // +1 to avoid division by zero

            foreach (var item in population)
            {
                var p = 1 - ((item.Weight + minimum) / diff);
                item.Weight = p;
            }
        }
        public void Mutate(ref IWeightedList <ConcreteSpecimen> population)
        {
            // Mutate
            var numberOfMutableProperties      = 1;
            var totalNumberOfMutableProperties = population.Count * numberOfMutableProperties; // population size * number of mutable properties.

            var indexes = Enumerable.Range(0, totalNumberOfMutableProperties)
                          .OrderBy(x => Guid.NewGuid())
                          .Take((int)Math.Floor(_mutationProbability * totalNumberOfMutableProperties));

            iteration = (iteration + 1) % 10;

            var strength = Math.Sin((iteration / 10.0d) * Math.PI);

            var mutationFactorX = strength * (random.Next(0, 2) == 0 ? -1 : 1) * random.NextDouble() * 10d;

            foreach (var idx in indexes)
            {
                var cellIndex     = idx / numberOfMutableProperties;
                var propertyIndex = idx % numberOfMutableProperties;

                var specimen = population[cellIndex].Item;

                var x = specimen.X;

                switch (propertyIndex)
                {
                case 0: x = x + mutationFactorX; break;

                default: throw new ArgumentOutOfRangeException(nameof(propertyIndex));
                }

                var mutatedSpecimen = new ConcreteSpecimen(x);

                population[cellIndex] = new WeightedItem <ConcreteSpecimen>(mutatedSpecimen, 0);
            }
        }
Exemplo n.º 3
0
 public void Initialize(int starterPopulationSize)
 {
     _population = _populationBuilder.Build(starterPopulationSize);
 }
Exemplo n.º 4
0
        public void NaturalSelection(ref IWeightedList <ConcreteSpecimen> population)
        {
            var originalPopulation = population.ToArray();

            population.Clear();
            var count               = originalPopulation.Length;
            var numberOfParents     = 2;
            var sumFitness          = originalPopulation.Sum(x => x.Weight);
            var random              = new Random();
            var acceptableSpecimens = new List <ConcreteSpecimen>();

            /**************************************************************************************************
            *    Based on https://stackoverflow.com/questions/10765660/roulette-wheel-selection-procedure    *
            **************************************************************************************************
            *                                                                                                *
            *    For all members of population                                                               *
            *         sum += fitness ( member )                                                              *
            *    End for                                                                                     *
            *                                                                                                *
            *    Loop until new population is full                                                           *
            *         Do this twice                                                                          *
            *              Number = Random between 0 and sum                                                 *
            *              Currentfitness = 0.0                                                              *
            *              For each member in population                                                     *
            *                 Currentfitness += fitness(member)                                              *
            *                 if Number > Currentfitness then select member                                  *
            *              End for                                                                           *
            *         End                                                                                    *
            *    Create offspring                                                                            *
            *    End loop                                                                                    *
            *                                                                                                *
            **************************************************************************************************/

            for (var i = 0; i < count; i++)
            {
                var parents = new WeightedItem <ConcreteSpecimen> [2];
                for (var j = 0; j < numberOfParents; j++)
                {
                    while (parents[j] == null)
                    {
                        var number         = random.NextDouble() * sumFitness;
                        var currentFitness = 0.0d;

                        foreach (var item in originalPopulation)
                        {
                            currentFitness += item.Weight;

                            if (number > currentFitness)
                            {
                                parents[j] = item;
                            }
                        }
                    }
                }

                double x;

                switch (random.Next(4))
                {
                case 0:
                case 1:
                case 2:
                    x = (parents[0].Weight * parents[0].Item.X + parents[1].Weight * parents[1].Item.X) / (parents[0].Weight + parents[1].Weight);
                    break;

                default:
                    // Default case: let's just randomly select which gene is coming from which parent...
                    x = parents[random.Next(0, 2)].Item.X;
                    break;
                }

                var offSpring = new ConcreteSpecimen(x);

                population.Add(new WeightedItem <ConcreteSpecimen>(offSpring, 0));
            }
        }