source: branches/LearningClassifierSystems/HeuristicLab.Encodings.VariableVector/3.3/Variable/DoubleVariable.cs @ 9475

Last change on this file since 9475 was 9475, checked in by sforsten, 8 years ago

#1980: several small bug fixes

File size: 7.7 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 System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28
29namespace HeuristicLab.Encodings.VariableVector {
30  [StorableClass]
31  [Item(Name = "DoubleVariable", Description = "")]
32  public class DoubleVariable : Variable<double> {
33    public override int VirtualLength {
34      get { return 2; }
35    }
36
37    [Storable]
38    protected double min;
39    public double Min {
40      get { return min; }
41    }
42    [Storable]
43    protected double max;
44    public double Max {
45      get { return max; }
46    }
47
48    [Storable]
49    protected double currentCenter;
50    public double CurrentCenter {
51      get { return currentCenter; }
52      set { currentCenter = value; }
53    }
54
55    [Storable]
56    protected double currentSpread;
57    public double CurrentSpread {
58      get { return currentSpread; }
59      set { currentSpread = value; }
60    }
61
62    [StorableConstructor]
63    protected DoubleVariable(bool deserializing) : base(deserializing) { }
64    protected DoubleVariable(DoubleVariable original, Cloner cloner)
65      : base(original, cloner) {
66      min = original.min;
67      max = original.max;
68      currentSpread = original.currentSpread;
69      currentCenter = original.currentCenter;
70    }
71    public DoubleVariable() : base() { }
72    public DoubleVariable(string variableName, IEnumerable<double> variableValues)
73      : base(variableName) {
74      min = variableValues.Min();
75      max = variableValues.Max();
76    }
77    protected DoubleVariable(string variableName, double min, double max)
78      : base(variableName) {
79      this.min = min;
80      this.max = max;
81    }
82    public DoubleVariable(string variableName, IEnumerable<double> variableValues, double center, double spread)
83      : this(variableName, variableValues) {
84      CurrentCenter = center;
85      CurrentSpread = spread;
86    }
87
88    public override IDeepCloneable Clone(Cloner cloner) {
89      return new DoubleVariable(this, cloner);
90    }
91
92    public override string ToString() {
93      return (currentCenter - currentSpread) + " - " + (currentCenter + currentSpread);
94    }
95
96    public override bool MatchInput(string target) {
97      return Match(Double.Parse(target));
98    }
99
100    public override bool Match(double target) {
101      return currentCenter - currentSpread <= target && target <= currentCenter + currentSpread;
102    }
103
104    public override IVariable GetEmptyCopy() {
105      return new DoubleVariable(variableName, min, max);
106    }
107    public override IVariable GetSetCopy() {
108      DoubleVariable copy = (DoubleVariable)GetEmptyCopy();
109      copy.CurrentCenter = this.CurrentCenter;
110      copy.CurrentSpread = this.CurrentSpread;
111      return copy;
112    }
113
114    // this method is not implemented on purpose, because it may lead to confusion or errors if the wrong parameter would be used (changeSymbolProbability instead of spreadPercentage)
115    public override void Randomize(IRandom random, double changeSymbolProbability) {
116      throw new NotImplementedException("The method DoubleVariable.Randomize(IRandom, double) should not be used. Use DoubleVariable.Randomize(IRandom, double, double) instead.");
117    }
118
119    // changeSymbolProbability is not used on purpose
120    public void Randomize(IRandom random, double changeSymbolProbability, double spreadPercentage) {
121      if (spreadPercentage < 0 || spreadPercentage > 100) {
122        throw new ArgumentException("Spread percentage has to be between 0 and 100.");
123      }
124      double delta = Max - Min;
125      CurrentCenter = random.NextDouble() * delta + Min;
126      CurrentSpread = random.NextDouble() * (delta * spreadPercentage);
127    }
128
129    public override bool Identical(IVariable target) {
130      var targetCast = target as DoubleVariable;
131      if (targetCast == null) { return false; }
132      if (variableName != targetCast.variableName || !currentCenter.IsAlmost(targetCast.currentCenter)
133        || !currentSpread.IsAlmost(targetCast.currentSpread) || !max.IsAlmost(targetCast.max)
134        || !min.IsAlmost(targetCast.min)) { return false; }
135
136      return true;
137    }
138
139    public override double GetGenerality() {
140      double delta = max - min;
141      double intervalInBoundsWidth = Math.Min(max, currentCenter + currentSpread) - Math.Max(min, currentCenter - currentSpread);
142      double generality = intervalInBoundsWidth / delta;
143      return generality > 1 ? 1 : generality;
144    }
145
146    public override bool IsGreaterThanOrEquallyGeneral(IVariable target) {
147      var targetCast = target as DoubleVariable;
148      if (targetCast == null) { return false; }
149      return currentCenter - currentSpread < targetCast.currentCenter - targetCast.currentSpread
150        && currentCenter + currentSpread > targetCast.currentCenter + targetCast.currentSpread;
151    }
152
153    public override IVariable CrossParentsAtPosition(IVariable parent2, int pos) {
154      DoubleVariable parent2Cast = parent2 as DoubleVariable;
155      if (parent2Cast == null) { throw new ArgumentException("Argument is not of the correct type."); }
156      if (pos > 1 || pos < 0) { throw new ArgumentOutOfRangeException(); }
157      DoubleVariable crossed = (DoubleVariable)this.GetSetCopy();
158      if (pos == 1) {
159        crossed.CurrentSpread = parent2Cast.CurrentSpread;
160      }
161      return crossed;
162    }
163
164    public override void Manipulate(IRandom random, string stringValue, int pos,
165                                   double spreadPercentage) {
166      Manipulate(random, pos, spreadPercentage);
167    }
168
169    public override void Manipulate(IRandom random, string stringValue, int pos) {
170      throw new NotImplementedException("DoubleVariable.Manipulate(IRandom, string, int) cannot be used. Use DoubleVariable.Manipulate(IRandom, string, int, double) or DoubleVariable.Manipulate(IRandom, int, double) instead.");
171    }
172
173    public void Manipulate(IRandom random, int pos, double percentage) {
174      if (pos > 1 || pos < 0) { throw new ArgumentOutOfRangeException(); }
175      double delta = max - min;
176      double maxChange = delta * percentage;
177      double actualChange = (random.NextDouble() * maxChange * 2) - maxChange;
178      if (pos == 0) {
179        currentCenter += actualChange;
180      } else if (pos == 1) {
181        currentSpread += actualChange;
182        //otherwise the interval could be corrupt and no input could match the rule.
183        currentSpread = currentSpread > 0 ? currentSpread : 0;
184      }
185    }
186
187    public override void Cover(IRandom random, string stringValue, double changeSymbolProbability) {
188      CoverWithSpreadPercentage(random, stringValue, changeSymbolProbability);
189    }
190
191    public void CoverWithSpreadPercentage(IRandom random, string stringValue, double spreadPercentage) {
192      currentCenter = double.Parse(stringValue);
193      double delta = max - min;
194      currentSpread = random.NextDouble() * (delta * spreadPercentage);
195    }
196  }
197}
Note: See TracBrowser for help on using the repository browser.