Example #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Population"/> class.
        /// </summary>
        ///
        /// <param name="size">Initial size of population.</param>
        /// <param name="ancestor">Ancestor chromosome to use for population creatioin.</param>
        /// <param name="fitnessFunction">Fitness function to use for calculating
        /// chromosome's fitness values.</param>
        /// <param name="selectionMethod">Selection algorithm to use for selection
        /// chromosome's to new generation.</param>
        ///
        /// <remarks>Creates new population of specified size. The specified ancestor
        /// becomes first member of the population and is used to create other members
        /// with same parameters, which were used for ancestor's creation.</remarks>
        ///
        /// <exception cref="ArgumentException">Too small population's size was specified. The
        /// exception is thrown in the case if <paramref name="size"/> is smaller than 2.</exception>
        ///
        public Population(int size,
                          IChromosome ancestor,
                          IFitnessFunction fitnessFunction,
                          ISelectionMethod selectionMethod)
        {
            if (size < 2)
            {
                throw new ArgumentException("Too small population's size was specified.");
            }

            this.fitnessFunction = fitnessFunction;
            this.selectionMethod = selectionMethod;
            this.size            = size;

            // add ancestor to the population
            ancestor.Evaluate(fitnessFunction);
            population.Add(ancestor.Clone());
            // add more chromosomes to the population
            for (var i = 1; i < size; i++)
            {
                // create new chromosome
                var c = ancestor.CreateNew();
                // calculate it's fitness
                c.Evaluate(fitnessFunction);
                // add it to population
                population.Add(c);
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="Population"/> class.
        /// </summary>
        /// 
        /// <param name="size">Initial size of population.</param>
        /// <param name="ancestor">Ancestor chromosome to use for population creatioin.</param>
        /// <param name="fitnessFunction">Fitness function to use for calculating
        /// chromosome's fitness values.</param>
        /// <param name="selectionMethod">Selection algorithm to use for selection
        /// chromosome's to new generation.</param>
        /// 
        /// <remarks>Creates new population of specified size. The specified ancestor
        /// becomes first member of the population and is used to create other members
        /// with same parameters, which were used for ancestor's creation.</remarks>
        /// 
        /// <exception cref="ArgumentException">Too small population's size was specified. The
        /// exception is thrown in the case if <paramref name="size"/> is smaller than 2.</exception>
        ///
        public QueuePopulation(int size,
                           IChromosome ancestor,
                           IFitnessFunction fitnessFunction,
                           ISelectionMethod selectionMethod)
        {
            if (size < 2)
                throw new ArgumentException("Too small population's size was specified.");

            this.fitnessFunction = fitnessFunction;
            this.selectionMethod = selectionMethod;
            this.size = size;

            // add ancestor to the population
            ancestor.Evaluate(fitnessFunction);
            population.Add(ancestor.Clone());
            // add more chromosomes to the population
            for (int i = 1; i < size; i++)
            {
                // create new chromosome
                IChromosome c = ancestor.CreateNew();
                // calculate it's fitness
                c.Evaluate(fitnessFunction);
                // add it to population
                population.Add(c);
            }
        }
Example #3
0
        /// <summary>
        /// Resize population to the new specified size.
        /// </summary>
        ///
        /// <param name="newPopulationSize">New size of population.</param>
        /// <param name="membersSelector">Selection algorithm to use in the case
        /// if population should get smaller.</param>
        ///
        /// <remarks><para>The method does resizing of population. In the case if population
        /// should grow, it just adds missing number of random members. In the case if
        /// population should get smaller, the specified selection method is used to
        /// reduce the population.</para></remarks>
        ///
        /// <exception cref="ArgumentException">Too small population's size was specified. The
        /// exception is thrown in the case if <paramref name="newPopulationSize"/> is smaller than 2.</exception>
        ///
        public void Resize(int newPopulationSize, ISelectionMethod membersSelector)
        {
            if (newPopulationSize < 2)
            {
                throw new ArgumentException("Too small new population's size was specified.");
            }

            if (newPopulationSize > size)
            {
                // population is growing, so add new rundom members

                // Note: we use population.Count here instead of "size" because
                // population may be bigger already after crossover/mutation. So
                // we just keep those members instead of adding random member.
                int toAdd = newPopulationSize - population.Count;

                for (int i = 0; i < toAdd; i++)
                {
                    // create new chromosome
                    IChromosome c = population[0].CreateNew();
                    // calculate it's fitness
                    c.Evaluate(fitnessFunction);
                    // add it to population
                    population.Add(c);
                }
            }
            else
            {
                // do selection
                membersSelector.ApplySelection(population, newPopulationSize);
            }

            size = newPopulationSize;
        }
Example #4
0
        public override void AddChromosome(IChromosome chromosome)
        {
            Action action = () => { chromosome.Evaluate(FitnessFunction); };

            TasksPool.QueueUserWorkItem(action);
            AddChromosomeNoEvaluation(chromosome);
        }
Example #5
0
        /// <summary>
        /// Do selection.
        /// </summary>
        ///
        /// <remarks>The method applies selection operator to the current population. Using
        /// specified selection algorithm it selects members to the new generation from current
        /// generates and adds certain amount of random members, if is required
        /// (see <see cref="RandomSelectionPortion"/>).</remarks>
        ///
        public virtual void Selection()
        {
            // amount of random chromosomes in the new population
            int randomAmount = (int)(randomSelectionPortion * size);

            // do selection
            selectionMethod.ApplySelection(population, size - randomAmount);

            // add random chromosomes
            if (randomAmount > 0)
            {
                IChromosome ancestor = population[0];

                for (int i = 0; i < randomAmount; i++)
                {
                    // create new chromosome
                    IChromosome c = ancestor.CreateNew();
                    // calculate it's fitness
                    c.Evaluate(fitnessFunction);
                    // add it to population
                    population.Add(c);
                }
            }

            FindBestChromosome();
        }
Example #6
0
        /// <summary>
        /// Do crossover in the population.
        /// </summary>
        ///
        /// <remarks>The method walks through the population and performs crossover operator
        /// taking each two chromosomes in the order of their presence in the population.
        /// The total amount of paired chromosomes is determined by
        /// <see cref="CrossoverRate">crossover rate</see>.</remarks>
        ///
        public virtual void Crossover()
        {
            // crossover
            for (int i = 1; i < size; i += 2)
            {
                // generate next random number and check if we need to do crossover
                if (rand.NextDouble() <= crossoverRate)
                {
                    // clone both ancestors
                    IChromosome c1 = population[i - 1].Clone();
                    IChromosome c2 = population[i].Clone();

                    // do crossover
                    c1.Crossover(c2);

                    // calculate fitness of these two offsprings
                    c1.Evaluate(fitnessFunction);
                    c2.Evaluate(fitnessFunction);

                    // add two new offsprings to the population
                    population.Add(c1);
                    population.Add(c2);
                }
            }
        }
Example #7
0
        public double Evaluate(IChromosome chromosome)
        {
            var fitness  = chromosome.Evaluate();
            var distance = Distance(chromosome);

            return(fitness / distance);
        }
Example #8
0
 private void DoCrossover(int crossovers, AutoResetEvent are)
 {
     for (int i = 0; i < crossovers; i++)
     {
         int index  = _rand.Next(0, _population.Count);
         int index2 = _rand.Next(0, _population.Count);
         while (index2 == index)
         {
             index2 = _rand.Next(0, _population.Count);
         }
         IChromosome chromosome1 = _population[index].Clone();
         IChromosome chromosome2 = _population[index2];
         chromosome1.Crossover(chromosome2);
         //chromosome2.Crossover(chromosome1);
         chromosome1.Evaluate(FitnessFunction);
         //chromosome2.Evaluate(FitnessFunction);
         lock (_population)
         {
             if (!_population.Contains(chromosome1))
             {
                 _population.Add(chromosome1);
             }
         }
         //if (!_population.Contains(chromosome2))
         //_population.Add(chromosome2);
     }
     if (are != null)
     {
         are.Set();
     }
 }
Example #9
0
 private void DoMutate(int mutations, AutoResetEvent are)
 {
     if (mutations <= 1)
     {
         mutations = 1;
     }
     for (int i = 0; i < mutations; i++)
     {
         int         index      = _rand.Next(0, Math.Min(PopulationSize, _population.Count));
         IChromosome chromosome = _population[index].Clone();
         chromosome.Mutate();
         chromosome.Evaluate(FitnessFunction);
         lock (_population)
         {
             if (!_population.Contains(chromosome))
             {
                 _population.Add(chromosome);
             }
         }
     }
     if (are != null)
     {
         are.Set();
     }
 }
Example #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Optimizer"/> class.
        /// </summary>
        /// <param name="ancestor">The ancestor chromosome.</param>
        /// <param name="populationSize">Size of the population.</param>
        /// <param name="ff">The fitness function to use for chromosome fitness calculation.</param>
        /// <param name="selection">The selection to be used to select the best chromosomes.</param>
        public Optimizer(IChromosome ancestor, int populationSize, IFitnessFunction ff, Selection.SelectionBase selection)
        {
            if (ancestor == null)
            {
                throw new ArgumentNullException("ancestor");
            }
            if (ff == null)
            {
                throw new ArgumentNullException("ff");
            }
            if (selection == null)
            {
                throw new ArgumentNullException("selection");
            }

            _populationSize = populationSize;
            FitnessFunction = ff;
            Selection       = selection;
            _population     = new List <IChromosome>();
            ancestor.Evaluate(ff);
            _population.Add(ancestor);
            while (_population.Count < populationSize)
            {
                IChromosome newC = ancestor.Clone();
                newC.Generate();
                newC.Evaluate(ff);
                _population.Add(newC);
            }
            MutationRate  = 0.08f;
            CrossoverRate = 0f;
        }
        public void ChooseBestTest()
        {
            A.CallTo(() => chromosome1.Evaluate()).Returns(1);
            A.CallTo(() => chromosome2.Evaluate()).Returns(8);
            A.CallTo(() => chromosome3.Evaluate()).Returns(0.5);

            var population = new Population(new[] { chromosome1, chromosome2, chromosome3 }).Evaluate();
            var best       = population.ChooseBest();

            Assert.AreEqual(chromosome2, best);
        }
Example #12
0
        /// <summary>
        /// Regenerate population.
        /// </summary>
        ///
        /// <remarks>The method regenerates population filling it with random chromosomes.</remarks>
        ///
        public void Regenerate()
        {
            IChromosome ancestor = population[0];

            // clear population
            population.Clear();
            // add chromosomes to the population
            for (int i = 0; i < size; i++)
            {
                // create new chromosome
                IChromosome c = ancestor.CreateNew();
                // calculate it's fitness
                c.Evaluate(fitnessFunction);
                // add it to population
                population.Add(c);
            }
        }
        /// <summary>
        /// Do crossover in the population.
        /// </summary>
        ///
        /// <remarks>The method walks through the population and performs crossover operator
        /// taking each two chromosomes in the order of their presence in the population.
        /// The total amount of paired chromosomes is determined by
        /// <see cref="CrossoverRate">crossover rate</see>.</remarks>
        ///
        public virtual void Crossover( )
        {
            // new population, initially empty
            List <IChromosome> newPopulation = new List <IChromosome>();

            // crossover
            for (int i = 1; i < size; i += 2)
            {
                // generate next random number and check if we need to do crossover
                if (rand.NextDouble() <= crossoverRate)
                {
                    // faz o torneio para escolher os ancestrais
                    IChromosome c1 = tournamentSelection(population); //population[i - 1].Clone();
                    IChromosome c2 = tournamentSelection(population); //population[i].Clone();

                    // do crossover
                    c1.Crossover(c2);

                    // calculate fitness of these two offsprings
                    c1.Evaluate(fitnessFunction);
                    c2.Evaluate(fitnessFunction);

                    // add two new offsprings to the population
                    //population.Add( c1 );
                    //population.Add( c2 );

                    // add two new offsprings to the new population
                    newPopulation.Add(c1);
                    newPopulation.Add(c2);
                }
                else
                {
                    //     clone both ancestors
                    newPopulation.Add(population[i - 1].Clone());
                    newPopulation.Add(population[i].Clone());
                }
            }

            // empty current population
            population.Clear();

            // move elements from new to current population
            population.AddRange(newPopulation);
        }
Example #14
0
 /// <summary>
 /// Do mutation in the population.
 /// </summary>
 ///
 /// <remarks>The method walks through the population and performs mutation operator
 /// taking each chromosome one by one. The total amount of mutated chromosomes is
 /// determined by <see cref="MutationRate">mutation rate</see>.</remarks>
 ///
 public virtual void Mutate()
 {
     // mutate
     for (int i = 0; i < size; i++)
     {
         // generate next random number and check if we need to do mutation
         if (rand.NextDouble() <= mutationRate)
         {
             // clone the chromosome
             IChromosome c = population[i].Clone();
             // mutate it
             c.Mutate();
             // calculate fitness of the mutant
             c.Evaluate(fitnessFunction);
             // add mutant to the population
             population.Add(c);
         }
     }
 }
Example #15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Population"/> class.
        /// </summary>
        ///
        /// <param name="size">Initial size of population.</param>
        /// <param name="ancestor">Ancestor chromosome to use for population creatioin.</param>
        /// <param name="fitnessFunction">Fitness function to use for calculating
        /// chromosome's fitness values.</param>
        /// <param name="selectionMethod">Selection algorithm to use for selection
        /// chromosome's to new generation.</param>
        ///
        /// <remarks>Creates new population of specified size. The specified ancestor
        /// becomes first member of the population and is used to create other members
        /// with same parameters, which were used for ancestor's creation.</remarks>
        ///
        public Population(int size,
                          IChromosome ancestor,
                          IFitnessFunction fitnessFunction,
                          ISelectionMethod selectionMethod)
        {
            this.fitnessFunction = fitnessFunction;
            this.selectionMethod = selectionMethod;
            this.size            = size;

            // add ancestor to the population
            ancestor.Evaluate(fitnessFunction);
            population.Add(ancestor.Clone( ));
            // add more chromosomes to the population
            for (int i = 1; i < size; i++)
            {
                // create new chromosome
                IChromosome c = ancestor.CreateNew( );
                // calculate it's fitness
                c.Evaluate(fitnessFunction);
                // add it to population
                population.Add(c);
            }
        }
        /// <summary>
        /// Do mutation in the population.
        /// </summary>
        ///
        /// <remarks>The method walks through the population and performs mutation operator
        /// taking each chromosome one by one. The total amount of mutated chromosomes is
        /// determined by <see cref="MutationRate">mutation rate</see>.</remarks>
        ///
        public virtual void Mutate( )
        {
            // new population, initially empty
            List <IChromosome> newPopulation = new List <IChromosome>();

            // mutate
            for (int i = 0; i < size; i++)
            {
                // generate next random number and check if we need to do mutation
                if (rand.NextDouble( ) <= mutationRate)
                {
                    // clone the chromosome
                    IChromosome c = population[i].Clone( );
                    // mutate it
                    c.Mutate( );
                    // calculate fitness of the mutant
                    c.Evaluate(fitnessFunction);
                    // add mutant to the population
                    population.Add(c);

                    // add mutant to the new population
                    //newPopulation.Add(c);
                }
                //else
                //{
                //    // clone both ancestors
                //    newPopulation.Add(population[i].Clone());
                //}
            }

            //// empty current population
            //population.Clear();

            //// move elements from new to current population
            //population.AddRange(newPopulation);
        }
Example #17
0
 /// <summary>
 /// Add chromosome to the population.
 /// </summary>
 ///
 /// <param name="chromosome">Chromosome to add to the population.</param>
 ///
 /// <remarks><para>The method adds specified chromosome to the current population.
 /// Manual adding of chromosome maybe useful, when it is required to add some initialized
 /// chromosomes instead of random.</para>
 ///
 /// <para><note>Adding chromosome manually should be done very carefully, since it
 /// may break the population. The manually added chromosome must have the same type
 /// and initialization parameters as the ancestor passed to constructor.</note></para>
 /// </remarks>
 ///
 public void AddChromosome(IChromosome chromosome)
 {
     chromosome.Evaluate(fitnessFunction);
     population.Add(chromosome);
 }
Example #18
0
 /// <summary>
 /// Add chromosome to the population.
 /// </summary>
 /// 
 /// <param name="chromosome">Chromosome to add to the population.</param>
 /// 
 /// <remarks><para>The method adds specified chromosome to the current population.
 /// Manual adding of chromosome maybe useful, when it is required to add some initialized
 /// chromosomes instead of random.</para>
 /// 
 /// <para><note>Adding chromosome manually should be done very carefully, since it
 /// may break the population. The manually added chromosome must have the same type
 /// and initialization parameters as the ancestor passed to constructor.</note></para>
 /// </remarks>
 /// 
 public void AddChromosome(IChromosome chromosome)
 {
     chromosome.Evaluate(fitnessFunction);
     population.Add(chromosome);
 }
Example #19
0
 public double Evaluate(IChromosome chromosome) => chromosome.Evaluate();