Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1215

  • implemented population diversity analysis
File size: 12.7 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 : NamedItem, IValueConfiguration {
18    public override bool CanChangeName {
19      get { return true; }
20    }
21
22    public override bool CanChangeDescription {
23      get { return true; }
24    }
25
26    [Storable]
27    protected bool isOptimizable;
28    public bool IsOptimizable {
29      get { return isOptimizable; }
30      set {
31        if (this.isOptimizable != value) {
32          this.isOptimizable = value;
33          OnIsOptimizableChanged();
34        }
35      }
36    }
37
38    [Storable]
39    protected bool optimize;
40    public bool Optimize {
41      get { return optimize; }
42      set {
43        if (optimize != value) {
44          optimize = value;
45          if (optimize) {
46            ClearParameterConfigurations();
47            if (this.actualValue.Value is IParameterizedNamedItem) PopulateParameterConfigurations(this.actualValue.Value as IParameterizedNamedItem);
48          } else {
49            ClearParameterConfigurations();
50          }
51          OnOptimizeChanged();
52          OnToStringChanged();
53        }
54      }
55    }
56
57    [Storable]
58    protected IItemCollection<IParameterConfiguration> parameterConfigurations = new ItemCollection<IParameterConfiguration>();
59    public IItemCollection<IParameterConfiguration> ParameterConfigurations {
60      get { return new ReadOnlyItemCollection<IParameterConfiguration>(this.parameterConfigurations); }
61      protected set { this.parameterConfigurations = value; }
62    }
63
64    [Storable]
65    protected ConstrainedValue actualValue;
66    public virtual ConstrainedValue ActualValue {
67      get { return actualValue; }
68      set {
69        if (this.actualValue != value) {
70          DeregisterActualValueEvents();
71          ClearParameterConfigurations();
72          this.actualValue = value;
73          if (this.actualValue.Value is IParameterizedNamedItem) PopulateParameterConfigurations(this.actualValue.Value as IParameterizedNamedItem);
74          OnValueChanged();
75          OnToStringChanged();
76          RegisterActualValueEvents();
77        }
78      }
79    }
80
81    [Storable]
82    protected IRange rangeConstraint;
83    public IRange RangeConstraint {
84      get { return rangeConstraint; }
85      private set {
86        if (rangeConstraint != value) {
87          DeregisterRangeConstraintEvents();
88          rangeConstraint = value;
89          RegisterActualValueEvents();
90        }
91      }
92    }
93
94    [Storable]
95    protected int number = 0;
96    public int Number {
97      get { return number; }
98      set {
99        if (value != number) {
100          number = value;
101          OnToStringChanged();
102        }
103      }
104    }
105
106    #region Constructors and Cloning
107    public ValueConfiguration(IItem value, Type valueDataType) {
108      this.ParameterConfigurations = new ItemList<IParameterConfiguration>();
109      var validTypes = ApplicationManager.Manager.GetTypes(valueDataType).OrderBy(x => x.Name).ToArray();
110      this.ActualValue = new ConstrainedValue(value, valueDataType, new ItemSet<IItem> { value }, false);
111      this.IsOptimizable = true;
112      if (actualValue.ValueDataType == typeof(IntValue)) {
113        RangeConstraint = new IntValueRange(new IntValue(0), (IntValue)value, new IntValue(1));
114      } else if (actualValue.ValueDataType == typeof(DoubleValue)) {
115        RangeConstraint = new DoubleValueRange(new DoubleValue(0), (DoubleValue)value, new DoubleValue(0.01));
116      } else if (actualValue.ValueDataType == typeof(PercentValue)) {
117        RangeConstraint = new PercentValueRange(new PercentValue(0), new PercentValue(1), new PercentValue(0.01));
118      } else if (actualValue.ValueDataType == typeof(BoolValue)) {
119        this.IsOptimizable = false; // there is nothing to configure for bools
120      } else {
121        RangeConstraint = null;
122      }
123    }
124
125    public ValueConfiguration() { }
126    [StorableConstructor]
127    protected ValueConfiguration(bool deserializing) { }
128    protected ValueConfiguration(ValueConfiguration original, Cloner cloner)
129      : base(original, cloner) {
130      this.ParameterConfigurations = cloner.Clone(original.parameterConfigurations);
131      this.actualValue = cloner.Clone(original.ActualValue);
132      this.rangeConstraint = cloner.Clone(original.RangeConstraint);
133      this.isOptimizable = original.isOptimizable;
134      this.optimize = original.optimize;
135      this.number = original.number;
136      RegisterActualValueEvents();
137      RegisterRangeConstraintEvents();
138    }
139    public override IDeepCloneable Clone(Cloner cloner) {
140      return new ValueConfiguration(this, cloner);
141    }
142    [StorableHook(HookType.AfterDeserialization)]
143    private void AfterDeserialization() {
144      RegisterRangeConstraintEvents();
145    }
146    #endregion
147
148    protected virtual void PopulateParameterConfigurations(IParameterizedNamedItem parameterizedItem) {
149      foreach (var childParameter in parameterizedItem.Parameters) {
150        var pc = ParameterConfiguration.Create(parameterizedItem, childParameter);
151        if (pc != null) this.parameterConfigurations.Add(pc);
152      }
153    }
154    protected virtual void ClearParameterConfigurations() {
155      parameterConfigurations.Clear();
156    }
157
158    private void RegisterRangeConstraintEvents() {
159      if (this.RangeConstraint != null) this.RangeConstraint.ToStringChanged += new EventHandler(RangeConstraint_ToStringChanged);
160    }
161    private void DeregisterRangeConstraintEvents() {
162      if (this.RangeConstraint != null) this.RangeConstraint.ToStringChanged -= new EventHandler(RangeConstraint_ToStringChanged);
163    }
164    private void RegisterActualValueEvents() {
165      if (this.actualValue != null) this.actualValue.ToStringChanged += new EventHandler(actualValue_ToStringChanged);
166    }
167    private void DeregisterActualValueEvents() {
168      if (this.actualValue != null) this.actualValue.ToStringChanged -= new EventHandler(actualValue_ToStringChanged);
169    }
170
171    #region Events
172    void actualValue_ToStringChanged(object sender, EventArgs e) {
173      OnToStringChanged();
174    }
175    void RangeConstraint_ToStringChanged(object sender, EventArgs e) {
176      OnToStringChanged();
177    }
178    #endregion
179
180    #region IItem Members
181    public override string ItemDescription {
182      get { return (actualValue != null && actualValue.Value != null) ? actualValue.Value.ItemDescription : base.ItemDescription; }
183    }
184
185    public override Image ItemImage {
186      get { return (actualValue != null && actualValue.Value != null) ? actualValue.Value.ItemImage : base.ItemImage; }
187    }
188
189    public override string ItemName {
190      get { return (actualValue != null && actualValue.Value != null) ? actualValue.Value.ItemDescription : base.ItemName; }
191    }
192    #endregion
193
194    #region Event Handlers
195    public virtual event EventHandler ValueChanged;
196    protected virtual void OnValueChanged() {
197      var handler = ValueChanged;
198      if (handler != null) handler(this, EventArgs.Empty);
199    }
200
201    public virtual event EventHandler IsOptimizableChanged;
202    private void OnIsOptimizableChanged() {
203      var handler = IsOptimizableChanged;
204      if (handler != null) handler(this, EventArgs.Empty);
205    }
206
207    public virtual event EventHandler OptimizeChanged;
208    protected virtual void OnOptimizeChanged() {
209      var handler = OptimizeChanged;
210      if (handler != null) handler(this, EventArgs.Empty);
211    }
212    #endregion
213
214    public override string ToString() {
215      if (ActualValue != null && ActualValue.Value != null) {
216        string name = NumberedName;
217
218        if (ActualValue.Value is IParameterizedItem) {
219          if (Optimize) {
220            return string.Format("{0} (Optimize)", name);
221          } else {
222            return string.Format("{0}", name);
223          }
224        } else {
225          if (Optimize) {
226            return string.Format("{0} (Optimize: {1})", name, RangeConstraint);
227          } else {
228            return string.Format("{0}: {1}", name, ActualValue.Value);
229          }
230        }
231      } else {
232        return base.ToString();
233      }
234    }
235
236    public string NumberedName {
237      get {
238        if (this.number == 0) {
239          return (ActualValue != null && ActualValue.Value != null) ? ActualValue.Value.ItemName : base.ToString();
240        } else {
241          return string.Format("{0} {1}", ActualValue.Value.ItemName, number);
242        }
243      }
244    }
245
246    public string ParameterInfoString {
247      get {
248        StringBuilder sb = new StringBuilder();
249        if (this.Optimize && this.ParameterConfigurations.Count > 0) {
250          var parameterInfos = new List<string>();
251          foreach (var pc in this.ParameterConfigurations) {
252            if (pc.Optimize) parameterInfos.Add(pc.ParameterInfoString);
253          }
254          sb.Append(string.Join(", ", parameterInfos.ToArray()));
255        }
256        return sb.ToString();
257      }
258    }
259
260    public virtual void Parameterize(IParameterizedItem item) {
261      foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
262        pc.Parameterize((IValueParameter)item.Parameters[pc.ParameterName]);
263      }
264    }
265
266    public void Randomize(IRandom random) {
267      if (Optimize) {
268        if (rangeConstraint != null) {
269          this.actualValue.Value = rangeConstraint.GetRandomValue(random);
270        } else {
271          foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
272            pc.Randomize(random);
273          }
274        }
275      }
276    }
277
278    public void Mutate(IRandom random, MutateDelegate mutate, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator) {
279      if (Optimize) {
280        if (rangeConstraint != null) {
281          mutate(random, this, intValueManipulator, doubleValueManipulator);
282        } else {
283          foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
284            pc.Mutate(random, mutate, intValueManipulator, doubleValueManipulator);
285          }
286        }
287      }
288    }
289
290    public void Cross(IRandom random, IOptimizable other, CrossDelegate cross, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover) {
291      if (Optimize) {
292        if (rangeConstraint != null) {
293          cross(random, this, other, intValueCrossover, doubleValueCrossover);
294        } else {
295          IValueConfiguration otherVc = (IValueConfiguration)other;
296          for (int i = 0; i < this.ParameterConfigurations.Count; i++) {
297            this.ParameterConfigurations.ElementAt(i).Cross(random, otherVc.ParameterConfigurations.ElementAt(i), cross, intValueCrossover, doubleValueCrossover);
298          }
299        }
300      }
301    }
302
303    public List<IOptimizable> GetAllOptimizables() {
304      var list = new List<IOptimizable>();
305      foreach (var pc in ParameterConfigurations) {
306        if (pc.Optimize) {
307          if (pc.ValueConfigurations.CheckedItems.Count() > 1) list.Add(pc); // only add if there are more than 1 choices. otherwise it makes no sense to optimize which VC is selected
308          list.AddRange(pc.GetAllOptimizables());
309        }
310      }
311      return list;
312    }
313
314    public void CollectOptimizedParameterNames(List<string> parameterNames, string prefix) {
315      foreach (var pc in ParameterConfigurations) {
316        if (pc.Optimize) {
317          parameterNames.Add(prefix + pc.ParameterName);
318          pc.CollectOptimizedParameterNames(parameterNames, prefix + pc.ParameterName + ".");
319        }
320      }
321    }
322
323    public IEnumerable<string> GetOptimizedParameterNames() {
324      var list = new List<string>();
325      this.CollectOptimizedParameterNames(list, "");
326      return list;
327    }
328
329    public double CalculateSimilarity(IOptimizable optimizable) {
330      var other = (IValueConfiguration)optimizable;
331      if (rangeConstraint != null) {
332        return this.RangeConstraint.CalculateSimilarity(this.ActualValue.Value, other.ActualValue.Value);
333      } else {
334        double sum = 0;
335        int count = 0;
336        for (int i = 0; i < ParameterConfigurations.Count; i++) {
337          if (this.ParameterConfigurations.ElementAt(i).Optimize) {
338            sum += this.ParameterConfigurations.ElementAt(i).CalculateSimilarity(other.ParameterConfigurations.ElementAt(i));
339            count++;
340          }
341        }
342        return count == 0 ? 1.0 : sum / (double)count;
343      }
344    }
345  }
346}
Note: See TracBrowser for help on using the repository browser.