Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encodings/RangeConstraints/Range.cs @ 5023

Last change on this file since 5023 was 5023, checked in by cneumuel, 14 years ago

#1215 worked on metaoptimization

File size: 6.5 KB
Line 
1using System;
2using HeuristicLab.Common;
3using HeuristicLab.Core;
4using HeuristicLab.Data;
5using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
6
7namespace HeuristicLab.Problems.MetaOptimization {
8  [StorableClass]
9  public abstract class Range<T> : Item, IRange<T> where T : class, IItem, IStringConvertibleValue, IDeepCloneable {
10    [Storable]
11    private T lowerBound;
12    public T LowerBound {
13      get { return lowerBound; }
14      set {
15        if (lowerBound != value) {
16          if (lowerBound != null) {
17            lowerBound.ValueChanged -= new EventHandler(lowerBound_ToStringChanged);
18          }
19          lowerBound = value;
20          if (lowerBound != null) {
21            lowerBound.ValueChanged += new EventHandler(lowerBound_ToStringChanged);
22          }
23          OnLowerBoundChanged();
24        }
25      }
26    }
27
28    [Storable]
29    private T upperBound;
30    public T UpperBound {
31      get { return upperBound; }
32      set {
33        if (upperBound != value) {
34          if (upperBound != null) {
35            upperBound.ValueChanged -= new EventHandler(upperBound_ToStringChanged);
36          }
37          upperBound = value;
38          if (upperBound != null) {
39            upperBound.ValueChanged += new EventHandler(upperBound_ToStringChanged);
40          }
41          OnUpperBoundChanged();
42        }
43      }
44    }
45
46    [Storable]
47    private T stepSize;
48    public T StepSize {
49      get { return stepSize; }
50      set {
51        if (stepSize != value) {
52          if (stepSize != null) {
53            stepSize.ValueChanged -= new EventHandler(upperBound_ToStringChanged);
54          }
55          stepSize = value;
56          if (stepSize != null) {
57            stepSize.ValueChanged += new EventHandler(stepSize_ToStringChanged);
58          }
59          OnStepSizeChanged();
60        }
61      }
62    }
63
64    #region IRange Members
65    object IRange.LowerBound {
66      get { return lowerBound; }
67      set { lowerBound = (T)value; }
68    }
69    object IRange.UpperBound {
70      get { return upperBound; }
71      set { upperBound = (T)value; }
72    }
73    object IRange.StepSize {
74      get { return stepSize; }
75      set { stepSize = (T)value; }
76    }
77    #endregion
78
79    #region Constructors and Cloning
80    public Range(T lowerBound, T upperBound, T stepSize) {
81      this.LowerBound = lowerBound;
82      this.UpperBound = upperBound;
83      this.StepSize = stepSize;
84    }
85
86    public Range() { }
87    [StorableConstructor]
88    protected Range(bool deserializing) : base(deserializing) { }
89    protected Range(Range<T> original, Cloner cloner) : base(original, cloner) {
90      this.LowerBound = cloner.Clone(original.LowerBound);
91      this.UpperBound = cloner.Clone(original.UpperBound);
92      this.StepSize = cloner.Clone(original.StepSize);
93    }
94
95    [StorableHook(HookType.AfterDeserialization)]
96    private void AfterDeserialization() {
97      if (lowerBound != null) {
98        lowerBound.ValueChanged += new EventHandler(lowerBound_ToStringChanged);
99      }
100      if (upperBound != null) {
101        upperBound.ValueChanged += new EventHandler(upperBound_ToStringChanged);
102      }
103      if (stepSize != null) {
104        stepSize.ValueChanged += new EventHandler(stepSize_ToStringChanged);
105      }
106    }
107    #endregion
108
109    #region Events
110    private void lowerBound_ToStringChanged(object sender, EventArgs e) {
111      OnToStringChanged();
112    }
113    private void upperBound_ToStringChanged(object sender, EventArgs e) {
114      OnToStringChanged();
115    }
116    private void stepSize_ToStringChanged(object sender, EventArgs e) {
117      OnToStringChanged();
118    }
119    #endregion
120
121    #region Eventhandler
122    public event EventHandler LowerBoundChanged;
123    private void OnLowerBoundChanged() {
124      var handler = LowerBoundChanged;
125      if (handler != null) handler(this, EventArgs.Empty);
126    }
127    public event EventHandler UpperBoundChanged;
128    private void OnUpperBoundChanged() {
129      var handler = UpperBoundChanged;
130      if (handler != null) handler(this, EventArgs.Empty);
131    }
132    public event EventHandler StepSizeChanged;
133    private void OnStepSizeChanged() {
134      var handler = StepSizeChanged;
135      if (handler != null) handler(this, EventArgs.Empty);
136    }
137    public event EventHandler ValueChanged;
138    private void OnValueChanged() {
139      var handler = ValueChanged;
140      if (handler != null) handler(this, EventArgs.Empty);
141    }
142    #endregion
143
144    public override string ToString() {
145      return string.Format("{0},{1}:{2}", LowerBound.ToString(), UpperBound.ToString(), StepSize.ToString());
146    }
147
148    #region IStringConvertibleValue Members
149
150    public string GetValue() {
151      return this.ToString();
152    }
153    public bool ReadOnly {
154      get { return false; }
155    }
156    public bool SetValue(string value) {
157      var parts1 = value.Split(':');
158      if (parts1.Length != 2) return false;
159      var parts2 = parts1[0].Split(',');
160      if (parts2.Length != 2) return false;
161
162      return
163        lowerBound.SetValue(parts2[0]) &&
164        upperBound.SetValue(parts2[1]) &&
165        stepSize.SetValue(parts1[1]);
166    }
167    public bool Validate(string value, out string errorMessage) {
168      // TODO: check that upper is larger than lower and that stepsize < upper-lower
169      T lower = (T)lowerBound.Clone();
170      T upper = (T)upperBound.Clone();
171      T step = (T)stepSize.Clone();
172
173      var parts1 = value.Split(':');
174      if (parts1.Length != 2) {
175        errorMessage = "Could not parse range."; return false;
176      }
177      var parts2 = parts1[0].Split(',');
178      if (parts2.Length != 2) {
179        errorMessage = "Could not parse range."; return false;
180      }
181
182      if (lowerBound.SetValue(parts2[0]) &&
183          upperBound.SetValue(parts2[1]) &&
184          stepSize.SetValue(parts1[1])) {
185        errorMessage = string.Empty; return true;
186      } else {
187        errorMessage = "Could not parse range."; return false;
188      }
189    }
190
191    #endregion
192
193    public T GetRandomValue(IRandom random) {
194      // by a chance return the extreme values of this range to intensify search in those regions
195      if (random.NextDouble() < 0.1) {
196        if (random.NextDouble() < 0.5) {
197          return LowerBound;
198        } else {
199          return UpperBound;
200        }
201      }
202
203      // otherwise sample a random value from the range
204      return GetRandomSample(random);
205    }
206
207    protected abstract T GetRandomSample(IRandom random);
208
209    IItem IRange.GetRandomValue(IRandom random) {
210      return GetRandomValue(random);
211    }
212  }
213}
Note: See TracBrowser for help on using the repository browser.