Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Random/3.3/UniformRandomAdder.cs @ 3030

Last change on this file since 3030 was 2524, checked in by swagner, 15 years ago

Removed plugin HeuristicLab.Constraints (#804)

File size: 5.9 KB
RevLine 
[2]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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 System.Collections.Generic;
24using System.Text;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27
28namespace HeuristicLab.Random {
[1153]29  /// <summary>
30  /// Uniformly distributed random number generator that adds the generated value to the existing one.
31  /// </summary>
[2]32  public class UniformRandomAdder : OperatorBase {
33
34    private static int MAX_NUMBER_OF_TRIES = 100;
35
[1153]36    /// <inheritdoc select="summary"/>
[2]37    public override string Description {
[763]38      get {
39        return @"Samples a uniformly distributed random variable 'U' with range = [min,max] and E(u) = (max-min)/2
[2]40and adds the result to the variable 'Value'. ShakingFactor influences the effective range of U.
41If r=(max-min) then the effective range of U is [E(u) - shakingFactor * r/2, E(u) + shakingFactor * r/2].
42
43If a constraint for the allowed range of 'Value' is defined and the result of the operation would be smaller then
[763]44the smallest allowed value then 'Value' is set to the lower bound and vice versa for the upper bound.";
45      }
[2]46    }
47
[1153]48    /// <summary>
49    /// Initializes a new instance of <see cref="UniformRandomAdder"/> with five variable infos
50    /// (<c>Value</c>, <c>ShakingFactor</c>, <c>Random</c>, <c>Min</c> and <c>Max</c>), having an interval
51    /// of -1.0 to 1.0.
52    /// </summary>
[2]53    public UniformRandomAdder() {
54      AddVariableInfo(new VariableInfo("Value", "The value to manipulate (type is one of: IntData, ConstrainedIntData, DoubleData, ConstrainedDoubleData)", typeof(IObjectData), VariableKind.In));
[469]55      AddVariableInfo(new VariableInfo("ShakingFactor", "Determines the force of the shaking factor", typeof(DoubleData), VariableKind.In));
[2]56      AddVariableInfo(new VariableInfo("Random", "The random generator to use", typeof(MersenneTwister), VariableKind.In));
[469]57      AddVariableInfo(new VariableInfo("Min", "Lower bound of the uniform distribution (inclusive)", typeof(DoubleData), VariableKind.None));
[2]58      GetVariableInfo("Min").Local = true;
59      AddVariable(new Variable("Min", new DoubleData(-1.0)));
60
[469]61      AddVariableInfo(new VariableInfo("Max", "Upper bound of the uniform distribution (exclusive)", typeof(DoubleData), VariableKind.None));
[2]62      GetVariableInfo("Max").Local = true;
63      AddVariable(new Variable("Max", new DoubleData(1.0)));
64    }
65
[1153]66    /// <summary>
67    /// Generates a new uniformly distributed random number and adds it to the value in the given
68    /// <paramref name="scope"/>.
69    /// </summary>
70    /// <param name="scope">The current scope where to add the generated random number.</param>
[1157]71    /// <returns><c>null</c>.</returns>
[2]72    public override IOperation Apply(IScope scope) {
73      IObjectData value = GetVariableValue<IObjectData>("Value", scope, false);
74      MersenneTwister mt = GetVariableValue<MersenneTwister>("Random", scope, true);
75      double factor = GetVariableValue<DoubleData>("ShakingFactor", scope, true).Data;
[719]76      double min = GetVariableValue<DoubleData>("Min", scope, true).Data;
77      double max = GetVariableValue<DoubleData>("Max", scope, true).Data;
[2]78
79      double ex = (max - min) / 2.0 + min;
80      double newRange = (max - min) * factor;
81      min = ex - newRange / 2;
82      max = ex + newRange / 2;
83
[763]84      AddUniform(value, mt, min, max);
[2]85      return null;
86    }
87
[763]88    private void AddUniform(IObjectData value, MersenneTwister mt, double min, double max) {
89      // dispatch manually on dynamic type
90      if (value is IntData)
91        AddUniform((IntData)value, mt, min, max);
92      else if (value is DoubleData)
93        AddUniform((DoubleData)value, mt, min, max);
94      else throw new InvalidOperationException("Can't handle type " + value.GetType().Name);
95    }
[2]96
[1153]97    /// <summary>
98    /// Generates a new double random variable and adds it to the value of
99    /// the given <paramref name="data"/>.
100    /// </summary>
101    /// <param name="data">The double object where to add the random value.</param>
102    /// <param name="mt">The random number generator.</param>
103    /// <param name="min">The left border of the interval in which the next random number has to lie.</param>
104    /// <param name="max">The right border (exclusive) of the interval in which the next random number
105    /// has to lie.</param>
[763]106    public void AddUniform(DoubleData data, MersenneTwister mt, double min, double max) {
107      data.Data = data.Data + mt.NextDouble() * (max - min) + min;
108    }
[2]109
[1153]110    /// <summary>
111    /// Generates a new int random variable and adds it to the value of the given
112    /// <paramref name="data"/>.
113    /// </summary>
114    /// <param name="data">The int object where to add the random value.</param>
115    /// <param name="mt">The random number generator.</param>
116    /// <param name="min">The left border of the interval in which the next random number has to lie.</param>
117    /// <param name="max">The right border (exclusive) of the interval in which the next random number
118    /// has to lie.</param>
[763]119    public void AddUniform(IntData data, MersenneTwister mt, double min, double max) {
120      data.Data = (int)Math.Floor(data.Data + mt.NextDouble() * (max - min) + min);
121    }
[2]122  }
123}
Note: See TracBrowser for help on using the repository browser.