1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022019 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 HeuristicLab.Persistence.Default.CompositeSerializers.Storable;


28 


29  namespace HeuristicLab.Encodings.IntegerVectorEncoding {


30  /// <summary>


31  /// Uniformly distributed change of a single position of an integer vector.


32  /// </summary>


33  /// <remarks>


34  /// It is implemented as described in Michalewicz, Z. 1999. Genetic Algorithms + Data Structures = Evolution Programs. Third, Revised and Extended Edition, SpringVerlag Berlin Heidelberg.


35  /// </remarks>


36  [Item("UniformOnePositionManipulator", " Uniformly distributed change of a single position of an integer vector. It is implemented as described in Michalewicz, Z. 1999. Genetic Algorithms + Data Structures = Evolution Programs. Third, Revised and Extended Edition, SpringVerlag Berlin Heidelberg.")]


37  [StorableClass]


38  public class UniformOnePositionManipulator : BoundedIntegerVectorManipulator {


39 


40  [StorableConstructor]


41  protected UniformOnePositionManipulator(bool deserializing) : base(deserializing) { }


42  protected UniformOnePositionManipulator(UniformOnePositionManipulator original, Cloner cloner) : base(original, cloner) { }


43  /// <summary>


44  /// Initializes a new instance of <see cref="UniformOnePositionManipulator"/> with two parameters


45  /// (<c>Minimum</c> and <c>Maximum</c>).


46  /// </summary>


47  public UniformOnePositionManipulator() : base() { }


48 


49  public override IDeepCloneable Clone(Cloner cloner) {


50  return new UniformOnePositionManipulator(this, cloner);


51  }


52 


53  // BackwardsCompatibility3.3


54  #region Backwards compatible code, remove with 3.4


55  [StorableHook(HookType.AfterDeserialization)]


56  private void AfterDeserialization() {


57  if (!Parameters.ContainsKey("Bounds")) {


58  var min = ((IValueLookupParameter<IntValue>)Parameters["Minimum"]).Value as IntValue;


59  var max = ((IValueLookupParameter<IntValue>)Parameters["Maximum"]).Value as IntValue;


60  Parameters.Remove("Minimum");


61  Parameters.Remove("Maximum");


62  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."));


63  if (min != null && max != null) {


64  BoundsParameter.Value = new IntMatrix(new int[,] { { min.Value, max.Value, 1 } });


65  }


66  }


67  }


68  #endregion


69 


70  /// <summary>


71  /// Changes randomly a single position in the given integer <paramref name="vector"/>.


72  /// </summary>


73  /// <param name="random">A random number generator.</param>


74  /// <param name="vector">The integer vector to manipulate.</param>


75  /// <param name="min">The minimum value of the sampling range for


76  /// the vector element to change (inclusive).</param>


77  /// <param name="max">The maximum value of the sampling range for


78  /// the vector element to change (exclusive).</param>


79  /// <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>


80  public static void Apply(IRandom random, IntegerVector vector, IntMatrix bounds) {


81  Manipulate(random, vector, bounds, random.Next(vector.Length));


82  }


83 


84  public static void Manipulate(IRandom random, IntegerVector vector, IntMatrix bounds, int index) {


85  if (bounds == null  bounds.Rows == 0  bounds.Columns < 2) throw new ArgumentException("UniformOnePositionManipulator: Invalid bounds specified", "bounds");


86  int min = bounds[index % bounds.Rows, 0], max = bounds[index % bounds.Rows, 1], step = 1;


87  if (min == max) {


88  vector[index] = min;


89  } else {


90  if (bounds.Columns > 2) step = bounds[index % bounds.Rows, 2];


91  // max has to be rounded to the lower feasible value


92  // e.g. min...max / step = 0...100 / 5, max is exclusive so it would be 0..99


93  // but 99 is not a feasible value, so max needs to be adjusted => min = 0, max = 95


94  max = FloorFeasible(min, max, step, max  1);


95  vector[index] = RoundFeasible(min, max, step, random.Next(min, max));


96  }


97  }


98 


99  /// <summary>


100  /// Changes randomly a single position in the given integer <paramref name="vector"/>.


101  /// </summary>


102  /// <remarks>Calls <see cref="Apply"/>.</remarks>


103  /// <param name="random">A random number generator.</param>


104  /// <param name="vector">The integer vector to manipulate.</param>


105  /// <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>


106  protected override void ManipulateBounded(IRandom random, IntegerVector vector, IntMatrix bounds) {


107  if (BoundsParameter.ActualValue == null) throw new InvalidOperationException("UniformOnePositionManipulator: Parameter " + BoundsParameter.ActualName + " could not be found.");


108  Apply(random, vector, bounds);


109  }


110  }


111  }

