Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ValueConfiguration.cs @ 5144

Last change on this file since 5144 was 5144, checked in by cneumuel, 13 years ago

#1215

  • added possibility to create all parameter combinations from a ParameterConfigurationTree and generate an experiment from them
File size: 13.1 KB
Line 
1using System;
2using System.Linq;
3using HeuristicLab.Common;
4using HeuristicLab.Core;
5using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
6using HeuristicLab.Data;
7using System.Drawing;
8using HeuristicLab.Encodings.RealVectorEncoding;
9using HeuristicLab.Encodings.IntegerVectorEncoding;
10using HeuristicLab.PluginInfrastructure;
11using System.Collections.Generic;
12using System.Text;
13
14namespace HeuristicLab.Problems.MetaOptimization {
15  // TODO: ItemName/Descr, storability
16  [StorableClass]
17  public class ValueConfiguration : Item, IValueConfiguration {
18    [Storable]
19    protected bool isOptimizable;
20    public bool IsOptimizable {
21      get { return isOptimizable; }
22      set {
23        if (this.isOptimizable != value) {
24          this.isOptimizable = value;
25          OnIsOptimizableChanged();
26        }
27      }
28    }
29
30    [Storable]
31    protected bool optimize;
32    public bool Optimize {
33      get { return optimize; }
34      set {
35        if (optimize != value) {
36          optimize = value;
37          if (optimize) {
38            ClearParameterConfigurations();
39            if (this.actualValue.Value is IParameterizedNamedItem) PopulateParameterConfigurations(this.actualValue.Value as IParameterizedNamedItem);
40          } else {
41            ClearParameterConfigurations();
42          }
43          OnOptimizeChanged();
44          OnToStringChanged();
45        }
46      }
47    }
48
49    [Storable]
50    protected IItemCollection<IParameterConfiguration> parameterConfigurations = new ItemCollection<IParameterConfiguration>();
51    public IItemCollection<IParameterConfiguration> ParameterConfigurations {
52      get { return new ReadOnlyItemCollection<IParameterConfiguration>(this.parameterConfigurations); }
53      protected set { this.parameterConfigurations = value; }
54    }
55
56    [Storable]
57    protected ConstrainedValue actualValue;
58    public virtual ConstrainedValue ActualValue {
59      get { return actualValue; }
60      set {
61        if (this.actualValue != value) {
62          RegisterActualValueEvents();
63          ClearParameterConfigurations();
64          this.actualValue = value;
65          if (this.actualValue.Value is IParameterizedNamedItem) PopulateParameterConfigurations(this.actualValue.Value as IParameterizedNamedItem);
66          OnValueChanged();
67          OnToStringChanged();
68          DeregisterActualValueEvents();
69        }
70      }
71    }
72
73    [Storable]
74    protected IRange rangeConstraint;
75    public IRange RangeConstraint {
76      get { return rangeConstraint; }
77      private set {
78        if (rangeConstraint != value) {
79          DeregisterRangeConstraintEvents();
80          rangeConstraint = value;
81          RegisterActualValueEvents();
82        }
83      }
84    }
85
86    #region Constructors and Cloning
87    public ValueConfiguration(IItem value, Type valueDataType) {
88      this.ParameterConfigurations = new ItemList<IParameterConfiguration>();
89      var validValues = new ItemSet<IItem>(ApplicationManager.Manager.GetInstances(valueDataType).Select(x => (IItem)x).OrderBy(x => x.ItemName));
90      this.ActualValue = new ConstrainedValue(value, valueDataType, validValues, false);
91      this.IsOptimizable = true;
92      if (actualValue.ValueDataType == typeof(IntValue)) {
93        RangeConstraint = new IntValueRange(new IntValue(0), (IntValue)value, new IntValue(1));
94      } else if (actualValue.ValueDataType == typeof(DoubleValue)) {
95        RangeConstraint = new DoubleValueRange(new DoubleValue(0), (DoubleValue)value, new DoubleValue(0.01));
96      } else if (actualValue.ValueDataType == typeof(PercentValue)) {
97        RangeConstraint = new PercentValueRange(new PercentValue(0), new PercentValue(1), new PercentValue(0.001));
98      } else if (actualValue.ValueDataType == typeof(BoolValue)) {
99        this.IsOptimizable = false; // there is nothing to configure for bools
100      } else {
101        RangeConstraint = null;
102      }
103    }
104
105    public ValueConfiguration() { }
106    [StorableConstructor]
107    protected ValueConfiguration(bool deserializing) { }
108    protected ValueConfiguration(ValueConfiguration original, Cloner cloner)
109      : base(original, cloner) {
110      this.ParameterConfigurations = cloner.Clone(original.parameterConfigurations);
111      this.actualValue = cloner.Clone(original.ActualValue);
112      this.rangeConstraint = cloner.Clone(original.RangeConstraint);
113      this.isOptimizable = original.isOptimizable;
114      this.optimize = original.optimize;
115      RegisterActualValueEvents();
116      RegisterRangeConstraintEvents();
117    }
118    public override IDeepCloneable Clone(Cloner cloner) {
119      return new ValueConfiguration(this, cloner);
120    }
121    [StorableHook(HookType.AfterDeserialization)]
122    private void AfterDeserialization() {
123      RegisterRangeConstraintEvents();
124    }
125    #endregion
126
127    protected virtual void PopulateParameterConfigurations(IParameterizedNamedItem parameterizedItem) {
128      foreach (var childParameter in parameterizedItem.Parameters) {
129        var pc = ParameterConfiguration.Create(parameterizedItem, childParameter);
130        if (pc != null) this.parameterConfigurations.Add(pc);
131      }
132    }
133    protected virtual void ClearParameterConfigurations() {
134      parameterConfigurations.Clear();
135    }
136
137    private void RegisterRangeConstraintEvents() {
138      if (this.RangeConstraint != null) this.RangeConstraint.ToStringChanged += new EventHandler(RangeConstraint_ToStringChanged);
139    }
140    private void DeregisterRangeConstraintEvents() {
141      if (this.RangeConstraint != null) this.RangeConstraint.ToStringChanged -= new EventHandler(RangeConstraint_ToStringChanged);
142    }
143    private void RegisterActualValueEvents() {
144      if (this.actualValue != null) this.actualValue.ToStringChanged += new EventHandler(actualValue_ToStringChanged);
145    }
146    private void DeregisterActualValueEvents() {
147      if (this.actualValue != null) this.actualValue.ToStringChanged -= new EventHandler(actualValue_ToStringChanged);
148    }
149
150    #region Events
151    void actualValue_ToStringChanged(object sender, EventArgs e) {
152      OnToStringChanged();
153    }
154    void RangeConstraint_ToStringChanged(object sender, EventArgs e) {
155      OnToStringChanged();
156    }
157    #endregion
158
159    #region IItem Members
160    public override string ItemDescription {
161      get { return (actualValue != null && actualValue.Value != null) ? actualValue.Value.ItemDescription : base.ItemDescription; }
162    }
163
164    public override Image ItemImage {
165      get { return (actualValue != null && actualValue.Value != null) ? actualValue.Value.ItemImage : base.ItemImage; }
166    }
167
168    public override string ItemName {
169      get { return (actualValue != null && actualValue.Value != null) ? actualValue.Value.ItemDescription : base.ItemName; }
170    }
171    #endregion
172
173    #region Event Handlers
174    public virtual event EventHandler ValueChanged;
175    protected virtual void OnValueChanged() {
176      var handler = ValueChanged;
177      if (handler != null) handler(this, EventArgs.Empty);
178    }
179
180    public virtual event EventHandler IsOptimizableChanged;
181    private void OnIsOptimizableChanged() {
182      var handler = IsOptimizableChanged;
183      if (handler != null) handler(this, EventArgs.Empty);
184    }
185
186    public virtual event EventHandler OptimizeChanged;
187    protected virtual void OnOptimizeChanged() {
188      var handler = OptimizeChanged;
189      if (handler != null) handler(this, EventArgs.Empty);
190    }
191    #endregion
192
193    public override string ToString() {
194      if (ActualValue != null && ActualValue.Value != null) {
195        if (ActualValue.Value is IParameterizedItem) {
196          if (Optimize) {
197            return string.Format("{0} (Optimize)", ActualValue.Value.ItemName);
198          } else {
199            return string.Format("{0}", ActualValue.Value.ItemName);
200          }
201        } else {
202          if (Optimize) {
203            return string.Format("{0} (Optimize: {1})", ActualValue.Value.ItemName, RangeConstraint);
204          } else {
205            return string.Format("{0}: {1}", ActualValue.Value.ItemName, ActualValue.Value);
206          }
207        }
208      } else {
209        return base.ToString();
210      }
211    }
212
213    public string ToParameterInfoString() {
214      StringBuilder sb = new StringBuilder();
215      if (this.Optimize) {
216        if (this.ParameterConfigurations.Count > 0) {
217          var parameterInfos = new List<string>();
218          foreach (var pc in this.ParameterConfigurations) {
219            if (pc.Optimize) parameterInfos.Add(pc.ToParameterInfoString());
220          }
221          sb.Append(string.Join(", ", parameterInfos.ToArray()));
222        }
223      }
224      return sb.ToString();
225    }
226
227    public virtual void Parameterize(IParameterizedItem item) {
228      foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
229        pc.Parameterize((IValueParameter)item.Parameters[pc.ParameterName]);
230      }
231    }
232
233    public void Randomize(IRandom random) {
234      if (Optimize) {
235        if (rangeConstraint != null) {
236          this.actualValue.Value = rangeConstraint.GetRandomValue(random);
237        } else {
238          foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
239            pc.Randomize(random);
240          }
241        }
242      }
243    }
244
245    public void Mutate(IRandom random, MutateDelegate mutate, ParameterConfigurationManipulator pcmanip) {
246      if (Optimize) {
247        if (rangeConstraint != null) {
248          mutate(random, this, pcmanip);
249        } else {
250          foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
251            pc.Mutate(random, mutate, pcmanip);
252          }
253        }
254      }
255    }
256
257    public void Cross(IRandom random, IOptimizable other, CrossDelegate cross, ParameterConfigurationCrossover pccross) {
258      if (Optimize) {
259        IValueConfiguration otherVc = (IValueConfiguration)other;
260        if (rangeConstraint != null) {
261          cross(random, this, pccross);
262
263          //if (this.actualValue.ValueDataType == typeof(IntValue)) {
264          //  //this.actualValue.Value = new IntValue((((IntValue)this.actualValue.Value).Value + ((IntValue)other.ActualValue.Value).Value) / 2);
265
266          //  IntegerVector[] parents = new IntegerVector[2];
267          //  parents[0] = new IntegerVector(new int[] { ((IntValue)this.actualValue.Value).Value });
268          //  parents[1] = new IntegerVector(new int[] { ((IntValue)other.ActualValue.Value).Value });
269
270          //  this.actualValue.Value = new IntValue(HeuristicLab.Encodings.IntegerVectorEncoding.DiscreteCrossover.Apply(random, parents[0], parents[1]).First());
271
272          //} else if (this.actualValue.ValueDataType == typeof(DoubleValue)) {
273          //  //this.actualValue.Value = new DoubleValue((((DoubleValue)this.actualValue.Value).Value + ((DoubleValue)other.ActualValue.Value).Value) / 2);
274          //  RealVector[] parents = new RealVector[2];
275          //  parents[0] = new RealVector(new double[] { ((DoubleValue)this.actualValue.Value).Value });
276          //  parents[1] = new RealVector(new double[] { ((DoubleValue)other.ActualValue.Value).Value });
277
278          //  if (random.NextDouble() < 0.5) {
279          //    this.actualValue.Value = new DoubleValue(AverageCrossover.Apply(random, new ItemArray<RealVector>(parents)).First());
280          //  } else {
281          //    this.actualValue.Value = new DoubleValue(HeuristicLab.Encodings.RealVectorEncoding.DiscreteCrossover.Apply(random, new ItemArray<RealVector>(parents)).First());
282          //  }
283          //  //this.actualValue.Value = new DoubleValue(AverageCrossover.Apply(random, new ItemArray<RealVector>(parents)).First());
284
285          //} else if (this.actualValue.ValueDataType == typeof(PercentValue)) {
286          //  //this.actualValue.Value = new PercentValue((((PercentValue)this.actualValue.Value).Value + ((PercentValue)other.ActualValue.Value).Value) / 2);
287
288          //  RealVector[] parents = new RealVector[2];
289          //  parents[0] = new RealVector(new double[] { ((PercentValue)this.actualValue.Value).Value });
290          //  parents[1] = new RealVector(new double[] { ((PercentValue)other.ActualValue.Value).Value });
291
292          //  if (random.NextDouble() < 0.5) {
293          //    this.actualValue.Value = new PercentValue(AverageCrossover.Apply(random, new ItemArray<RealVector>(parents)).First());
294          //  } else {
295          //    this.actualValue.Value = new PercentValue(HeuristicLab.Encodings.RealVectorEncoding.DiscreteCrossover.Apply(random, new ItemArray<RealVector>(parents)).First());
296          //  }
297
298          //} else if (this.actualValue.ValueDataType == typeof(BoolValue)) {
299          //  if (random.NextDouble() > 0.5)
300          //    this.actualValue.Value = this.actualValue.Value;
301          //  else
302          //    this.actualValue.Value = other.ActualValue.Value;
303          //} else {
304          //  throw new NotImplementedException();
305          //}
306        } else {
307          for (int i = 0; i < this.ParameterConfigurations.Count; i++) {
308            this.ParameterConfigurations.ElementAt(i).Cross(random, otherVc.ParameterConfigurations.ElementAt(i), cross, pccross);
309          }
310        }
311      }
312    }
313  }
314}
Note: See TracBrowser for help on using the repository browser.