Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ParameterConfigurationEncoding/HeuristicLab.Encodings.ParameterConfigurationEncoding/3.3/RangeConstraints/Range.cs @ 10368

Last change on this file since 10368 was 8644, checked in by jkarder, 12 years ago

#1853:

  • removed multi-crossovers for integer and double values
  • restructured crossovers and manipulators for integer and double values
File size: 8.9 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.Data;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29
30namespace HeuristicLab.Encodings.ParameterConfigurationEncoding {
31  [StorableClass]
32  public abstract class Range<T> : Item, IRange<T> where T : class, IItem, IStringConvertibleValue, IDeepCloneable {
33    [Storable]
34    private T lowerBound;
35    public virtual T LowerBound {
36      get { return lowerBound; }
37      set {
38        if (lowerBound != value) {
39          if (lowerBound != null) {
40            lowerBound.ValueChanged -= new EventHandler(lowerBound_ValueChanged);
41            lowerBound.ValueChanged -= new EventHandler(lowerBound_ToStringChanged);
42          }
43          lowerBound = value;
44          if (lowerBound != null) {
45            lowerBound.ValueChanged += new EventHandler(lowerBound_ValueChanged);
46            lowerBound.ValueChanged += new EventHandler(lowerBound_ToStringChanged);
47          }
48          OnLowerBoundChanged();
49        }
50      }
51    }
52
53    [Storable]
54    private T upperBound;
55    public virtual T UpperBound {
56      get { return upperBound; }
57      set {
58        if (upperBound != value) {
59          if (upperBound != null) {
60            upperBound.ValueChanged -= new EventHandler(upperBound_ValueChanged);
61            upperBound.ValueChanged -= new EventHandler(upperBound_ToStringChanged);
62          }
63          upperBound = value;
64          if (upperBound != null) {
65            upperBound.ValueChanged += new EventHandler(upperBound_ValueChanged);
66            upperBound.ValueChanged += new EventHandler(upperBound_ToStringChanged);
67          }
68          OnUpperBoundChanged();
69        }
70      }
71    }
72
73    [Storable]
74    private T stepSize;
75    public virtual T StepSize {
76      get { return stepSize; }
77      set {
78        if (stepSize != value) {
79          if (stepSize != null) {
80            stepSize.ValueChanged -= new EventHandler(stepSize_ValueChanged);
81            stepSize.ValueChanged -= new EventHandler(stepSize_ToStringChanged);
82          }
83          stepSize = value;
84          if (stepSize != null) {
85            stepSize.ValueChanged += new EventHandler(stepSize_ValueChanged);
86            stepSize.ValueChanged += new EventHandler(stepSize_ToStringChanged);
87          }
88          OnStepSizeChanged();
89        }
90      }
91    }
92
93    #region IRange Members
94    object IRange.LowerBound {
95      get { return lowerBound; }
96      set { lowerBound = (T)value; }
97    }
98    object IRange.UpperBound {
99      get { return upperBound; }
100      set { upperBound = (T)value; }
101    }
102    object IRange.StepSize {
103      get { return stepSize; }
104      set { stepSize = (T)value; }
105    }
106    #endregion
107
108    #region Constructors and Cloning
109    [StorableConstructor]
110    protected Range(bool deserializing) : base(deserializing) { }
111    protected Range(Range<T> original, Cloner cloner)
112      : base(original, cloner) {
113      this.LowerBound = cloner.Clone(original.LowerBound);
114      this.UpperBound = cloner.Clone(original.UpperBound);
115      this.StepSize = cloner.Clone(original.StepSize);
116    }
117    public Range(T lowerBound, T upperBound, T stepSize)
118      : base() {
119      this.LowerBound = lowerBound;
120      this.UpperBound = upperBound;
121      this.StepSize = stepSize;
122    }
123    [StorableHook(HookType.AfterDeserialization)]
124    private void AfterDeserialization() {
125      if (lowerBound != null) {
126        lowerBound.ValueChanged += new EventHandler(lowerBound_ValueChanged);
127        lowerBound.ValueChanged += new EventHandler(lowerBound_ToStringChanged);
128      }
129      if (upperBound != null) {
130        upperBound.ValueChanged += new EventHandler(upperBound_ValueChanged);
131        upperBound.ValueChanged += new EventHandler(upperBound_ToStringChanged);
132      }
133      if (stepSize != null) {
134        stepSize.ValueChanged += new EventHandler(stepSize_ValueChanged);
135        stepSize.ValueChanged += new EventHandler(stepSize_ToStringChanged);
136      }
137    }
138    #endregion
139
140    #region Events
141    private void lowerBound_ValueChanged(object sender, EventArgs e) {
142      OnLowerBoundChanged();
143    }
144    private void upperBound_ValueChanged(object sender, EventArgs e) {
145      OnUpperBoundChanged();
146    }
147    private void stepSize_ValueChanged(object sender, EventArgs e) {
148      OnStepSizeChanged();
149    }
150    private void lowerBound_ToStringChanged(object sender, EventArgs e) {
151      OnToStringChanged();
152    }
153    private void upperBound_ToStringChanged(object sender, EventArgs e) {
154      OnToStringChanged();
155    }
156    private void stepSize_ToStringChanged(object sender, EventArgs e) {
157      OnToStringChanged();
158    }
159    #endregion
160
161    #region Eventhandler
162    public event EventHandler LowerBoundChanged;
163    private void OnLowerBoundChanged() {
164      var handler = LowerBoundChanged;
165      if (handler != null) handler(this, EventArgs.Empty);
166    }
167    public event EventHandler UpperBoundChanged;
168    private void OnUpperBoundChanged() {
169      var handler = UpperBoundChanged;
170      if (handler != null) handler(this, EventArgs.Empty);
171    }
172    public event EventHandler StepSizeChanged;
173    private void OnStepSizeChanged() {
174      var handler = StepSizeChanged;
175      if (handler != null) handler(this, EventArgs.Empty);
176    }
177    public event EventHandler ValueChanged;
178    private void OnValueChanged() {
179      var handler = ValueChanged;
180      if (handler != null) handler(this, EventArgs.Empty);
181    }
182    #endregion
183
184    public override string ToString() {
185      return string.Format("{0},{1}:{2}", LowerBound.ToString(), UpperBound.ToString(), StepSize.ToString());
186    }
187
188    #region IStringConvertibleValue Members
189
190    public string GetValue() {
191      return this.ToString();
192    }
193    public bool ReadOnly {
194      get { return false; }
195    }
196    public bool SetValue(string value) {
197      var parts1 = value.Split(':');
198      if (parts1.Length != 2) return false;
199      var parts2 = parts1[0].Split(',');
200      if (parts2.Length != 2) return false;
201
202      return
203        lowerBound.SetValue(parts2[0]) &&
204        upperBound.SetValue(parts2[1]) &&
205        stepSize.SetValue(parts1[1]);
206    }
207    public bool Validate(string value, out string errorMessage) {
208      T lower = (T)lowerBound.Clone();
209      T upper = (T)upperBound.Clone();
210      T step = (T)stepSize.Clone();
211
212      var parts1 = value.Split(':');
213      if (parts1.Length != 2) {
214        errorMessage = "Could not parse range."; return false;
215      }
216      var parts2 = parts1[0].Split(',');
217      if (parts2.Length != 2) {
218        errorMessage = "Could not parse range."; return false;
219      }
220      if (lowerBound.SetValue(parts2[0]) &&
221          upperBound.SetValue(parts2[1]) &&
222          stepSize.SetValue(parts1[1])) {
223        if (Comparer<T>.Default.Compare(lowerBound, upperBound) >= 0) {
224          errorMessage = "Invalid bounds. (Lower >= Upper)"; return false;
225        }
226        errorMessage = string.Empty; return true;
227      } else {
228        errorMessage = "Could not parse range."; return false;
229      }
230    }
231
232    #endregion
233
234    public T GetRandomValue(IRandom random) {
235      // by a chance return the extreme values of this range to intensify search in those regions
236      if (random.NextDouble() < 0.1) {
237        if (random.NextDouble() < 0.5) {
238          return (T)LowerBound.Clone();
239        } else {
240          return (T)UpperBound.Clone();
241        }
242      }
243
244      // otherwise sample a random value from the range
245      return GetRandomSample(random);
246    }
247
248    protected abstract T GetRandomSample(IRandom random);
249
250    IItem IRange.GetRandomValue(IRandom random) {
251      return GetRandomValue(random);
252    }
253
254    public abstract IEnumerable<T> GetCombinations();
255    IEnumerable<IItem> IRange.GetCombinations() {
256      return GetCombinations().Cast<IItem>().ToArray();
257    }
258
259    public virtual double CalculateSimilarity(IItem a, IItem b) {
260      return CalculateSimilarityValue((T)a, (T)b);
261    }
262
263    protected abstract double CalculateSimilarityValue(T a, T b);
264  }
265}
Note: See TracBrowser for help on using the repository browser.