Free cookie consent management tool by TermsFeed Policy Generator

source: addons/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurations/ParameterConfiguration.cs @ 18242

Last change on this file since 18242 was 16996, checked in by gkronber, 6 years ago

#2520 Update plugin dependencies and references for HL.MetaOptimization for new persistence

File size: 26.6 KB
Line 
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Drawing;
5using System.Linq;
6using System.Text;
7using HeuristicLab.Collections;
8using HeuristicLab.Common;
9using HeuristicLab.Core;
10using HeuristicLab.Data;
11using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
12using HeuristicLab.Parameters;
13using HeuristicLab.PluginInfrastructure;
14using HEAL.Attic;
15
16namespace HeuristicLab.Problems.MetaOptimization {
17  [StorableType("8B47B960-3147-42AE-8AEC-C485D6A455F6")]
18  public class ParameterConfiguration : Item, IParameterConfiguration, IStorableContent {
19    public bool IsOptimizable {
20      get { return true; }
21    }
22
23    public string Filename { get; set; }
24
25    [Storable]
26    protected bool optimize;
27    public virtual bool Optimize {
28      get { return optimize; }
29      set {
30        if (optimize != value) {
31          optimize = value;
32          if (optimize) {
33            PopulateValueConfigurations();
34          } else {
35            ClearValueConfigurations();
36          }
37          OnOptimizeChanged();
38          OnToStringChanged();
39        }
40      }
41    }
42
43    [Storable]
44    protected Image itemImage;
45    public override Image ItemImage {
46      get { return itemImage ?? base.ItemImage; }
47    }
48
49    [Storable]
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
67    protected Type[] validTypes;
68    public Type[] ValidTypes {
69      get { return validTypes; }
70      protected set {
71        if (this.validTypes != value) {
72          this.validTypes = value;
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]
85    protected ICheckedValueConfigurationList valueConfigurations;
86    public ICheckedValueConfigurationList ValueConfigurations {
87      get { return this.valueConfigurations; }
88      protected set {
89        if (this.valueConfigurations != value) {
90          if (this.valueConfigurations != null) DeregisterValueConfigurationEvents();
91          this.valueConfigurations = value;
92          KeepActualValueConfigurationIndexConsistent();
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
129    [Storable]
130    protected bool discoverValidValues;
131    public bool DiscoverValidValues {
132      get { return discoverValidValues; }
133      set { discoverValidValues = value; }
134    }
135
136    protected IItemSet<IItem> validValues;
137
138    [Storable]
139    private bool autoPopulateValueConfigurations = true;
140    public bool AutoPopulateValueConfigurations {
141      get { return autoPopulateValueConfigurations; }
142      set { autoPopulateValueConfigurations = value; }
143    }
144
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    }
158
159    #region Constructors and Cloning
160    public ParameterConfiguration(string parameterName, IValueParameter valueParameter, bool discoverValidValues) {
161      this.AutoPopulateValueConfigurations = true;
162      this.ParameterName = parameterName;
163      this.parameterDataType = valueParameter.GetType();
164      this.valueDataType = valueParameter.DataType;
165      this.discoverValidValues = discoverValidValues;
166      this.validValues = discoverValidValues ? GetValidValues(valueParameter) : new ItemSet<IItem> { valueParameter.Value };
167      this.validTypes = GetValidTypes(valueParameter).ToArray();
168      this.IsNullable = valueParameter.ItemName.StartsWith("Optional");
169      this.itemImage = valueParameter.ItemImage;
170      if (IsNullable) {
171        validTypes = new List<Type>(validTypes) { typeof(NullValue) }.ToArray();
172      }
173      this.ValueConfigurations = new CheckedValueConfigurationList(this.validValues ?? CreateValidValues());
174      this.ActualValue = new ConstrainedValue(
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
176        valueParameter.DataType,
177        this.validValues != null ? new ItemSet<IItem>(this.validValues) : CreateValidValues(),
178        this.IsNullable);
179      if (Optimize) {
180        PopulateValueConfigurations();
181      }
182    }
183    public ParameterConfiguration(string parameterName, Type type, IItem actualValue, IEnumerable<IValueConfiguration> valueConfigurations) {
184      this.AutoPopulateValueConfigurations = false;
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) {
197      this.AutoPopulateValueConfigurations = true;
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    }
212    protected ParameterConfiguration() { }
213    [StorableConstructor]
214    protected ParameterConfiguration(StorableConstructorFlag _) { }
215
216    protected ParameterConfiguration(ParameterConfiguration original, Cloner cloner)
217      : base(original, cloner) {
218      this.parameterName = original.ParameterName;
219      this.parameterDataType = original.parameterDataType;
220      this.valueDataType = original.ValueDataType;
221      this.validValues = cloner.Clone(original.validValues);
222      this.validTypes = original.validTypes.ToArray();
223      this.valueConfigurations = cloner.Clone(original.ValueConfigurations);
224      if (this.valueConfigurations != null) RegisterValueConfigurationEvents();
225      this.actualValue = cloner.Clone(original.actualValue);
226      if (this.actualValue != null) RegisterActualValueEvents();
227      this.optimize = original.optimize;
228      this.actualValueConfigurationIndex = original.actualValueConfigurationIndex;
229      this.isNullable = original.isNullable;
230      this.itemImage = original.itemImage;
231      this.discoverValidValues = original.discoverValidValues;
232      this.AutoPopulateValueConfigurations = original.AutoPopulateValueConfigurations;
233      this.valuesReadOnly = original.valuesReadOnly;
234    }
235
236    public override IDeepCloneable Clone(Cloner cloner) {
237      return new ParameterConfiguration(this, cloner);
238    }
239    [StorableHook(HookType.AfterDeserialization)]
240    protected virtual void AfterDeserialization() {
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
248      if (this.valueConfigurations != null) RegisterValueConfigurationEvents();
249      if (this.actualValue != null) RegisterActualValueEvents();
250    }
251    #endregion
252
253    private void RegisterValueConfigurationEvents() {
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);
257    }
258
259    private void DeregisterValueConfigurationEvents() {
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);
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    }
271
272    protected virtual void PopulateValueConfigurations() {
273      if (!this.AutoPopulateValueConfigurations)
274        return;
275
276      foreach (Type t in this.validTypes) {
277        if (t == typeof(NullValue)) {
278          this.ValueConfigurations.Add(new NullValueConfiguration());
279        } else {
280          IItem val;
281          if (ActualValue.Value != null && ActualValue.Value.GetType() == t) {
282            val = (IItem)ActualValue.Value.Clone(); // use existing value for that type (if available)
283          } else {
284            val = CreateItem(t);
285          }
286          if (val != null) { // val can be null when ValidValues does not contain the type (this can happen when discoverValidValues=false)
287            IValueConfiguration valueConfiguration;
288            if (val is IParameterizedItem) {
289              valueConfiguration = new ParameterizedValueConfiguration(val, val.GetType(), true);
290            } else {
291              if (val is ISymbolicExpressionGrammar) {
292                valueConfiguration = new SymbolicExpressionGrammarValueConfiguration((ISymbolicExpressionGrammar)val);
293              } else {
294                valueConfiguration = new RangeValueConfiguration(val, val.GetType());
295              }
296            }
297            this.ValueConfigurations.Add(valueConfiguration, true);
298          }
299        }
300      }
301    }
302
303    protected virtual void ClearValueConfigurations() {
304      if (!this.AutoPopulateValueConfigurations)
305        return;
306
307      this.ValueConfigurations.Clear();
308    }
309
310    private static IEnumerable<Type> GetValidTypes(IValueParameter parameter) {
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
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))
317        return new List<Type> { parameter.DataType };
318
319      if (IsSubclassOfRawGeneric(typeof(OptionalConstrainedValueParameter<>), parameter.GetType())) {
320        // use existing validvalues if known
321        var parameterValidValues = (IEnumerable)parameter.GetType().GetProperty("ValidValues").GetValue(parameter, new object[] { });
322        return parameterValidValues.Cast<object>().Select(x => x.GetType());
323      } else {
324        // otherwise use all assignable types
325        return ApplicationManager.Manager.GetTypes(parameter.DataType, true);
326      }
327    }
328
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
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[] { });
352        return new ItemSet<IItem>(x.Cast<IItem>().Select(y => (IItem)y.Clone())); // cloning actually saves memory, because references to event-subscribers are removed
353      } else {
354        return null;
355      }
356    }
357
358    public IItem CreateItem(Type type) {
359      // no valid values; just instantiate
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      }
367
368      if (type == typeof(NullValue))
369        return new NullValue();
370
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();
373      if (value != null)
374        return value;
375
376      return null;
377    }
378
379    private IItemSet<IItem> CreateValidValues() {
380      var validValues = new ItemSet<IItem>();
381      foreach (Type t in this.validTypes) {
382        try {
383          var val = CreateItem(t);
384          if (val != null) validValues.Add(val);
385        }
386        catch (MissingMethodException) { /* Constructor is missing, don't use those types */ }
387      }
388      return validValues;
389    }
390
391    public static bool IsSubclassOfRawGeneric(Type generic, Type toCheck) {
392      while (toCheck != typeof(object)) {
393        var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
394        if (generic == cur) {
395          return true;
396        }
397        toCheck = toCheck.BaseType; // baseType is null when toCheck is an Interface
398        if (toCheck == null)
399          return false;
400      }
401      return false;
402    }
403
404    private void ValueConfigurations_CheckedItemsChanged(object sender, Collections.CollectionItemsChangedEventArgs<IndexedItem<IValueConfiguration>> e) {
405      OnToStringChanged();
406      KeepActualValueConfigurationIndexConsistent();
407    }
408
409    private void ValueConfigurations_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs<IndexedItem<IValueConfiguration>> e) {
410      OnToStringChanged();
411      KeepActualValueConfigurationIndexConsistent();
412    }
413    private void ValueConfigurations_ItemsAdded(object sender, Collections.CollectionItemsChangedEventArgs<IndexedItem<IValueConfiguration>> e) {
414      OnToStringChanged();
415      KeepActualValueConfigurationIndexConsistent();
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
442    protected virtual void ActualValue_ToStringChanged(object sender, EventArgs e) {
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    }
465
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
487    public virtual string ParameterInfoString {
488      get {
489        StringBuilder sb = new StringBuilder();
490        if (this.Optimize) {
491          var vc = this.ValueConfigurations[actualValueConfigurationIndex];
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())) {
495            // for int, double, bool use the value directly
496            sb.Append(string.Format("{0}: {1}", parameterName, this.ActualValue.Value.ToString()));
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          }
501
502          if (this.ValueConfigurations[actualValueConfigurationIndex] is ParameterizedValueConfiguration) {
503            string subParams = this.ValueConfigurations[actualValueConfigurationIndex].ParameterInfoString;
504            if (!string.IsNullOrEmpty(subParams)) {
505              sb.Append(" (");
506              sb.Append(subParams);
507              sb.Append(")");
508            }
509          }
510        }
511        return sb.ToString();
512      }
513    }
514
515    public static IParameterConfiguration Create(IParameterizedNamedItem parent, IParameter parameter, bool discoverValidValues) {
516      if (parameter is IValueParameter) {
517        IValueParameter valueParameter = parameter as IValueParameter;
518        return new ParameterConfiguration(parameter.Name, valueParameter, discoverValidValues);
519      }
520      return null;
521    }
522
523    public void Parameterize(IValueParameter parameter) {
524      if (!Optimize && ValuesReadOnly)
525        return;
526
527      if (Optimize) {
528        if (this.ActualValue.Value is IParameterizedItem) {
529          ((ParameterizedValueConfiguration)this.ValueConfigurations[actualValueConfigurationIndex]).Parameterize((IParameterizedItem)this.ActualValue.Value);
530        }
531        if (this.ActualValue.Value is ISymbolicExpressionGrammar) {
532          ((SymbolicExpressionGrammarValueConfiguration)this.ValueConfigurations[actualValueConfigurationIndex]).Parameterize((ISymbolicExpressionGrammar)this.ActualValue.Value);
533        }
534      }
535      var clonedValue = this.ActualValue.Value != null ? (IItem)this.ActualValue.Value.Clone() : null;
536      if (clonedValue != null) AdaptValidValues(parameter, clonedValue);
537      parameter.Value = clonedValue;
538    }
539
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
557    public void Randomize(IRandom random) {
558      if (Optimize) {
559        foreach (var vc in this.ValueConfigurations) {
560          if (this.ValueConfigurations.ItemChecked(vc)) {
561            if (vc.Optimize) vc.Randomize(random);
562          }
563        }
564        do {
565          actualValueConfigurationIndex = random.Next(ValueConfigurations.Count());
566        } while (!this.ValueConfigurations.ItemChecked(this.ValueConfigurations[actualValueConfigurationIndex]));
567        this.ActualValue = this.ValueConfigurations[actualValueConfigurationIndex].ActualValue;
568      }
569    }
570
571    public void Mutate(IRandom random, MutateDelegate mutate, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator) {
572      if (Optimize) {
573        foreach (var vc in this.ValueConfigurations) {
574          if (this.ValueConfigurations.ItemChecked(vc)) {
575            if (vc.Optimize) vc.Mutate(random, mutate, intValueManipulator, doubleValueManipulator);
576          }
577        }
578        mutate(random, this, intValueManipulator, doubleValueManipulator);
579      }
580    }
581
582    public void Cross(IRandom random, IOptimizable other, CrossDelegate cross, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover) {
583      if (Optimize) {
584        IParameterConfiguration otherPc = (IParameterConfiguration)other;
585        for (int i = 0; i < this.ValueConfigurations.Count; i++) {
586          if (this.ValueConfigurations.ItemChecked(this.ValueConfigurations[i])) {
587            if (this.ValueConfigurations[i].Optimize) this.ValueConfigurations[i].Cross(random, otherPc.ValueConfigurations[i], cross, intValueCrossover, doubleValueCrossover);
588          }
589        }
590        cross(random, this, other, intValueCrossover, doubleValueCrossover);
591      }
592    }
593
594    public void UpdateActualValueIndexToItem(IValueConfiguration vc) {
595      for (int i = 0; i < this.ValueConfigurations.Count(); i++) {
596        if (this.ValueConfigurations.ElementAt(i) == vc) {
597          this.actualValueConfigurationIndex = i;
598          return;
599        }
600      }
601    }
602
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    }
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    }
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    }
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) {
637        if (this.valueConfigurations.Count <= this.actualValueConfigurationIndex &&
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    }
649  }
650}
Note: See TracBrowser for help on using the repository browser.