Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encodings/ParameterConfigurations/ParameterConfiguration.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: 13.0 KB
Line 
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Linq;
5using HeuristicLab.Common;
6using HeuristicLab.Core;
7using HeuristicLab.Data;
8using HeuristicLab.Parameters;
9using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
10using HeuristicLab.PluginInfrastructure;
11
12namespace HeuristicLab.Problems.MetaOptimization {
13  [StorableClass]
14  public class ParameterConfiguration : Item, IParameterConfiguration, IStorableContent {
15    public bool IsOptimizable {
16      get { return true; }
17    }
18
19    [Storable]
20    public string Filename { get; set; }
21
22    [Storable]
23    protected bool optimize;
24    public bool Optimize {
25      get { return optimize; }
26      set {
27        if (optimize != value) {
28          optimize = value;
29          if (optimize) {
30            PopulateValueConfigurations();
31          } else {
32            this.ValueConfigurations.Clear();
33          }
34          OnOptimizeChanged();
35          OnToStringChanged();
36        }
37      }
38    }
39
40    [Storable]
41    protected string parameterName;
42    public string ParameterName {
43      get { return parameterName; }
44      set {
45        if (parameterName != value) {
46          parameterName = value;
47          OnToStringChanged();
48        }
49      }
50    }
51
52    [Storable]
53    protected Type parameterDataType;
54    public Type ParameterDataType {
55      get { return this.parameterDataType; }
56    }
57
58    [Storable]
59    protected IItemSet<IItem> validValues;
60    public IItemSet<IItem> ValidValues {
61      get { return validValues; }
62      protected set {
63        if (this.validValues != value) {
64          this.validValues = value;
65        }
66      }
67    }
68
69    [Storable]
70    protected Type valueDataType;
71    public Type ValueDataType {
72      get { return valueDataType; }
73      protected set { this.valueDataType = value; }
74    }
75
76    [Storable]
77    protected ICheckedValueConfigurationCollection valueConfigurations;
78    public ICheckedValueConfigurationCollection ValueConfigurations {
79      get { return this.valueConfigurations; }
80      protected set {
81        if (this.valueConfigurations != value) {
82          if (this.valueConfigurations != null) DeregisterValueConfigurationEvents();
83          this.valueConfigurations = value;
84          if (this.valueConfigurations != null) RegisterValueConfigurationEvents();
85        }
86      }
87    }
88
89    [Storable]
90    protected int actualValueConfigurationIndex = 0;
91
92    [Storable]
93    protected ConstrainedValue actualValue;
94    public ConstrainedValue ActualValue {
95      get { return actualValue; }
96      set {
97        if (actualValue != value) {
98          DeregisterActualValueEvents();
99          actualValue = value;
100          RegisterActualValueEvents();
101        }
102      }
103    }
104
105    [Storable]
106    protected bool isNullable;
107    public bool IsNullable {
108      get { return isNullable; }
109      protected set {
110        if (this.isNullable != value) {
111          this.isNullable = value;
112        }
113      }
114    }
115
116    #region Constructors and Cloning
117    public ParameterConfiguration(string parameterName, IValueParameter valueParameter) {
118      this.ParameterName = parameterName;
119      this.parameterDataType = valueParameter.GetType();
120      this.valueDataType = valueParameter.DataType;
121      this.validValues = GetValidValues(valueParameter);
122      this.IsNullable = valueParameter.ItemName.StartsWith("Optional");
123      if (IsNullable) {
124        validValues.Add(new NullValue());
125      }
126      this.ValueConfigurations = new CheckedValueConfigurationCollection(this.validValues);
127      this.ActualValue = new ConstrainedValue(valueParameter.Value, valueParameter.DataType, this.ValidValues, this.IsNullable);
128      if (Optimize) {
129        PopulateValueConfigurations();
130      }
131    }
132
133    public ParameterConfiguration() { }
134    [StorableConstructor]
135    protected ParameterConfiguration(bool deserializing) { }
136    protected ParameterConfiguration(ParameterConfiguration original, Cloner cloner) : base(original, cloner) {
137      this.parameterName = original.ParameterName;
138      this.parameterDataType = original.parameterDataType;
139      this.valueDataType = original.ValueDataType;
140      this.validValues = cloner.Clone(original.ValidValues);
141      this.valueConfigurations = cloner.Clone(original.ValueConfigurations);
142      this.ActualValue = cloner.Clone(original.ActualValue);
143      this.optimize = original.optimize;
144      this.actualValueConfigurationIndex = original.actualValueConfigurationIndex;
145      this.isNullable = original.isNullable;
146      if (this.valueConfigurations != null) RegisterValueConfigurationEvents();
147    }
148    public override IDeepCloneable Clone(Cloner cloner) {
149      return new ParameterConfiguration(this, cloner);
150    }
151    [StorableHook(HookType.AfterDeserialization)]
152    private void AfterDeserialization() {
153      if (this.valueConfigurations != null) RegisterValueConfigurationEvents();
154    }
155    #endregion
156
157    private void RegisterValueConfigurationEvents() {
158      this.ValueConfigurations.CheckedItemsChanged += new Collections.CollectionItemsChangedEventHandler<IValueConfiguration>(ValueConfigurations_CheckedItemsChanged);
159      this.ValueConfigurations.ItemsAdded += new Collections.CollectionItemsChangedEventHandler<IValueConfiguration>(ValueConfigurations_ItemsAdded);
160      this.ValueConfigurations.ItemsRemoved += new Collections.CollectionItemsChangedEventHandler<IValueConfiguration>(ValueConfigurations_ItemsRemoved);
161    }
162
163    private void DeregisterValueConfigurationEvents() {
164      this.ValueConfigurations.CheckedItemsChanged -= new Collections.CollectionItemsChangedEventHandler<IValueConfiguration>(ValueConfigurations_CheckedItemsChanged);
165      this.ValueConfigurations.ItemsAdded -= new Collections.CollectionItemsChangedEventHandler<IValueConfiguration>(ValueConfigurations_ItemsAdded);
166      this.ValueConfigurations.ItemsRemoved -= new Collections.CollectionItemsChangedEventHandler<IValueConfiguration>(ValueConfigurations_ItemsRemoved);
167    }
168
169    private void RegisterActualValueEvents() {
170      if (this.ActualValue != null) this.ActualValue.ToStringChanged += new EventHandler(ActualValue_ToStringChanged);
171    }
172    private void DeregisterActualValueEvents() {
173      if (this.ActualValue != null) this.ActualValue.ToStringChanged -= new EventHandler(ActualValue_ToStringChanged);
174    }
175
176    private void PopulateValueConfigurations() {
177      foreach (IItem validValue in this.validValues) {
178        if (validValue is NullValue) {
179          this.ValueConfigurations.Add(new NullValueConfiguration());
180        } else {
181          IItem val;
182          if (ActualValue.Value != null && ActualValue.ValueDataType == validValue.GetType()) {
183            val = ActualValue.Value; // use existing value for that type (if available)
184          } else {
185            val = validValue;
186          }
187          this.ValueConfigurations.Add(new ValueConfiguration(val, val.GetType()), true);
188        }
189      }
190    }
191
192    private IItemSet<IItem> GetValidValues(IValueParameter parameter) {
193      if (IsSubclassOfRawGeneric(typeof(OptionalConstrainedValueParameter<>), parameter.GetType())) {
194        var x = (IEnumerable)parameter.GetType().GetProperty("ValidValues").GetValue(parameter, new object[] { });
195        return new ItemSet<IItem>(x.Cast<IItem>());
196      } else {
197        return new ItemSet<IItem>(ApplicationManager.Manager.GetInstances(valueDataType).Select(x => (IItem)x).OrderBy(x => x.ItemName));
198      }
199    }
200
201    private static bool IsSubclassOfRawGeneric(Type generic, Type toCheck) {
202      while (toCheck != typeof(object)) {
203        var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
204        if (generic == cur) {
205          return true;
206        }
207        toCheck = toCheck.BaseType;
208      }
209      return false;
210    }
211
212    void ValueConfigurations_CheckedItemsChanged(object sender, Collections.CollectionItemsChangedEventArgs<IValueConfiguration> e) {
213      OnToStringChanged();
214    }
215    void ValueConfigurations_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs<IValueConfiguration> e) {
216      OnToStringChanged();
217    }
218    void ValueConfigurations_ItemsAdded(object sender, Collections.CollectionItemsChangedEventArgs<IValueConfiguration> e) {
219      OnToStringChanged();
220    }
221
222    #region INamedItem Properties
223    public virtual string Name {
224      get { return ParameterName; }
225      set { throw new NotSupportedException(); }
226    }
227    public virtual string Description {
228      get { return base.ItemDescription; }
229      set { throw new NotSupportedException(); }
230    }
231    public virtual bool CanChangeDescription {
232      get { return false; }
233    }
234    public virtual bool CanChangeName {
235      get { return false; }
236    }
237    public override string ItemDescription {
238      //get { return parameter != null ? parameter.Description : base.ItemDescription; }
239      get { return base.ItemDescription; }
240    }
241    public override System.Drawing.Image ItemImage {
242      //get { return parameter != null ? parameter.ItemImage : base.ItemImage; }
243      get { return base.ItemImage; }
244    }
245    public override string ItemName {
246      //get { return parameter != null ?parameter.ItemName : base.ItemName; }
247      get { return base.ItemName; }
248    }
249    #endregion
250
251    #region Events
252    void ActualValue_ToStringChanged(object sender, EventArgs e) {
253      OnToStringChanged();
254    }
255    #endregion
256
257    #region Event Handler
258    public virtual event EventHandler NameChanged;
259    protected virtual void OnNameChanged(object sender, EventArgs e) {
260      var handler = NameChanged;
261      if (handler != null) handler(sender, e);
262    }
263
264    public virtual event EventHandler<CancelEventArgs<string>> NameChanging;
265    protected virtual void OnNameChanging(object sender, CancelEventArgs<string> e) {
266      var handler = NameChanging;
267      if (handler != null) handler(sender, e);
268    }
269
270    public virtual event EventHandler DescriptionChanged;
271    protected virtual void OnDescriptionChanged(object sender, EventArgs e) {
272      var handler = DescriptionChanged;
273      if (handler != null) handler(sender, e);
274    }
275   
276    public virtual event EventHandler IsOptimizableChanged;
277    private void OnIsOptimizableChanged() {
278      var handler = IsOptimizableChanged;
279      if (handler != null) handler(this, EventArgs.Empty);
280    }
281
282    public virtual event EventHandler OptimizeChanged;
283    protected virtual void OnOptimizeChanged() {
284      var handler = OptimizeChanged;
285      if (handler != null) handler(this, EventArgs.Empty);
286    }
287    #endregion
288
289    public override string ToString() {
290      if (Optimize) {
291        return string.Format("{0}: (Optimize: {1})", ParameterName, ValueConfigurations.CheckedItems.Count());
292      } else {
293        return string.Format("{0}: {1}", ParameterName, ActualValue.Value);
294      }
295    }
296
297    public static IParameterConfiguration Create(IParameterizedNamedItem parent, IParameter parameter) {
298      if (parameter is IValueParameter) {
299        IValueParameter valueParameter = parameter as IValueParameter;
300        return new ParameterConfiguration(parameter.Name, valueParameter);
301      }
302      return null;
303    }
304
305    public void Parameterize(IValueParameter parameter) {
306      if (Optimize) {
307        if (this.ActualValue.Value is IParameterizedItem) {
308          this.ValueConfigurations.CheckedItems.ElementAt(actualValueConfigurationIndex).Parameterize((IParameterizedItem)this.ActualValue.Value);
309        }
310      }
311      parameter.Value = this.ActualValue.Value;
312    }
313
314    public void Randomize(IRandom random) {
315      if (Optimize) {
316        foreach (var vc in this.ValueConfigurations.CheckedItems) {
317          vc.Randomize(random);
318        }
319        actualValueConfigurationIndex = random.Next(ValueConfigurations.CheckedItems.Count());
320        this.ActualValue = this.ValueConfigurations.CheckedItems.ElementAt(actualValueConfigurationIndex).ActualValue;
321      }
322    }
323
324    public void Mutate(IRandom random) {
325      if (Optimize) {
326        foreach (IValueConfiguration vc in this.ValueConfigurations.CheckedItems) {
327          vc.Mutate(random);
328        }
329        actualValueConfigurationIndex = random.Next(ValueConfigurations.CheckedItems.Count());
330        this.ActualValue = this.ValueConfigurations.CheckedItems.ElementAt(actualValueConfigurationIndex).ActualValue;
331      }
332    }
333
334    public void Cross(IOptimizable other, IRandom random) {
335      if (Optimize) {
336        IParameterConfiguration otherPc = (IParameterConfiguration)other;
337        for (int i = 0; i < this.ValueConfigurations.Count; i++) {
338          this.ValueConfigurations.ElementAt(i).Cross(otherPc.ValueConfigurations.ElementAt(i), random);
339        }
340        if (random.NextDouble() > 0.5) {
341          actualValueConfigurationIndex = ((ParameterConfiguration)other).actualValueConfigurationIndex;
342        }
343        this.ActualValue = this.ValueConfigurations.CheckedItems.ElementAt(actualValueConfigurationIndex).ActualValue;
344      }
345    }
346  }
347}
Note: See TracBrowser for help on using the repository browser.