Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encodings/ValueConfigurations/ValueConfiguration.cs @ 5110

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

#1215

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