1 | #region License Information
|
---|
2 | /* HeuristicLab
|
---|
3 | * Copyright (C) 2002-2019 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.Data;
|
---|
26 | using HeuristicLab.Parameters;
|
---|
27 | using HEAL.Attic;
|
---|
28 |
|
---|
29 | namespace HeuristicLab.Encodings.RealVectorEncoding {
|
---|
30 | /// <summary>
|
---|
31 | /// The uniform all positions arithmetic crossover (continuous recombination) constructs an offspring by calculating x = alpha * p1 + (1-alpha) * p2 for a position x in the vector with a given probability (otherwise p1 is taken at this position).
|
---|
32 | /// </summary>
|
---|
33 | /// <remarks>
|
---|
34 | /// It is implemented as described in Dumitrescu, D. et al. (2000), Evolutionary computation, CRC Press, Boca Raton, FL, p. 191.<br />
|
---|
35 | /// Note that the implementation is a bit more general than the operator described by Dumitrescu et al. There the alpha parameter was defined to be fixed at 0.5 and thus calculating the average at some positions.
|
---|
36 | /// </remarks>
|
---|
37 | [Item("UniformSomePositionsArithmeticCrossover", "The uniform some positions arithmetic crossover (continuous recombination) constructs an offspring by calculating x = alpha * p1 + (1-alpha) * p2 for a position x in the vector with a given probability (otherwise p1 is taken at this position). It is implemented as described in Dumitrescu, D. et al. (2000), Evolutionary computation, CRC Press, Boca Raton, FL, p. 191. Note that Dumitrescu et al. specify the alpha to be 0.5.")]
|
---|
38 | [StorableType("54FF8CE9-72E4-4C39-AF00-F38A548EDDD6")]
|
---|
39 | public class UniformSomePositionsArithmeticCrossover : RealVectorCrossover {
|
---|
40 | /// <summary>
|
---|
41 | /// The alpha parameter needs to be in the interval [0;1] and specifies how close the resulting offspring should be either to parent1 (alpha -> 0) or parent2 (alpha -> 1).
|
---|
42 | /// </summary>
|
---|
43 | public ValueLookupParameter<DoubleValue> AlphaParameter {
|
---|
44 | get { return (ValueLookupParameter<DoubleValue>)Parameters["Alpha"]; }
|
---|
45 | }
|
---|
46 | /// <summary>
|
---|
47 | /// The probability in the range [0;1] for each position in the vector to be crossed.
|
---|
48 | /// </summary>
|
---|
49 | public ValueLookupParameter<DoubleValue> ProbabilityParameter {
|
---|
50 | get { return (ValueLookupParameter<DoubleValue>)Parameters["Probability"]; }
|
---|
51 | }
|
---|
52 |
|
---|
53 | [StorableConstructor]
|
---|
54 | protected UniformSomePositionsArithmeticCrossover(StorableConstructorFlag _) : base(_) { }
|
---|
55 | protected UniformSomePositionsArithmeticCrossover(UniformSomePositionsArithmeticCrossover original, Cloner cloner) : base(original, cloner) { }
|
---|
56 | /// <summary>
|
---|
57 | /// Initializes a new instance with two parameters (<c>Alpha</c> and <c>Probability</c>).
|
---|
58 | /// </summary>
|
---|
59 | public UniformSomePositionsArithmeticCrossover()
|
---|
60 | : base() {
|
---|
61 | Parameters.Add(new ValueLookupParameter<DoubleValue>("Alpha", "The alpha value in the range [0;1] that defines whether the point should be close to parent1 (=1) or parent2 (=0)", new DoubleValue(0.5)));
|
---|
62 | Parameters.Add(new ValueLookupParameter<DoubleValue>("Probability", "The probability for crossing a position in the range [0;1]", new DoubleValue(0.5)));
|
---|
63 | }
|
---|
64 |
|
---|
65 | public override IDeepCloneable Clone(Cloner cloner) {
|
---|
66 | return new UniformSomePositionsArithmeticCrossover(this, cloner);
|
---|
67 | }
|
---|
68 |
|
---|
69 | /// <summary>
|
---|
70 | /// Performs the arithmetic crossover on some positions by taking either x = alpha * p1 + (1 - alpha) * p2 or x = p1 depending on the probability for a gene to be crossed.
|
---|
71 | /// </summary>
|
---|
72 | /// <param name="random">The random number generator.</param>
|
---|
73 | /// <param name="parent1">The first parent vector.</param>
|
---|
74 | /// <param name="parent2">The second parent vector.</param>
|
---|
75 | /// <param name="alpha">The alpha parameter (<see cref="AlphaParameter"/>).</param>
|
---|
76 | /// <param name="probability">The probability parameter (<see cref="ProbabilityParameter"/>).</param>
|
---|
77 | /// <returns>The vector resulting from the crossover.</returns>
|
---|
78 | public static RealVector Apply(IRandom random, RealVector parent1, RealVector parent2, DoubleValue alpha, DoubleValue probability) {
|
---|
79 | int length = parent1.Length;
|
---|
80 | if (length != parent2.Length) throw new ArgumentException("UniformSomePositionsArithmeticCrossover: The parent vectors are of different length.", "parent1");
|
---|
81 | if (alpha.Value < 0 || alpha.Value > 1) throw new ArgumentException("UniformSomePositionsArithmeticCrossover: Parameter alpha must be in the range [0;1]", "alpha");
|
---|
82 | if (probability.Value < 0 || probability.Value > 1) throw new ArgumentException("UniformSomePositionsArithmeticCrossover: Parameter probability must be in the range [0;1]", "probability");
|
---|
83 |
|
---|
84 | RealVector result = new RealVector(length);
|
---|
85 | for (int i = 0; i < length; i++) {
|
---|
86 | if (random.NextDouble() < probability.Value)
|
---|
87 | result[i] = alpha.Value * parent1[i] + (1 - alpha.Value) * parent2[i];
|
---|
88 | else result[i] = parent1[i];
|
---|
89 | }
|
---|
90 | return result;
|
---|
91 | }
|
---|
92 |
|
---|
93 | /// <summary>
|
---|
94 | /// Checks that there are exactly 2 parents, that the alpha and the probability parameter are not null and fowards the call to <see cref="Apply(IRandom, RealVector, DoubleArrrayData, DoubleValue)"/>.
|
---|
95 | /// </summary>
|
---|
96 | /// <exception cref="ArgumentException">Thrown when there are not exactly two parents.</exception>
|
---|
97 | /// <exception cref="InvalidOperationException">Thrown when either the alpha parmeter or the probability parameter could not be found.</exception>
|
---|
98 | /// <param name="random">The random number generator.</param>
|
---|
99 | /// <param name="parents">The collection of parents (must be of size 2).</param>
|
---|
100 | /// <returns>The vector resulting from the crossover.</returns>
|
---|
101 | protected override RealVector Cross(IRandom random, ItemArray<RealVector> parents) {
|
---|
102 | if (parents.Length != 2) throw new ArgumentException("UniformSomePositionsArithmeticCrossover: There must be exactly two parents.", "parents");
|
---|
103 | if (AlphaParameter.ActualValue == null) throw new InvalidOperationException("UniformSomePositionsArithmeticCrossover: Parameter " + AlphaParameter.ActualName + " could not be found.");
|
---|
104 | if (ProbabilityParameter.ActualValue == null) throw new InvalidOperationException("UniformSomePositionsArithmeticCrossover: Parameter " + ProbabilityParameter.ActualName + " could not be found.");
|
---|
105 | return Apply(random, parents[0], parents[1], AlphaParameter.ActualValue, ProbabilityParameter.ActualValue);
|
---|
106 | }
|
---|
107 | }
|
---|
108 | }
|
---|