[2918] | 1 | #region License Information
|
---|
| 2 | /* HeuristicLab
|
---|
[17180] | 3 | * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
|
---|
[2918] | 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;
|
---|
[4722] | 23 | using HeuristicLab.Common;
|
---|
[2918] | 24 | using HeuristicLab.Core;
|
---|
| 25 | using HeuristicLab.Data;
|
---|
| 26 | using HeuristicLab.Parameters;
|
---|
[16565] | 27 | using HEAL.Attic;
|
---|
[2918] | 28 |
|
---|
[3053] | 29 | namespace 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.")]
|
---|
[16565] | 38 | [StorableType("0A0686ED-BA7E-41A6-824E-134C4BF36408")]
|
---|
[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]
|
---|
[16565] | 48 | protected SimulatedBinaryCrossover(StorableConstructorFlag _) : base(_) { }
|
---|
[4722] | 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 | }
|
---|