source: branches/GeneralizedQAP/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/Manipulators/RoundedNormalAllPositionsManipulator.cs @ 15605

Last change on this file since 15605 was 15605, checked in by abeham, 17 months ago

#1614: merged trunk into branch

File size: 5.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2018 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;
28using HeuristicLab.Random;
29
30namespace HeuristicLab.Encodings.IntegerVectorEncoding {
31  /// <summary>
32  /// Manipulates each dimension in the integer vector with the mutation strength given
33  /// in the sigma parameter vector and rounds the result to the next feasible value.
34  /// </summary>
35  [Item("RoundedNormalAllPositionsManipulator", "This manipulation operator adds a value sigma_i * N_i(0,1) to the current value in each position i given the values for sigma_i in the parameter. The result is rounded to the next feasible value. If there are less elements in Sigma than positions, then Sigma is cycled.")]
36  [StorableClass]
37  public class RoundedNormalAllPositionsManipulator : BoundedIntegerVectorManipulator {
38
39    public IValueParameter<DoubleArray> SigmaParameter {
40      get { return (IValueParameter<DoubleArray>)Parameters["Sigma"]; }
41    }
42
43    [StorableConstructor]
44    protected RoundedNormalAllPositionsManipulator(bool deserializing) : base(deserializing) { }
45    protected RoundedNormalAllPositionsManipulator(RoundedNormalAllPositionsManipulator original, Cloner cloner) : base(original, cloner) { }
46    /// <summary>
47    /// Initializes a new instance of <see cref="RoundedNormalAllPositionsManipulator"/> with one
48    /// parameter (<c>Sigma</c>).
49    /// </summary>
50    public RoundedNormalAllPositionsManipulator()
51      : base() {
52      Parameters.Add(new ValueParameter<DoubleArray>("Sigma", "The vector containing the standard deviations used for manipulating each dimension. If it is only of length one the same sigma will be used for every dimension.", new DoubleArray(new double[] { 1 })));
53    }
54
55    public override IDeepCloneable Clone(Cloner cloner) {
56      return new RoundedNormalAllPositionsManipulator(this, cloner);
57    }
58
59    /// <summary>
60    /// Performs a normally distributed all position manipulation on the given
61    /// <paramref name="vector"/> and rounds the result to the next feasible value.
62    /// </summary>
63    /// <exception cref="InvalidOperationException">Thrown when the sigma vector is null or of length 0.</exception>
64    /// <param name="sigma">The sigma vector determining the strength of the mutation.</param>
65    /// <param name="random">A random number generator.</param>
66    /// <param name="vector">The integer vector to manipulate.</param>#
67    /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
68    /// <returns>The manipulated integer vector.</returns>
69    public static void Apply(IRandom random, IntegerVector vector, IntMatrix bounds, DoubleArray sigma) {
70      if (sigma == null || sigma.Length == 0) throw new ArgumentException("RoundedNormalAllPositionsManipulator: Vector containing the standard deviations is not defined.", "sigma");
71      if (bounds == null || bounds.Rows == 0 || bounds.Columns < 2) throw new ArgumentException("RoundedNormalAllPositionsManipulator: Invalid bounds specified.", "bounds");
72      var N = new NormalDistributedRandom(random, 0.0, 1.0);
73      for (int i = 0; i < vector.Length; i++) {
74        int min = bounds[i % bounds.Rows, 0], max = bounds[i % bounds.Rows, 1], step = 1;
75        if (bounds.Columns > 2) step = bounds[i % bounds.Rows, 2];
76
77        int value = (vector[i] + (int)Math.Round((N.NextDouble() * sigma[i % sigma.Length])) - min) / step;
78        max = FloorFeasible(min, max, step, max - 1);
79        vector[i] = RoundFeasible(min, max, step, value);
80      }
81    }
82
83    /// <summary>
84    /// Retrieves the bounds and forwards the call to the static Apply method.
85    /// </summary>
86    /// <param name="random">The random number generator.</param>
87    /// <param name="vector">The vector of integer values that is manipulated.</param>
88    /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
89    protected override void ManipulateBounded(IRandom random, IntegerVector vector, IntMatrix bounds) {
90      Apply(random, vector, bounds, SigmaParameter.Value);
91    }
92  }
93}
Note: See TracBrowser for help on using the repository browser.