Free cookie consent management tool by TermsFeed Policy Generator

source: addons/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/Range.cs @ 16574

Last change on this file since 16574 was 16574, checked in by gkronber, 5 years ago

#2520: changed HeuristicLab.MetaOptimization addon to compile with new HL.Persistence

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