1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022019 Heuristic and Evolutionary Algorithms Laboratory (HEAL)


4  *


5  * This file is part of HeuristicLab.


6  *


7  * HeuristicLab is free software: you can redistribute it and/or modify


8  * it under the terms of the GNU General Public License as published by


9  * the Free Software Foundation, either version 3 of the License, or


10  * (at your option) any later version.


11  *


12  * HeuristicLab is distributed in the hope that it will be useful,


13  * but WITHOUT ANY WARRANTY; without even the implied warranty of


14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the


15  * GNU General Public License for more details.


16  *


17  * You should have received a copy of the GNU General Public License


18  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.


19  */


20  #endregion


21 


22  using System;


23  using HeuristicLab.Common;


24  using HeuristicLab.Core;


25  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;


26 


27  namespace HeuristicLab.Encodings.RealVectorEncoding {


28  /// <summary>


29  /// The average crossover (intermediate recombination) calculates the average or centroid of a number of parent vectors.


30  /// </summary>


31  /// <remarks>


32  /// It is implemented as described by Beyer, H.G. and Schwefel, H.P. 2002. Evolution Strategies  A Comprehensive Introduction Natural Computing, 1, pp. 352.


33  /// </remarks>


34  [Item("AverageCrossover", "The average crossover (intermediate recombination) produces a new offspring by calculating in each position the average of a number of parents. It is implemented as described by Beyer, H.G. and Schwefel, H.P. 2002. Evolution Strategies  A Comprehensive Introduction Natural Computing, 1, pp. 352.")]


35  [StorableClass]


36  public class AverageCrossover : RealVectorCrossover {


37  [StorableConstructor]


38  protected AverageCrossover(bool deserializing) : base(deserializing) { }


39  protected AverageCrossover(AverageCrossover original, Cloner cloner) : base(original, cloner) { }


40  public AverageCrossover() : base() { }


41 


42  public override IDeepCloneable Clone(Cloner cloner) {


43  return new AverageCrossover(this, cloner);


44  }


45 


46  /// <summary>


47  /// Performs the average crossover (intermediate recombination) on a list of parents.


48  /// </summary>


49  /// <exception cref="ArgumentException">Thrown when there is just one parent or when the parent vectors are of different length.</exception>


50  /// <remarks>


51  /// There can be more than two parents.


52  /// </remarks>


53  /// <param name="random">The random number generator.</param>


54  /// <param name="parents">The list of parents.</param>


55  /// <returns>The child vector (average) of the parents.</returns>


56  public static RealVector Apply(IRandom random, ItemArray<RealVector> parents) {


57  int length = parents[0].Length, parentsCount = parents.Length;


58  if (parents.Length < 2) throw new ArgumentException("AverageCrossover: The number of parents is less than 2.", "parents");


59  RealVector result = new RealVector(length);


60  try {


61  double avg;


62  for (int i = 0; i < length; i++) {


63  avg = 0;


64  for (int j = 0; j < parentsCount; j++)


65  avg += parents[j][i];


66  result[i] = avg / (double)parentsCount;


67  }


68  }


69  catch (IndexOutOfRangeException) {


70  throw new ArgumentException("AverageCrossover: The parents' vectors are of different length.", "parents");


71  }


72 


73  return result;


74  }


75 


76  /// <summary>


77  /// Forwards the call to <see cref="Apply(IRandom, ItemArray<RealVector>)"/>.


78  /// </summary>


79  /// <param name="random">The random number generator.</param>


80  /// <param name="parents">The list of parents.</param>


81  /// <returns>The child vector (average) of the parents.</returns>


82  protected override RealVector Cross(IRandom random, ItemArray<RealVector> parents) {


83  return Apply(random, parents);


84  }


85  }


86  }

