Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurations/ParameterConfiguration.cs @ 5184

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

#1215

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