Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/Crossovers/SimulatedBinaryCrossover.cs @ 5060

Last change on this file since 5060 was 4722, checked in by swagner, 14 years ago

Merged cloning refactoring branch back into trunk (#922)

File size: 6.7 KB
RevLine 
[2918]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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
22using System;
[4722]23using HeuristicLab.Common;
[2918]24using HeuristicLab.Core;
25using HeuristicLab.Data;
26using HeuristicLab.Parameters;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28
[3053]29namespace HeuristicLab.Encodings.RealVectorEncoding {
[2918]30  /// <summary>
31  /// Performs the simulated binary crossover (SBX) on a vector of real values such that each position is either crossed contracted or expanded with a certain probability.
32  /// The probability distribution is designed such that the children will lie closer to their parents as is the case with the single point binary crossover.
33  /// </summary>
34  /// <remarks>
35  /// It is implemented as described in Deb, K. and Agrawal, R. B. 1995. Simulated binary crossover for continuous search space. Complex Systems, 9, pp. 115-148.
36  /// </remarks>
37  [Item("SimulatedBinaryCrossover", "The simulated binary crossover (SBX) is implemented as described in Deb, K. and Agrawal, R. B. 1995. Simulated binary crossover for continuous search space. Complex Systems, 9, pp. 115-148.")]
[3017]38  [StorableClass]
[2918]39  public class SimulatedBinaryCrossover : RealVectorCrossover {
40    /// <summary>
41    /// The parameter must be greater or equal than 0. Common values are in the range [0;5] and more often just [2;5].
42    /// </summary>
[3048]43    public ValueLookupParameter<DoubleValue> ContiguityParameter {
44      get { return (ValueLookupParameter<DoubleValue>)Parameters["Contiguity"]; }
[2918]45    }
46
[4722]47    [StorableConstructor]
48    protected SimulatedBinaryCrossover(bool deserializing) : base(deserializing) { }
49    protected SimulatedBinaryCrossover(SimulatedBinaryCrossover original, Cloner cloner) : base(original, cloner) { }
[2921]50    /// <summary>
51    /// Initializes a new instance of <see cref="SimulatedBinaryCrossover"/> with one
52    /// parameter (<c>Contiguity</c>).
53    /// </summary>
[2918]54    public SimulatedBinaryCrossover()
55      : base() {
[3048]56      Parameters.Add(new ValueLookupParameter<DoubleValue>("Contiguity", "Specifies whether the crossover should produce very different (small value) or very similar (large value) children. Valid values must be greater or equal to 0.", new DoubleValue(2)));
[2918]57    }
58
[4722]59    public override IDeepCloneable Clone(Cloner cloner) {
60      return new SimulatedBinaryCrossover(this, cloner);
61    }
62
[2918]63    /// <summary>
64    /// Performs the simulated binary crossover on a real vector. Each position is crossed with a probability of 50% and if crossed either a contracting crossover or an expanding crossover is performed, again with equal probability.
65    /// For more details refer to the paper by Deb and Agrawal.
66    /// </summary>
67    /// <exception cref="ArgumentException">Thrown when the parents' vectors are of unequal length or when <paramref name="contiguity"/> is smaller than 0.</exception>
[2927]68    /// <remarks>
69    /// The manipulated value is not restricted by the (possibly) specified lower and upper bounds. Use the <see cref="BoundsChecker"/> to correct the values after performing the crossover.
70    /// </remarks>
[2918]71    /// <param name="random">The random number generator to use.</param>
72    /// <param name="parent1">The first parent vector.</param>
73    /// <param name="parent2">The second parent vector.</param>
74    /// <param name="contiguity">The contiguity value that specifies how close a child should be to its parents (larger value means closer). The value must be greater or equal than 0. Typical values are in the range [2;5].</param>
75    /// <returns>The vector resulting from the crossover.</returns>
[3060]76    public static RealVector Apply(IRandom random, RealVector parent1, RealVector parent2, DoubleValue contiguity) {
[2928]77      if (parent1.Length != parent2.Length) throw new ArgumentException("SimulatedBinaryCrossover: Parents are of unequal length");
[2918]78      if (contiguity.Value < 0) throw new ArgumentException("SimulatedBinaryCrossover: Contiguity value is smaller than 0", "contiguity");
79      int length = parent1.Length;
[3060]80      RealVector result = new RealVector(length);
[2918]81      for (int i = 0; i < length; i++) {
[2927]82        if (length == 1 || random.NextDouble() < 0.5) { // cross this variable
[2918]83          double u = random.NextDouble();
84          double beta = 0;
85          if (u < 0.5) { // if u is smaller than 0.5 perform a contracting crossover
86            beta = Math.Pow(2 * u, 1.0 / (contiguity.Value + 1));
[2919]87          } else if (u > 0.5) { // otherwise perform an expanding crossover
[3172]88            beta = Math.Pow(0.5 / (1.0 - u), 1.0 / (contiguity.Value + 1));
[2919]89          } else if (u == 0.5)
90            beta = 1;
91
[2918]92          if (random.NextDouble() < 0.5)
93            result[i] = ((parent1[i] + parent2[i]) / 2.0) - beta * 0.5 * Math.Abs(parent1[i] - parent2[i]);
94          else
95            result[i] = ((parent1[i] + parent2[i]) / 2.0) + beta * 0.5 * Math.Abs(parent1[i] - parent2[i]);
[2927]96        } else result[i] = parent1[i];
[2918]97      }
98      return result;
99    }
100
101    /// <summary>
[3060]102    /// Checks number of parents, availability of the parameters and forwards the call to <see cref="Apply(IRandom, RealVector, RealVector, DoubleValue)"/>.
[2918]103    /// </summary>
[2936]104    /// <exception cref="ArgumentException">Thrown when there are not exactly 2 parents or when the contiguity parameter could not be found.</exception>
[2918]105    /// <param name="random">The random number generator.</param>
106    /// <param name="parents">The collection of parents (must be of size 2).</param>
107    /// <returns>The real vector resulting from the crossover.</returns>
[3060]108    protected override RealVector Cross(IRandom random, ItemArray<RealVector> parents) {
[2936]109      if (parents.Length != 2) throw new ArgumentException("SimulatedBinaryCrossover: The number of parents is not equal to 2");
[2918]110      if (ContiguityParameter.ActualValue == null) throw new InvalidOperationException("SimulatedBinaryCrossover: Parameter " + ContiguityParameter.ActualName + " could not be found.");
111      return Apply(random, parents[0], parents[1], ContiguityParameter.ActualValue);
112    }
113  }
114}
Note: See TracBrowser for help on using the repository browser.