/// <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); } }
/// <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; }
public override void AddChromosome(IChromosome chromosome) { Action action = () => { chromosome.Evaluate(FitnessFunction); }; TasksPool.QueueUserWorkItem(action); AddChromosomeNoEvaluation(chromosome); }
/// <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(); }
/// <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); } } }
public double Evaluate(IChromosome chromosome) { var fitness = chromosome.Evaluate(); var distance = Distance(chromosome); return(fitness / distance); }
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(); } }
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(); } }
/// <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); }
/// <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); }
/// <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); } } }
/// <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); }
/// <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); }
public double Evaluate(IChromosome chromosome) => chromosome.Evaluate();