Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Random/NormalRandomizer.cs @ 834

Last change on this file since 834 was 763, checked in by gkronber, 16 years ago

removed visitor interfaces and methods in HeuristicLab.Data and fixed classes in HeuristicLab.Random to work without visitor methods. #343 (Rethink about usefulness of visitors for ObjectData and Constraints)

File size: 5.0 KB
Line 
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;
27using HeuristicLab.Constraints;
28
29namespace HeuristicLab.Random {
30  public class NormalRandomizer : OperatorBase {
31    private static int MAX_NUMBER_OF_TRIES = 100;
32
33    public override string Description {
34      get { return "Initializes the value of variable 'Value' to a random value normally distributed with 'Mu' and 'Sigma'."; }
35    }
36
37    public double Mu {
38      get { return ((DoubleData)GetVariable("Mu").Value).Data; }
39      set { ((DoubleData)GetVariable("Mu").Value).Data = value; }
40    }
41    public double Sigma {
42      get { return ((DoubleData)GetVariable("Sigma").Value).Data; }
43      set { ((DoubleData)GetVariable("Sigma").Value).Data = value; }
44    }
45
46    public NormalRandomizer() {
47      AddVariableInfo(new VariableInfo("Mu", "Parameter mu of the normal distribution", typeof(DoubleData), VariableKind.None));
48      GetVariableInfo("Mu").Local = true;
49      AddVariable(new Variable("Mu", new DoubleData(0.0)));
50
51      AddVariableInfo(new VariableInfo("Sigma", "Parameter sigma of the normal distribution", typeof(DoubleData), VariableKind.None));
52      GetVariableInfo("Sigma").Local = true;
53      AddVariable(new Variable("Sigma", new DoubleData(1.0)));
54
55      AddVariableInfo(new VariableInfo("Value", "The value to manipulate (actual type is one of: IntData, DoubleData, ConstrainedIntData, ConstrainedDoubleData)", typeof(IObjectData), VariableKind.In));
56      AddVariableInfo(new VariableInfo("Random", "The random generator to use", typeof(MersenneTwister), VariableKind.In));
57    }
58
59    public override IOperation Apply(IScope scope) {
60      IObjectData value = GetVariableValue<IObjectData>("Value", scope, false);
61      MersenneTwister mt = GetVariableValue<MersenneTwister>("Random", scope, true);
62      double mu = GetVariableValue<DoubleData>("Mu", scope, true).Data;
63      double sigma = GetVariableValue<DoubleData>("Sigma", scope, true).Data;
64
65      NormalDistributedRandom n = new NormalDistributedRandom(mt, mu, sigma);
66      RandomizeNormal(value, n);
67      return null;
68    }
69
70    private void RandomizeNormal(IObjectData value, NormalDistributedRandom n) {
71      // dispatch manually based on dynamic type
72      if (value is IntData)
73        RandomizeNormal((IntData)value, n);
74      else if (value is ConstrainedIntData)
75        RandomizeNormal((ConstrainedIntData)value, n);
76      else if (value is DoubleData)
77        RandomizeNormal((DoubleData)value, n);
78      else if (value is ConstrainedDoubleData)
79        RandomizeNormal((ConstrainedDoubleData)value, n);
80      else throw new InvalidOperationException("Can't handle type " + value.GetType().Name);
81    }
82
83    public void RandomizeNormal(ConstrainedDoubleData data, NormalDistributedRandom normal) {
84      for (int tries = MAX_NUMBER_OF_TRIES; tries >= 0; tries--) {
85        double r = normal.NextDouble();
86        if (IsIntegerConstrained(data)) {
87          r = Math.Round(r);
88        }
89        if (data.TrySetData(r)) {
90          return;
91        }
92      }
93      throw new InvalidOperationException("Couldn't find a valid value in 100 tries with mu=" + normal.Mu + " sigma=" + normal.Sigma);
94    }
95
96    public void RandomizeNormal(ConstrainedIntData data, NormalDistributedRandom normal) {
97      for (int tries = MAX_NUMBER_OF_TRIES; tries >= 0; tries--) {
98        double r = normal.NextDouble();
99        if (data.TrySetData((int)Math.Round(r))) // since r is a continuous normally distributed random variable rounding should be OK
100          return;
101      }
102      throw new InvalidOperationException("Couldn't find a valid value");
103    }
104
105    public void RandomizeNormal(DoubleData data, NormalDistributedRandom normal) {
106      data.Data = normal.NextDouble();
107    }
108
109    public void RandomizeNormal(IntData data, NormalDistributedRandom normal) {
110      data.Data = (int)Math.Round(normal.NextDouble());
111    }
112
113
114    private bool IsIntegerConstrained(ConstrainedDoubleData data) {
115      foreach (IConstraint constraint in data.Constraints) {
116        if (constraint is IsIntegerConstraint) {
117          return true;
118        }
119      }
120      return false;
121    }
122  }
123}
Note: See TracBrowser for help on using the repository browser.