using System; using System.Collections.Generic; using System.Linq; using System.Text; using HeuristicLab.Core; using HeuristicLab.Common; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Optimization; using HeuristicLab.Data; using System.Collections; namespace HeuristicLab.Problems.MetaOptimization { // todo: storable, name, descr, ... [StorableClass] public class ParameterConfigurationTree : ValueConfiguration, IEnumerable { [Storable] private DoubleValue averageQualityNormalized; public DoubleValue AverageQualityNormalized { get { return averageQualityNormalized; } set { if (averageQualityNormalized != value) { averageQualityNormalized = value; OnQualityChanged(); } } } [Storable] private DoubleArray qualitiesNormalized; public DoubleArray QualitiesNormalized { get { return qualitiesNormalized; } set { if (qualitiesNormalized != value) { qualitiesNormalized = value; } } } [Storable] private DoubleArray bestQualities; public DoubleArray BestQualities { get { return bestQualities; } set { if (bestQualities != value) { bestQualities = value; } } } [Storable] private DoubleArray averageQualities; public DoubleArray AverageQualities { get { return averageQualities; } set { averageQualities = value; } } [Storable] private DoubleArray worstQualities; public DoubleArray WorstQualities { get { return worstQualities; } set { worstQualities = value; } } [Storable] private DoubleArray qualityVariances; public DoubleArray QualityVariances { get { return qualityVariances; } set { qualityVariances = value; } } [Storable] private DoubleArray qualityStandardDeviations; public DoubleArray QualityStandardDeviations { get { return qualityStandardDeviations; } set { qualityStandardDeviations = value; } } [Storable] private ItemList averageExecutionTimes; public ItemList AverageExecutionTimes { get { return averageExecutionTimes; } set { averageExecutionTimes = value; } } [Storable] private IntValue repetitions; public IntValue Repetitions { get { return repetitions; } set { repetitions = value; } } [Storable] protected RunCollection runs; public RunCollection Runs { get { return runs; } set { runs = value; } } [Storable] protected IDictionary parameters; public IDictionary Parameters { get { return parameters; } set { parameters = value; } } #region constructors and cloning public ParameterConfigurationTree(EngineAlgorithm algorithm) : base(null, algorithm.GetType()) { this.Optimize = true; // root must always be optimized this.parameters = new Dictionary(); PopulateParameterConfigurations(algorithm); } public ParameterConfigurationTree() { } [StorableConstructor] protected ParameterConfigurationTree(bool deserializing) : base(deserializing) { } protected ParameterConfigurationTree(ParameterConfigurationTree original, Cloner cloner) : base(original, cloner) { this.bestQualities = cloner.Clone(original.BestQualities); this.averageQualities = cloner.Clone(original.averageQualities); this.worstQualities = cloner.Clone(original.worstQualities); this.qualityStandardDeviations = cloner.Clone(original.qualityStandardDeviations); this.qualityVariances = cloner.Clone(original.qualityVariances); this.averageExecutionTimes = cloner.Clone(original.averageExecutionTimes); this.repetitions = cloner.Clone(original.repetitions); this.runs = cloner.Clone(original.runs); this.parameters = new Dictionary(); foreach (var p in original.parameters) { this.parameters.Add(p.Key, cloner.Clone(p.Value)); } } public override IDeepCloneable Clone(Cloner cloner) { return new ParameterConfigurationTree(this, cloner); } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { } #endregion public virtual void CollectResultValues(IDictionary values) { values.Add("RunsAverageExecutionTimes", AverageExecutionTimes); values.Add("Repetitions", Repetitions); values.Add("RunsBestQualities", BestQualities); values.Add("RunsAverageQualities", AverageQualities); values.Add("RunsWorstQualities", WorstQualities); values.Add("RunsQualityVariances", QualityVariances); values.Add("RunsQualityStandardDeviations", QualityStandardDeviations); values.Add("QualitiesNormalized", QualitiesNormalized); values.Add("AverageQualityNormalized", AverageQualityNormalized); values.Add("Runs", Runs); } public virtual void CollectParameterValues(IDictionary values) { foreach (var p in parameters) { values.Add(p); } } #region Events public event EventHandler QualityChanged; private void OnQualityChanged() { var handler = QualityChanged; if (handler != null) handler(this, EventArgs.Empty); } private void Quality_ValueChanged(object sender, EventArgs e) { OnQualityChanged(); } #endregion public override void Parameterize(IParameterizedItem item) { this.parameters.Clear(); base.Parameterize(item); ((IAlgorithm)item).CollectParameterValues(this.Parameters); } public Experiment GenerateExperiment(IAlgorithm algorithm, bool createBatchRuns, int repetitions) { Experiment experiment = new Experiment(); foreach (IValueConfiguration combination in this) { IAlgorithm clonedAlg = (IAlgorithm)algorithm.Clone(); clonedAlg.Name = combination.ParameterInfoString; combination.Parameterize(clonedAlg); clonedAlg.StoreAlgorithmInEachRun = false; if (createBatchRuns) { BatchRun batchRun = new BatchRun(string.Format("BatchRun: {0}", combination.ParameterInfoString)); batchRun.Algorithm = clonedAlg; batchRun.Repetitions = repetitions; experiment.Optimizers.Add(batchRun); } else { experiment.Optimizers.Add(clonedAlg); } } return experiment; } public Experiment GenerateExperiment(IAlgorithm algorithm) { return GenerateExperiment(algorithm, false, 0); } public IEnumerator GetEnumerator() { IEnumerator enumerator = new ParameterCombinationsEnumerator(this); enumerator.Reset(); return enumerator; } public long GetCombinationCount() { long cnt = 0; foreach (var c in this) { cnt++; } return cnt; } } }