using System; using System.Collections.Generic; using System.Drawing; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Problems.MetaOptimization { // TODO: ItemName/Descr, storability [StorableClass] public abstract class ValueConfiguration : NamedItem, IValueConfiguration { [Storable] protected bool isOptimizable; public virtual bool IsOptimizable { get { return isOptimizable; } set { if (this.isOptimizable != value) { this.isOptimizable = value; OnIsOptimizableChanged(); } } } [Storable] protected bool optimize; public virtual bool Optimize { get { return optimize; } set { if (optimize != value) { if (value == true && !this.IsOptimizable) throw new NotSupportedException("This value is not optimizable."); optimize = value; OnOptimizeChanged(); OnToStringChanged(); } } } [Storable] protected ConstrainedValue actualValue; public virtual ConstrainedValue ActualValue { get { return actualValue; } set { if (this.actualValue != value) { DeregisterActualValueEvents(); this.actualValue = value; OnValueChanged(); OnToStringChanged(); RegisterActualValueEvents(); } } } [Storable] protected int number = 0; public int Number { get { return number; } set { if (value != number) { number = value; OnToStringChanged(); } } } [Storable] protected bool valuesReadOnly = false; public virtual bool ValuesReadOnly { get { return valuesReadOnly; } set { if (value != this.valuesReadOnly) { this.valuesReadOnly = value; } } } #region Constructors and Cloning protected ValueConfiguration(IItem value, Type valueDataType) { this.ActualValue = new ConstrainedValue(value, valueDataType, new ItemSet { value }, false); this.IsOptimizable = true; this.Name = value == null ? "ValueConfiguration" : value.ItemName; } protected ValueConfiguration() { } [StorableConstructor] protected ValueConfiguration(bool deserializing) { } protected ValueConfiguration(ValueConfiguration original, Cloner cloner) : base(original, cloner) { this.actualValue = cloner.Clone(original.ActualValue); this.isOptimizable = original.isOptimizable; this.optimize = original.optimize; this.number = original.number; this.valuesReadOnly = original.valuesReadOnly; RegisterActualValueEvents(); } #endregion private void RegisterActualValueEvents() { if (this.actualValue != null) this.actualValue.ToStringChanged += new EventHandler(actualValue_ToStringChanged); } private void DeregisterActualValueEvents() { if (this.actualValue != null) this.actualValue.ToStringChanged -= new EventHandler(actualValue_ToStringChanged); } #region Events private void actualValue_ToStringChanged(object sender, EventArgs e) { OnToStringChanged(); } #endregion #region IItem Members public override string ItemDescription { get { return (actualValue != null && actualValue.Value != null) ? actualValue.Value.ItemDescription : base.ItemDescription; } } public override Image ItemImage { get { return (actualValue != null && actualValue.Value != null) ? actualValue.Value.ItemImage : base.ItemImage; } } public override string ItemName { get { return (actualValue != null && actualValue.Value != null) ? actualValue.Value.ItemDescription : base.ItemName; } } #endregion #region Event Handlers public virtual event EventHandler ValueChanged; protected virtual void OnValueChanged() { var handler = ValueChanged; if (handler != null) handler(this, EventArgs.Empty); } public virtual event EventHandler IsOptimizableChanged; private void OnIsOptimizableChanged() { var handler = IsOptimizableChanged; if (handler != null) handler(this, EventArgs.Empty); } public virtual event EventHandler OptimizeChanged; protected virtual void OnOptimizeChanged() { var handler = OptimizeChanged; if (handler != null) handler(this, EventArgs.Empty); } #endregion public string NumberedName { get { if (this.number == 0) { return (ActualValue != null && ActualValue.Value != null) ? ActualValue.Value.ItemName : base.ToString(); } else { return string.Format("{0} {1}", ActualValue.Value.ItemName, number); } } } public abstract void Randomize(IRandom random); public abstract void Mutate(IRandom random, MutateDelegate mutate, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator); public abstract void Cross(IRandom random, IOptimizable other, CrossDelegate cross, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover); public abstract double CalculateSimilarity(IOptimizable optimizable); public abstract string ParameterInfoString { get; } public abstract void CollectOptimizedParameterNames(List parameterNames, string prefix); public abstract List GetAllOptimizables(); } }