/// <summary> /// Performs a crossover of 2 parents /// The first child will contain all the best rows of the 2 parents /// The second child will contain all the best columns of the 2 parents /// </summary> /// <param name="parent1">The first parent1.</param> /// <param name="parent2">The second parent2.</param> /// <param name="child1">the first offspring of the 2 parents</param> /// <param name="child2">the 2nd offspring of the 2 parents</param> protected override void DoCrossOver(IChromosome parent1, IChromosome parent2, out IChromosome child1, out IChromosome child2) { // child 1 receives the best rows of parent 1 & parent 2 child1 = parent1.Clone(); for (var row = 0; row < 9; ++row) { var gene1 = (SudokuGene)parent1.Genes[row]; var gene2 = (SudokuGene)parent2.Genes[row]; if (RowScore(gene2) > RowScore(gene1)) { child1.Genes[row] = gene2.Clone(); } } // child 2 receives the best colums of parent 1 & parent 2 child2 = parent1.Clone(); for (var col = 0; col < 9; ++col) { if (ColumnScore(parent2, col) > ColumnScore(parent1, col)) { for (var row = 0; row < 9; row++) { var gene2 = (SudokuGene)parent2.Genes[row]; var geneChild = (SudokuGene)child2.Genes[row]; geneChild.Columns[col] = gene2.Columns[col]; } } } }
/// <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> /// Performs crossover using point selection. /// </summary> /// <param name="chromosome1">First parent.</param> /// <param name="chromosome2">Second parent.</param> /// <returns></returns> public IChromosome Crossover(IChromosome chromosome1, IChromosome chromosome2) { this.InitPoints(chromosome1.Sequence.Length, this.IsDynamic); IChromosome parent = chromosome1; IChromosome clone = parent.Clone(); int split = 0; for (int i = 0; i < chromosome1.Sequence.Length; i++) { if (i == this.Points[split]) { // striated genes double p = Sampling.GetUniform(); if (p <= this.Probability) { parent = (parent == chromosome1 ? chromosome2 : chromosome1); } if (split < this.Points.Length - 1) { split++; } } // do crossover clone.Sequence[i] = parent.Sequence[i]; } return(clone); }
/// <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> /// 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; }
/// <summary> /// Mutates the chromosome using random replacement. /// </summary> /// <param name="chromosome">Chromosome to mutate.</param> /// <returns>IChromosome.</returns> public override IChromosome Mutate(IChromosome chromosome) { var clone = chromosome.Clone(); clone.Sequence[this.N] = Sampling.GetUniform(this.Range.Min, this.Range.Max); return(clone); }
/// <summary> /// Mutates the chromosome using random flips. /// </summary> /// <param name="chromosome">Chromosome to mutate.</param> /// <returns>IChromosome.</returns> public override IChromosome Mutate(IChromosome chromosome) { var clone = chromosome.Clone(); double val = clone.Sequence[this.N]; clone.Sequence[this.N] = (val > 0 ? val - 1 : val + 1); return(clone); }
/// <summary> /// Konstruktor. /// </summary> /// <param name="prototype">Osobnik-wzorzec, który będzie kopiowany na potrzeby utworzenia populacji.</param> /// <param name="initialSize">Początkowy rozmiar populacji.</param> public DefaultPopulation(IChromosome prototype, UInt32 initialSize) { Generation = 0; Specimens = new IChromosome[initialSize]; for (Int32 i = 0; i < initialSize; ++i) { IChromosome chromosome = prototype.Clone(); chromosome.Randomize(); Specimens[i] = chromosome; } }
/// <summary> /// Mutates the chromosome using the current chain. /// </summary> /// <param name="chromosome">Chromosome to mutate.</param> /// <returns>IChromosome.</returns> public IChromosome Mutate(IChromosome chromosome) { var clone = chromosome.Clone(); foreach (var mutator in this.Mutations) { clone = mutator.Mutate(clone); } return(clone); }
/// <summary> /// Mutates the chromosome using Guassian mutation. /// </summary> /// <param name="chromosome">Chromosome to mutate.</param> /// <returns>IChromosome.</returns> public override IChromosome Mutate(IChromosome chromosome) { var clone = chromosome.Clone(); double val = Sampling.GetNormal(Mu, Sigma); if (Compound) { val += clone.Sequence[N]; } clone.Sequence[N] = Range?.Clip(val) ?? val; return(clone); }
/// <summary> /// Mutates the chromosome using Guassian mutation. /// </summary> /// <param name="chromosome">Chromosome to mutate.</param> /// <returns>IChromosome.</returns> public override IChromosome Mutate(IChromosome chromosome) { var clone = chromosome.Clone(); double val = Sampling.GetNormal(this.Mu, this.Sigma); if (this.Compound) { val += clone.Sequence[this.N]; } clone.Sequence[this.N] = (this.Range != null ? this.Range.Clip(val) : val); return(clone); }
/// <summary> /// Performs a simple crossover of 2 parents by selecting random genes from both parent. /// </summary> /// <param name="parent1">The parent1.</param> /// <param name="parent2">The parent2.</param> /// <param name="child1">the first offspring of the 2 parents</param> /// <param name="child2">the 2nd offspring of the 2 parents</param> protected virtual void DoCrossOver(IChromosome parent1, IChromosome parent2, out IChromosome child1, out IChromosome child2) { child1 = parent1.Clone(); child2 = parent2.Clone(); var x = _rnd.Next() % parent1.Genes.Count; for (var i = 0; i < x; ++i) { child1.Genes[i] = parent2.Genes[i].Clone(); } x = _rnd.Next() % parent2.Genes.Count; for (var i = 0; i < x; ++i) { child2.Genes[i] = parent1.Genes[i].Clone(); } }
/// <summary> /// Evolves using a standard genetic algorithm. /// </summary> /// <param name="chromosomes">Chromosomes to undergo evolution.</param> /// <param name="fitnessMetric">Fitness metric to use for evaluation.</param> /// <param name="fitnessMode">Fitness mode for evaluating performance.</param> public virtual IEnumerable <IChromosome> Evolve(IEnumerable <IChromosome> chromosomes, IFitnessMetric fitnessMetric, FitnessMode fitnessMode) { int count = chromosomes.Count(); var candidates = new List <IChromosome>(); int elites = (int)System.Math.Ceiling(chromosomes.Count() * this.ElitistRate); var topCandidates = (chromosomes.OrderByDescending(o => o.Weight).Take(elites)); foreach (var pair in this.Pairing.Pair(chromosomes)) { (IChromosome c1, IChromosome c2) = pair; IChromosome candidate = null; double rand = Sampling.GetUniform(); if (rand < this.CrossoverRate) { candidate = this.Crossover.Crossover(c1, c2); } double selector = Sampling.GetUniform(); candidate = candidate ?? (selector <= 0.5 ? c1 : c2); if (rand < this.MutationRate) { candidate = this.Mutation.Mutate(candidate.Clone()); } candidates.Add(candidate); } foreach (var elite in topCandidates) { candidates.Add(elite); } var result = this.Selection.Select(candidates, fitnessMode).Take(count); return(result); }
/// <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); } }
private Chromosome setBestSolution(IChromosome chromosome) { var c = chromosome.Clone(true) as Chromosome; return(c); }