Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 13067 was 8087, checked in by mkommend, 13 years ago

#1877: Corrected plugin dependencies and ToString methods in MetaOpt.

File size: 26.6 KB
RevLine 
[5112]1using System;
2using System.Collections;
3using System.Collections.Generic;
[5653]4using System.Drawing;
[5112]5using System.Linq;
[5653]6using System.Text;
7using HeuristicLab.Collections;
[5112]8using HeuristicLab.Common;
9using HeuristicLab.Core;
10using HeuristicLab.Data;
[5927]11using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
[5112]12using HeuristicLab.Parameters;
13using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
14using HeuristicLab.PluginInfrastructure;
15
16namespace HeuristicLab.Problems.MetaOptimization {
17  [StorableClass]
18  public class ParameterConfiguration : Item, IParameterConfiguration, IStorableContent {
[5207]19    public bool IsOptimizable {
20      get { return true; }
[5112]21    }
22
23    public string Filename { get; set; }
24
25    [Storable]
26    protected bool optimize;
[5927]27    public virtual bool Optimize {
[5112]28      get { return optimize; }
29      set {
30        if (optimize != value) {
31          optimize = value;
32          if (optimize) {
33            PopulateValueConfigurations();
34          } else {
[5927]35            ClearValueConfigurations();
[5112]36          }
37          OnOptimizeChanged();
38          OnToStringChanged();
39        }
40      }
41    }
42
43    [Storable]
[5927]44    protected Image itemImage;
45    public override Image ItemImage {
[5313]46      get { return itemImage ?? base.ItemImage; }
47    }
48
49    [Storable]
[5112]50    protected string parameterName;
51    public string ParameterName {
52      get { return parameterName; }
53      set {
54        if (parameterName != value) {
55          parameterName = value;
56          OnToStringChanged();
57        }
58      }
59    }
60
61    [Storable]
62    protected Type parameterDataType;
63    public Type ParameterDataType {
64      get { return this.parameterDataType; }
65    }
66
[5207]67    protected Type[] validTypes;
68    public Type[] ValidTypes {
69      get { return validTypes; }
[5112]70      protected set {
[5207]71        if (this.validTypes != value) {
72          this.validTypes = value;
[5112]73        }
74      }
75    }
76
77    [Storable]
78    protected Type valueDataType;
79    public Type ValueDataType {
80      get { return valueDataType; }
81      protected set { this.valueDataType = value; }
82    }
83
84    [Storable]
[5277]85    protected ICheckedValueConfigurationList valueConfigurations;
86    public ICheckedValueConfigurationList ValueConfigurations {
[5112]87      get { return this.valueConfigurations; }
88      protected set {
89        if (this.valueConfigurations != value) {
90          if (this.valueConfigurations != null) DeregisterValueConfigurationEvents();
91          this.valueConfigurations = value;
[6018]92          KeepActualValueConfigurationIndexConsistent();
[5112]93          if (this.valueConfigurations != null) RegisterValueConfigurationEvents();
94        }
95      }
96    }
97
98    [Storable]
99    private int actualValueConfigurationIndex = 0;
100    public int ActualValueConfigurationIndex {
101      get { return actualValueConfigurationIndex; }
102      set { actualValueConfigurationIndex = value; }
103    }
104
105    [Storable]
106    protected ConstrainedValue actualValue;
107    public ConstrainedValue ActualValue {
108      get { return actualValue; }
109      set {
110        if (actualValue != value) {
111          DeregisterActualValueEvents();
112          actualValue = value;
113          RegisterActualValueEvents();
114        }
115      }
116    }
117
118    [Storable]
119    protected bool isNullable;
120    public bool IsNullable {
121      get { return isNullable; }
122      protected set {
123        if (this.isNullable != value) {
124          this.isNullable = value;
125        }
126      }
127    }
128
[5267]129    [Storable]
[5665]130    protected bool discoverValidValues;
131    public bool DiscoverValidValues {
132      get { return discoverValidValues; }
133      set { discoverValidValues = value; }
134    }
135
[5231]136    protected IItemSet<IItem> validValues;
137
[6017]138    [Storable]
139    private bool autoPopulateValueConfigurations = true;
140    public bool AutoPopulateValueConfigurations {
141      get { return autoPopulateValueConfigurations; }
142      set { autoPopulateValueConfigurations = value; }
143    }
144
[6489]145    [Storable]
146    protected bool valuesReadOnly = false;
147    public virtual bool ValuesReadOnly {
148      get { return valuesReadOnly; }
149      set {
150        if (value != this.valuesReadOnly) {
151          this.valuesReadOnly = value;
152          foreach (var vc in this.valueConfigurations) {
153            vc.ValuesReadOnly = value;
154          }
155        }
156      }
157    }
[6018]158
[5112]159    #region Constructors and Cloning
[5665]160    public ParameterConfiguration(string parameterName, IValueParameter valueParameter, bool discoverValidValues) {
[6017]161      this.AutoPopulateValueConfigurations = true;
[5112]162      this.ParameterName = parameterName;
163      this.parameterDataType = valueParameter.GetType();
164      this.valueDataType = valueParameter.DataType;
[5665]165      this.discoverValidValues = discoverValidValues;
166      this.validValues = discoverValidValues ? GetValidValues(valueParameter) : new ItemSet<IItem> { valueParameter.Value };
[5207]167      this.validTypes = GetValidTypes(valueParameter).ToArray();
[5112]168      this.IsNullable = valueParameter.ItemName.StartsWith("Optional");
[5313]169      this.itemImage = valueParameter.ItemImage;
[5112]170      if (IsNullable) {
[5207]171        validTypes = new List<Type>(validTypes) { typeof(NullValue) }.ToArray();
[5112]172      }
[5313]173      this.ValueConfigurations = new CheckedValueConfigurationList(this.validValues ?? CreateValidValues());
[5267]174      this.ActualValue = new ConstrainedValue(
[5361]175        valueParameter.Value != null ? valueParameter.Value : null, // don't clone here; otherwise settings of a non-optimized ValueParameter will not be synchronized with the ConstrainedValue
[5653]176        valueParameter.DataType,
177        this.validValues != null ? new ItemSet<IItem>(this.validValues) : CreateValidValues(),
[5267]178        this.IsNullable);
[5112]179      if (Optimize) {
180        PopulateValueConfigurations();
181      }
182    }
[5927]183    public ParameterConfiguration(string parameterName, Type type, IItem actualValue, IEnumerable<IValueConfiguration> valueConfigurations) {
[6017]184      this.AutoPopulateValueConfigurations = false;
[5927]185      this.ParameterName = parameterName;
186      this.parameterDataType = type;
187      this.valueDataType = type;
188      this.discoverValidValues = false;
189      this.validValues = null; // maybe use values from valueConfigurations
190      this.validTypes = new Type[] { type };
191      this.IsNullable = false;
192      this.itemImage = valueConfigurations.Count() > 0 ? valueConfigurations.FirstOrDefault().ItemImage : null;
193      this.ValueConfigurations = new CheckedValueConfigurationList(valueConfigurations);
194      this.ActualValue = new ConstrainedValue(actualValue, type, CreateValidValues(), this.IsNullable);
195    }
196    public ParameterConfiguration(string parameterName, Type type, IItem actualValue) {
[6017]197      this.AutoPopulateValueConfigurations = true;
[5927]198      this.ParameterName = parameterName;
199      this.parameterDataType = type;
200      this.valueDataType = type;
201      this.discoverValidValues = false;
202      this.validValues = null;
203      this.validTypes = new Type[] { type };
204      this.IsNullable = false;
205      this.itemImage = actualValue.ItemImage;
206      this.ValueConfigurations = new CheckedValueConfigurationList();
207      this.ActualValue = new ConstrainedValue(actualValue, type, CreateValidValues(), this.IsNullable);
208      if (Optimize) {
209        PopulateValueConfigurations();
210      }
211    }
[8087]212    protected ParameterConfiguration() { }
[5112]213    [StorableConstructor]
214    protected ParameterConfiguration(bool deserializing) { }
[7153]215
[5207]216    protected ParameterConfiguration(ParameterConfiguration original, Cloner cloner)
217      : base(original, cloner) {
[5112]218      this.parameterName = original.ParameterName;
219      this.parameterDataType = original.parameterDataType;
220      this.valueDataType = original.ValueDataType;
[5231]221      this.validValues = cloner.Clone(original.validValues);
[5207]222      this.validTypes = original.validTypes.ToArray();
[5112]223      this.valueConfigurations = cloner.Clone(original.ValueConfigurations);
[6197]224      if (this.valueConfigurations != null) RegisterValueConfigurationEvents();
225      this.actualValue = cloner.Clone(original.actualValue);
226      if (this.actualValue != null) RegisterActualValueEvents();
[5112]227      this.optimize = original.optimize;
228      this.actualValueConfigurationIndex = original.actualValueConfigurationIndex;
229      this.isNullable = original.isNullable;
[5313]230      this.itemImage = original.itemImage;
[5665]231      this.discoverValidValues = original.discoverValidValues;
[6017]232      this.AutoPopulateValueConfigurations = original.AutoPopulateValueConfigurations;
[6489]233      this.valuesReadOnly = original.valuesReadOnly;
[5112]234    }
[5927]235
[5112]236    public override IDeepCloneable Clone(Cloner cloner) {
237      return new ParameterConfiguration(this, cloner);
238    }
239    [StorableHook(HookType.AfterDeserialization)]
[6197]240    protected virtual void AfterDeserialization() {
[7153]241      this.validTypes = GetValidTypes(parameterDataType).ToArray();
242
243      if (IsNullable) {
244        validTypes = new List<Type>(validTypes) { typeof(NullValue) }.ToArray();
245      }
246      this.validValues = CreateValidValues();
247
[5112]248      if (this.valueConfigurations != null) RegisterValueConfigurationEvents();
[6197]249      if (this.actualValue != null) RegisterActualValueEvents();
[5112]250    }
251    #endregion
252
253    private void RegisterValueConfigurationEvents() {
[5277]254      this.ValueConfigurations.CheckedItemsChanged += new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(ValueConfigurations_CheckedItemsChanged);
255      this.ValueConfigurations.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(ValueConfigurations_ItemsAdded);
256      this.ValueConfigurations.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(ValueConfigurations_ItemsRemoved);
[5112]257    }
258
259    private void DeregisterValueConfigurationEvents() {
[5277]260      this.ValueConfigurations.CheckedItemsChanged -= new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(ValueConfigurations_CheckedItemsChanged);
261      this.ValueConfigurations.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(ValueConfigurations_ItemsAdded);
262      this.ValueConfigurations.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(ValueConfigurations_ItemsRemoved);
[5112]263    }
264
265    private void RegisterActualValueEvents() {
266      if (this.ActualValue != null) this.ActualValue.ToStringChanged += new EventHandler(ActualValue_ToStringChanged);
267    }
268    private void DeregisterActualValueEvents() {
269      if (this.ActualValue != null) this.ActualValue.ToStringChanged -= new EventHandler(ActualValue_ToStringChanged);
270    }
[5653]271
[5927]272    protected virtual void PopulateValueConfigurations() {
[6017]273      if (!this.AutoPopulateValueConfigurations)
274        return;
275
[5207]276      foreach (Type t in this.validTypes) {
277        if (t == typeof(NullValue)) {
[5112]278          this.ValueConfigurations.Add(new NullValueConfiguration());
279        } else {
[5267]280          IItem val;
[6018]281          if (ActualValue.Value != null && ActualValue.Value.GetType() == t) {
[5267]282            val = (IItem)ActualValue.Value.Clone(); // use existing value for that type (if available)
283          } else {
284            val = CreateItem(t);
285          }
[5665]286          if (val != null) { // val can be null when ValidValues does not contain the type (this can happen when discoverValidValues=false)
[5927]287            IValueConfiguration valueConfiguration;
[5665]288            if (val is IParameterizedItem) {
[5927]289              valueConfiguration = new ParameterizedValueConfiguration(val, val.GetType(), true);
[5665]290            } else {
[5927]291              if (val is ISymbolicExpressionGrammar) {
292                valueConfiguration = new SymbolicExpressionGrammarValueConfiguration((ISymbolicExpressionGrammar)val);
293              } else {
294                valueConfiguration = new RangeValueConfiguration(val, val.GetType());
295              }
[5665]296            }
[5927]297            this.ValueConfigurations.Add(valueConfiguration, true);
[5653]298          }
[5112]299        }
300      }
301    }
302
[5927]303    protected virtual void ClearValueConfigurations() {
[6017]304      if (!this.AutoPopulateValueConfigurations)
305        return;
306
[5927]307      this.ValueConfigurations.Clear();
308    }
309
[5337]310    private static IEnumerable<Type> GetValidTypes(IValueParameter parameter) {
[5267]311      // in case of IOperator return empty list, otherwise hundreds of types would be returned. this mostly occurs for Successor which will never be optimized
312      if (parameter.DataType == typeof(IOperator))
313        return new List<Type>();
314
[5337]315      // return only one type for ValueTypeValues<> (Int, Double, Percent, Bool). Otherwise 2 types would be returned for DoubleValue (PercentValue which is derived)
316      if (IsSubclassOfRawGeneric(typeof(ValueTypeValue<>), parameter.DataType))
[5653]317        return new List<Type> { parameter.DataType };
318
[5231]319      if (IsSubclassOfRawGeneric(typeof(OptionalConstrainedValueParameter<>), parameter.GetType())) {
[5337]320        // use existing validvalues if known
[5231]321        var parameterValidValues = (IEnumerable)parameter.GetType().GetProperty("ValidValues").GetValue(parameter, new object[] { });
322        return parameterValidValues.Cast<object>().Select(x => x.GetType());
323      } else {
[5337]324        // otherwise use all assignable types
325        return ApplicationManager.Manager.GetTypes(parameter.DataType, true);
[5231]326      }
[5112]327    }
328
[7153]329    private static IEnumerable<Type> GetValidTypes(Type parameter) {
330      // in case of IOperator return empty list, otherwise hundreds of types would be returned. this mostly occurs for Successor which will never be optimized
331      if (parameter == typeof(IOperator))
332        return new List<Type>();
333
334      // return only one type for ValueTypeValues<> (Int, Double, Percent, Bool). Otherwise 2 types would be returned for DoubleValue (PercentValue which is derived)
335      if (IsSubclassOfRawGeneric(typeof(ValueTypeValue<>), parameter))
336        return new List<Type> { parameter };
337
338      //TODO: not sure if this if makes sense; maybe only leave else branch here
339      if (IsSubclassOfRawGeneric(typeof(OptionalConstrainedValueParameter<>), parameter.GetType())) {
340        // use existing validvalues if known
341        var parameterValidValues = (IEnumerable)parameter.GetType().GetProperty("ValidValues").GetValue(parameter, new object[] { });
342        return parameterValidValues.Cast<object>().Select(x => x.GetType());
343      } else {
344        // otherwise use all assignable types
345        return ApplicationManager.Manager.GetTypes(parameter, true);
346      }
347    }
348
[5231]349    private IItemSet<IItem> GetValidValues(IValueParameter parameter) {
350      if (IsSubclassOfRawGeneric(typeof(OptionalConstrainedValueParameter<>), parameter.GetType())) {
351        var x = (IEnumerable)parameter.GetType().GetProperty("ValidValues").GetValue(parameter, new object[] { });
[5267]352        return new ItemSet<IItem>(x.Cast<IItem>().Select(y => (IItem)y.Clone())); // cloning actually saves memory, because references to event-subscribers are removed
[5231]353      } else {
354        return null;
355      }
356    }
357
358    public IItem CreateItem(Type type) {
359      // no valid values; just instantiate
[5927]360      try {
361        if (validValues == null)
362          return (IItem)Activator.CreateInstance(type);
363      }
364      catch (MissingMemberException) {
365        return null; // can happen, when ApplicationManager.Manager.GetTypes(type, OnlyInstantiable=true) returns objects which have no default constructor
366      }
[5231]367
368      if (type == typeof(NullValue))
369        return new NullValue();
[5653]370
[5231]371      // copy value from ValidValues; this ensures that previously set ActualNames for a type are kept
372      IItem value = this.validValues.Where(v => v.GetType() == type).SingleOrDefault();
[5653]373      if (value != null)
[5267]374        return value;
[5231]375
376      return null;
377    }
378
[5313]379    private IItemSet<IItem> CreateValidValues() {
[5231]380      var validValues = new ItemSet<IItem>();
381      foreach (Type t in this.validTypes) {
[5267]382        try {
383          var val = CreateItem(t);
[5927]384          if (val != null) validValues.Add(val);
[5267]385        }
386        catch (MissingMethodException) { /* Constructor is missing, don't use those types */ }
[5231]387      }
388      return validValues;
389    }
390
[6445]391    public static bool IsSubclassOfRawGeneric(Type generic, Type toCheck) {
[5112]392      while (toCheck != typeof(object)) {
393        var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
394        if (generic == cur) {
395          return true;
396        }
[5337]397        toCheck = toCheck.BaseType; // baseType is null when toCheck is an Interface
398        if (toCheck == null)
399          return false;
[5112]400      }
401      return false;
402    }
403
[6421]404    private void ValueConfigurations_CheckedItemsChanged(object sender, Collections.CollectionItemsChangedEventArgs<IndexedItem<IValueConfiguration>> e) {
[5112]405      OnToStringChanged();
[6018]406      KeepActualValueConfigurationIndexConsistent();
[5112]407    }
[6018]408
[6421]409    private void ValueConfigurations_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs<IndexedItem<IValueConfiguration>> e) {
[5112]410      OnToStringChanged();
[6018]411      KeepActualValueConfigurationIndexConsistent();
[5112]412    }
[6421]413    private void ValueConfigurations_ItemsAdded(object sender, Collections.CollectionItemsChangedEventArgs<IndexedItem<IValueConfiguration>> e) {
[5112]414      OnToStringChanged();
[6018]415      KeepActualValueConfigurationIndexConsistent();
[5112]416    }
417
418    #region INamedItem Properties
419    public virtual string Name {
420      get { return ParameterName; }
421      set { throw new NotSupportedException(); }
422    }
423    public virtual string Description {
424      get { return base.ItemDescription; }
425      set { throw new NotSupportedException(); }
426    }
427    public virtual bool CanChangeDescription {
428      get { return false; }
429    }
430    public virtual bool CanChangeName {
431      get { return false; }
432    }
433    public override string ItemDescription {
434      get { return base.ItemDescription; }
435    }
436    public override string ItemName {
437      get { return base.ItemName; }
438    }
439    #endregion
440
441    #region Events
[6197]442    protected virtual void ActualValue_ToStringChanged(object sender, EventArgs e) {
[5112]443      OnToStringChanged();
444    }
445    #endregion
446
447    #region Event Handler
448    public virtual event EventHandler NameChanged;
449    protected virtual void OnNameChanged(object sender, EventArgs e) {
450      var handler = NameChanged;
451      if (handler != null) handler(sender, e);
452    }
453
454    public virtual event EventHandler<CancelEventArgs<string>> NameChanging;
455    protected virtual void OnNameChanging(object sender, CancelEventArgs<string> e) {
456      var handler = NameChanging;
457      if (handler != null) handler(sender, e);
458    }
459
460    public virtual event EventHandler DescriptionChanged;
461    protected virtual void OnDescriptionChanged(object sender, EventArgs e) {
462      var handler = DescriptionChanged;
463      if (handler != null) handler(sender, e);
464    }
[5207]465
[5112]466    public virtual event EventHandler IsOptimizableChanged;
467    private void OnIsOptimizableChanged() {
468      var handler = IsOptimizableChanged;
469      if (handler != null) handler(this, EventArgs.Empty);
470    }
471
472    public virtual event EventHandler OptimizeChanged;
473    protected virtual void OnOptimizeChanged() {
474      var handler = OptimizeChanged;
475      if (handler != null) handler(this, EventArgs.Empty);
476    }
477    #endregion
478
479    public override string ToString() {
480      if (Optimize) {
481        return string.Format("{0}: (Optimize: {1})", ParameterName, ValueConfigurations.CheckedItems.Count());
482      } else {
483        return string.Format("{0}: {1}", ParameterName, ActualValue.Value);
484      }
485    }
486
[6018]487    public virtual string ParameterInfoString {
[5184]488      get {
489        StringBuilder sb = new StringBuilder();
490        if (this.Optimize) {
[5359]491          var vc = this.ValueConfigurations[actualValueConfigurationIndex];
[5361]492          if (vc.ActualValue == null || vc.ActualValue.Value == null) {
493            sb.Append(string.Format("{0}: null", parameterName));
494          } else if (IsSubclassOfRawGeneric(typeof(ValueTypeValue<>), vc.ActualValue.Value.GetType())) {
[5359]495            // for int, double, bool use the value directly
[5361]496            sb.Append(string.Format("{0}: {1}", parameterName, this.ActualValue.Value.ToString()));
[5359]497          } else {
498            // for other types use NumberedName (this also uses the Number-Property for otherwise ambiguous ValueConfigurations)
499            sb.Append(string.Format("{0}: {1}", parameterName, vc.NumberedName));
500          }
[5184]501
[6018]502          if (this.ValueConfigurations[actualValueConfigurationIndex] is ParameterizedValueConfiguration) {
[5277]503            string subParams = this.ValueConfigurations[actualValueConfigurationIndex].ParameterInfoString;
[5184]504            if (!string.IsNullOrEmpty(subParams)) {
505              sb.Append(" (");
506              sb.Append(subParams);
507              sb.Append(")");
508            }
509          }
510        }
511        return sb.ToString();
[5144]512      }
513    }
514
[5665]515    public static IParameterConfiguration Create(IParameterizedNamedItem parent, IParameter parameter, bool discoverValidValues) {
[5112]516      if (parameter is IValueParameter) {
517        IValueParameter valueParameter = parameter as IValueParameter;
[5665]518        return new ParameterConfiguration(parameter.Name, valueParameter, discoverValidValues);
[5112]519      }
520      return null;
521    }
522
523    public void Parameterize(IValueParameter parameter) {
[6489]524      if (!Optimize && ValuesReadOnly)
525        return;
526
[5112]527      if (Optimize) {
528        if (this.ActualValue.Value is IParameterizedItem) {
[5653]529          ((ParameterizedValueConfiguration)this.ValueConfigurations[actualValueConfigurationIndex]).Parameterize((IParameterizedItem)this.ActualValue.Value);
[5112]530        }
[5927]531        if (this.ActualValue.Value is ISymbolicExpressionGrammar) {
532          ((SymbolicExpressionGrammarValueConfiguration)this.ValueConfigurations[actualValueConfigurationIndex]).Parameterize((ISymbolicExpressionGrammar)this.ActualValue.Value);
533        }
[5112]534      }
[5207]535      var clonedValue = this.ActualValue.Value != null ? (IItem)this.ActualValue.Value.Clone() : null;
[5665]536      if (clonedValue != null) AdaptValidValues(parameter, clonedValue);
[6421]537      parameter.Value = clonedValue;
[5112]538    }
539
[5207]540    /// <summary>
541    /// Adds value to the ValidValues of the parameter if they don't contain the value
542    /// </summary>
543    private void AdaptValidValues(IValueParameter parameter, IItem value) {
544      // this requires some tricky reflection, because the type is unknown at runtime so parameter.ValidValues cannot be casted to Collection<?>
545      if (IsSubclassOfRawGeneric(typeof(OptionalConstrainedValueParameter<>), parameter.GetType())) {
546        var validValues = parameter.GetType().GetProperty("ValidValues").GetValue(parameter, new object[] { });
547        Type validValuesType = validValues.GetType();
548
549        var containsMethod = validValuesType.GetMethod("Contains");
550        if (!(bool)containsMethod.Invoke(validValues, new object[] { value })) {
551          var addMethod = validValuesType.GetMethod("Add");
552          addMethod.Invoke(validValues, new object[] { value });
553        }
554      }
555    }
556
[5112]557    public void Randomize(IRandom random) {
558      if (Optimize) {
[5277]559        foreach (var vc in this.ValueConfigurations) {
560          if (this.ValueConfigurations.ItemChecked(vc)) {
[5653]561            if (vc.Optimize) vc.Randomize(random);
[5277]562          }
[5112]563        }
[5277]564        do {
565          actualValueConfigurationIndex = random.Next(ValueConfigurations.Count());
566        } while (!this.ValueConfigurations.ItemChecked(this.ValueConfigurations[actualValueConfigurationIndex]));
567        this.ActualValue = this.ValueConfigurations[actualValueConfigurationIndex].ActualValue;
[5112]568      }
569    }
570
[5277]571    public void Mutate(IRandom random, MutateDelegate mutate, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator) {
[5112]572      if (Optimize) {
[5277]573        foreach (var vc in this.ValueConfigurations) {
574          if (this.ValueConfigurations.ItemChecked(vc)) {
[5653]575            if (vc.Optimize) vc.Mutate(random, mutate, intValueManipulator, doubleValueManipulator);
[5277]576          }
[5112]577        }
[5277]578        mutate(random, this, intValueManipulator, doubleValueManipulator);
[5112]579      }
580    }
581
[5277]582    public void Cross(IRandom random, IOptimizable other, CrossDelegate cross, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover) {
[5112]583      if (Optimize) {
584        IParameterConfiguration otherPc = (IParameterConfiguration)other;
585        for (int i = 0; i < this.ValueConfigurations.Count; i++) {
[5277]586          if (this.ValueConfigurations.ItemChecked(this.ValueConfigurations[i])) {
[5653]587            if (this.ValueConfigurations[i].Optimize) this.ValueConfigurations[i].Cross(random, otherPc.ValueConfigurations[i], cross, intValueCrossover, doubleValueCrossover);
[5277]588          }
[5112]589        }
[5277]590        cross(random, this, other, intValueCrossover, doubleValueCrossover);
[5112]591      }
592    }
[5144]593
594    public void UpdateActualValueIndexToItem(IValueConfiguration vc) {
[5277]595      for (int i = 0; i < this.ValueConfigurations.Count(); i++) {
596        if (this.ValueConfigurations.ElementAt(i) == vc) {
[5144]597          this.actualValueConfigurationIndex = i;
598          return;
599        }
600      }
601    }
602
[5303]603    public List<IOptimizable> GetAllOptimizables() {
604      var list = new List<IOptimizable>();
605      foreach (var vc in ValueConfigurations) {
606        if (vc.Optimize) {
607          list.Add(vc);
608          list.AddRange(vc.GetAllOptimizables());
609        }
610      }
611      return list;
612    }
[5340]613
614    public void CollectOptimizedParameterNames(List<string> parameterNames, string prefix) {
615      foreach (var vc in ValueConfigurations) {
616        if (vc.Optimize) {
617          vc.CollectOptimizedParameterNames(parameterNames, prefix);
618        }
619      }
620    }
[5522]621
622    public double CalculateSimilarity(IOptimizable optimizable) {
623      var other = (IParameterConfiguration)optimizable;
624      if (this.ActualValueConfigurationIndex == other.ActualValueConfigurationIndex) {
625        return this.ValueConfigurations[this.ActualValueConfigurationIndex].CalculateSimilarity(other.ValueConfigurations[other.ActualValueConfigurationIndex]);
626      } else {
627        return 0.0;
628      }
629    }
[6018]630
631    /// <summary>
632    /// Ensures that the ActualValueConfigurationIndex has a valid value
633    /// Only indices of items which are checked are allowed
634    /// </summary>
635    private void KeepActualValueConfigurationIndexConsistent() {
636      if (this.valueConfigurations != null && this.valueConfigurations.CheckedItems.Count() > 0) {
[7153]637        if (this.valueConfigurations.Count <= this.actualValueConfigurationIndex &&
[6018]638           this.valueConfigurations.CheckedItems.Count(x => x.Index == this.actualValueConfigurationIndex) == 1) {
639          // everything is ok; do nothing
640        } else {
641          // current index is invalid, set new one
642          this.ActualValueConfigurationIndex = this.valueConfigurations.CheckedItems.First().Index;
643        }
644      } else {
645        // no checked valueConfiguration is available; cannot be used
646        this.ActualValueConfigurationIndex = -1;
647      }
648    }
[5112]649  }
650}
Note: See TracBrowser for help on using the repository browser.