Free cookie consent management tool by TermsFeed Policy Generator

source: branches/IntegerVectorEncoding/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/Crossovers/UniformAllPositionsArithmeticCrossover.cs @ 7681

Last change on this file since 7681 was 7681, checked in by abeham, 12 years ago

#1775: added branch of plugin and new operators

File size: 6.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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;
23using HeuristicLab.Common;
24using HeuristicLab.Core;
25using HeuristicLab.Data;
26using HeuristicLab.Parameters;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28
29namespace HeuristicLab.Encodings.IntegerVectorEncoding {
30  /// <summary>
31  /// The uniform all positions arithmetic crossover constructs an offspring by calculating x = alpha * p1 + (1-alpha) * p2 for every position x in the vector.
32  /// The final value is rounded according to the bounds and the given step size.
33  /// </summary>
34  /// <remarks>
35  /// By setting alpha = 0.5 it is the same as the <see cref="AverageCrossover"/>, but works only on two parents.
36  /// </remarks>
37  [Item("UniformAllPositionsArithmeticCrossover", "The uniform all positions arithmetic crossover constructs an offspring by calculating x = alpha * p1 + (1-alpha) * p2 for every position x in the vector. Note that for alpha = 0.5 it is the same as the AverageCrossover (except that the AverageCrossover is defined for more than 2 parents).")]
38  [StorableClass]
39  public class UniformAllPositionsArithmeticCrossover : IntegerVectorCrossover, IBoundedIntegerVectorOperator {
40
41    /// <summary>
42    /// The bounds parameter must contain at least one row and at least two columns. The first two columns specify min and max values, the last column specifies the step size, but is optional (1 is assumed if omitted).
43    /// </summary>
44    public IValueLookupParameter<IntMatrix> BoundsParameter {
45      get { return (IValueLookupParameter<IntMatrix>)Parameters["Bounds"]; }
46    }
47
48    /// <summary>
49    /// 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).
50    /// </summary>
51    public ValueLookupParameter<DoubleValue> AlphaParameter {
52      get { return (ValueLookupParameter<DoubleValue>)Parameters["Alpha"]; }
53    }
54
55    [StorableConstructor]
56    protected UniformAllPositionsArithmeticCrossover(bool deserializing) : base(deserializing) { }
57    protected UniformAllPositionsArithmeticCrossover(UniformAllPositionsArithmeticCrossover original, Cloner cloner) : base(original, cloner) { }
58    /// <summary>
59    /// Initializes a new instance with one parameter (<c>Alpha</c>).
60    /// </summary>
61    public UniformAllPositionsArithmeticCrossover()
62      : base() {
63      Parameters.Add(new ValueLookupParameter<IntMatrix>("Bounds", "The bounds matrix can contain one row for each dimension with three columns specifying minimum (inclusive), maximum (exclusive), and step size. If less rows are given the matrix is cycled."));
64      Parameters.Add(new ValueLookupParameter<DoubleValue>("Alpha", "The alpha value in the range [0;1]", new DoubleValue(0.33)));
65    }
66
67    public override IDeepCloneable Clone(Cloner cloner) {
68      return new UniformAllPositionsArithmeticCrossover(this, cloner);
69    }
70
71    /// <summary>
72    /// Performs the arithmetic crossover on all positions by calculating x = alpha * p1 + (1 - alpha) * p2.
73    /// </summary>
74    /// <exception cref="ArgumentException">Thrown when the parent vectors are of different length or alpha is outside the range [0;1].</exception>
75    /// <param name="random">The random number generator.</param>
76    /// <param name="parent1">The first parent vector.</param>
77    /// <param name="parent2">The second parent vector.</param>
78    /// <param name="alpha">The alpha parameter (<see cref="AlphaParameter"/>).</param>
79    /// <returns>The vector resulting from the crossover.</returns>
80    public static IntegerVector Apply(IRandom random, IntegerVector parent1, IntegerVector parent2, IntMatrix bounds, DoubleValue alpha) {
81      int length = parent1.Length;
82      if (length != parent2.Length) throw new ArgumentException("UniformAllPositionsArithmeticCrossover: The parent vectors are of different length.", "parent1");
83      if (alpha.Value < 0 || alpha.Value > 1) throw new ArgumentException("UniformAllPositionsArithmeticCrossover: Parameter alpha must be in the range [0;1]", "alpha");
84      var result = new IntegerVector(length);
85      for (int i = 0; i < length; i++) {
86        int min = bounds[i % bounds.Rows, 0], max = bounds[i % bounds.Rows, 1], step = 1;
87        if (bounds.Columns > 2) step = bounds[i % bounds.Rows, 2];
88        double value = alpha.Value * parent1[i] + (1 - alpha.Value) * parent2[i];
89        result[i] = (int)Math.Round((value - min) / step) * step + min;
90      }
91      return result;
92    }
93
94    /// <summary>
95    /// Checks that there are exactly 2 parents, that the alpha parameter is not null and fowards the call to the static Apply method.
96    /// </summary>
97    /// <exception cref="ArgumentException">Thrown when there are not exactly two parents.</exception>
98    /// <exception cref="InvalidOperationException">Thrown when the alpha parmeter could not be found.</exception>
99    /// <param name="random">The random number generator.</param>
100    /// <param name="parents">The collection of parents (must be of size 2).</param>
101    /// <returns>The vector resulting from the crossover.</returns>
102    protected override IntegerVector Cross(IRandom random, ItemArray<IntegerVector> parents) {
103      if (parents.Length != 2) throw new ArgumentException("UniformAllPositionsArithmeticCrossover: There must be exactly two parents.", "parents");
104      if (AlphaParameter.ActualValue == null) throw new InvalidOperationException("UniformAllPositionsArithmeticCrossover: Parameter " + AlphaParameter.ActualName + " could not be found.");
105      return Apply(random, parents[0], parents[1], BoundsParameter.ActualValue, AlphaParameter.ActualValue);
106    }
107  }
108}
Note: See TracBrowser for help on using the repository browser.