Free cookie consent management tool by TermsFeed Policy Generator

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

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

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