#region License Information
/* HeuristicLab
* Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Linq;
using HeuristicLab.Common;
using HeuristicLab.Core;
using HeuristicLab.Data;
using HeuristicLab.Optimization;
using HeuristicLab.Parameters;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
using HeuristicLab.PluginInfrastructure;
using HeuristicLab.Algorithms.GeneticAlgorithm;
using HeuristicLab.Problems.TestFunctions;
namespace HeuristicLab.Problems.MetaOptimization {
[Item("Meta Optimization Problem", "Represents a Meta Optimization Problem.")]
[Creatable("Problems")]
[StorableClass]
public sealed class MetaOptimizationProblem : SingleObjectiveProblem {
public const string AlgorithmTypeParameterName = "AlgorithmType";
public const string ProblemTypeParameterName = "ProblemType";
public const string ProblemsParameterName = "Problems";
public const string ParameterConfigurationTreeParameterName = "ParameterConfiguration";
public const string RepetitionsParameterName = "Repetitions";
public const string IntValueManipulatorParameterName = "IntValueManipulator";
public const string DoubleValueManipulatorParameterName = "DoubleValueManipulator";
public const string IntValueCrossoverParameterName = "IntValueCrossover";
public const string DoubleValueCrossoverParameterName = "DoubleValueCrossover";
#region Parameter Properties
public IValueParameter> AlgorithmTypeParameter {
get { return (ValueParameter>)Parameters[AlgorithmTypeParameterName]; }
}
public IValueParameter> ProblemTypeParameter {
get { return (ValueParameter>)Parameters[ProblemTypeParameterName]; }
}
public IValueParameter> ProblemsParameter {
get { return (ValueParameter>)Parameters[ProblemsParameterName]; }
}
public IValueParameter ParameterConfigurationTreeParameter {
get { return (ValueParameter)Parameters[ParameterConfigurationTreeParameterName]; }
}
public IValueParameter RepetitionsParameter {
get { return (ValueParameter)Parameters[RepetitionsParameterName]; }
}
public IValueParameter IntValueManipulatorParameter {
get { return (ValueParameter)Parameters[IntValueManipulatorParameterName]; }
}
public IValueParameter DoubleValueManipulatorParameter {
get { return (ValueParameter)Parameters[DoubleValueManipulatorParameterName]; }
}
#endregion
#region Properties
public IAlgorithm Algorithm {
get { return CreateAlgorithm(AlgorithmType.Value, ProblemType.Value); }
}
public ConstrainedTypeValue AlgorithmType {
get { return AlgorithmTypeParameter.Value; }
set { AlgorithmTypeParameter.Value = value; }
}
public ConstrainedTypeValue ProblemType {
get { return ProblemTypeParameter.Value; }
set { ProblemTypeParameter.Value = value; }
}
public ConstrainedItemList Problems {
get { return ProblemsParameter.Value; }
set { ProblemsParameter.Value = value; }
}
public ParameterConfigurationTree ParameterConfigurationTree {
get { return ParameterConfigurationTreeParameter.Value; }
set { ParameterConfigurationTreeParameter.Value = value; }
}
public IntValue Repetitions {
get { return RepetitionsParameter.Value; }
set { RepetitionsParameter.Value = value; }
}
private BestParameterConfigurationAnalyzer BestParameterConfigurationAnalyzer {
get { return Operators.OfType().FirstOrDefault(); }
}
private ReferenceQualityAnalyzer ReferenceQualityAnalyzer {
get { return Operators.OfType().FirstOrDefault(); }
}
private SolutionCacheAnalyzer RunsAnalyzer {
get { return Operators.OfType().FirstOrDefault(); }
}
private PMOPopulationDiversityAnalyzer PMOPopulationDiversityAnalyzer {
get { return Operators.OfType().FirstOrDefault(); }
}
#endregion
public MetaOptimizationProblem()
: base() {
Parameters.Add(new ValueParameter>(AlgorithmTypeParameterName, "The algorithm which's parameters should be optimized.", new ConstrainedTypeValue(typeof(GeneticAlgorithm))));
Parameters.Add(new ValueParameter>(ProblemTypeParameterName, "The problem type.", new ConstrainedTypeValue()));
Parameters.Add(new ValueParameter>(ProblemsParameterName, "The problems that should be evaluated.", new ConstrainedItemList()));
Parameters.Add(new ValueParameter(ParameterConfigurationTreeParameterName, "Tree of algorithm parameters that should be optimized."));
Parameters.Add(new ValueParameter(RepetitionsParameterName, "The number of evaluations for each problem.", new IntValue(3)));
var validIntManipulators = new ItemSet(ApplicationManager.Manager.GetInstances());
var validDoubleManipulators = new ItemSet(ApplicationManager.Manager.GetInstances());
var validIntCrossovers = new ItemSet(ApplicationManager.Manager.GetInstances());
var validDoubleCrossovers = new ItemSet(ApplicationManager.Manager.GetInstances());
Parameters.Add(new ConstrainedValueParameter(IntValueManipulatorParameterName, "", validIntManipulators, validIntManipulators.Where(x => x.GetType() == typeof(NormalIntValueManipulator)).SingleOrDefault()));
Parameters.Add(new ConstrainedValueParameter(DoubleValueManipulatorParameterName, "", validDoubleManipulators, validDoubleManipulators.Where(x => x.GetType() == typeof(NormalDoubleValueManipulator)).SingleOrDefault()));
Parameters.Add(new ConstrainedValueParameter(IntValueCrossoverParameterName, "", validIntCrossovers, validIntCrossovers.Where(x => x.GetType() == typeof(NormalIntValueCrossover)).SingleOrDefault()));
Parameters.Add(new ConstrainedValueParameter(DoubleValueCrossoverParameterName, "", validDoubleCrossovers, validDoubleCrossovers.Where(x => x.GetType() == typeof(NormalDoubleValueCrossover)).SingleOrDefault()));
Maximization = new BoolValue(false);
SolutionCreator = new RandomParameterConfigurationCreator();
Evaluator = new ParameterConfigurationEvaluator();
InitializeOperators();
RegisterParameterEvents();
ParameterizeAnalyzer();
ParameterizeSolutionCreator();
ParameterizeEvaluator();
ParameterizeOperators();
AlgorithmTypeParameter_ValueChanged(this, EventArgs.Empty);
}
[StorableConstructor]
private MetaOptimizationProblem(bool deserializing) : base(deserializing) { }
private MetaOptimizationProblem(MetaOptimizationProblem original, Cloner cloner)
: base(original, cloner) {
this.RegisterParameterEvents();
}
public override IDeepCloneable Clone(Cloner cloner) {
return new MetaOptimizationProblem(this, cloner);
}
#region Helpers
[StorableHook(HookType.AfterDeserialization)]
private void AfterDeserializationHook() {
RegisterParameterEvents();
}
private void RegisterParameterEvents() {
SolutionCreatorParameter.ValueChanged += new EventHandler(SolutionCreatorParameter_ValueChanged);
EvaluatorParameter.ValueChanged += new EventHandler(EvaluatorParameter_ValueChanged);
Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
AlgorithmTypeParameter.ValueChanged += new EventHandler(AlgorithmTypeParameter_ValueChanged);
AlgorithmType.ValueChanged += new EventHandler(AlgorithmType_ValueChanged);
ProblemTypeParameter.ValueChanged += new EventHandler(ProblemTypeParameter_ValueChanged);
ProblemType.ValueChanged += new EventHandler(ProblemType_ValueChanged);
}
private void InitializeOperators() {
Operators.AddRange(ApplicationManager.Manager.GetInstances().Cast());
Operators.Add(new BestParameterConfigurationAnalyzer());
Operators.Add(new ReferenceQualityAnalyzer());
Operators.Add(new SolutionCacheAnalyzer());
Operators.Add(new PMOPopulationDiversityAnalyzer());
}
private void ParameterizeSolutionCreator() {
}
private void ParameterizeEvaluator() {
((ParameterConfigurationEvaluator)Evaluator).ParameterConfigurationParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
}
private void ParameterizeAnalyzer() {
if (BestParameterConfigurationAnalyzer != null) {
BestParameterConfigurationAnalyzer.ParameterConfigurationParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
}
if (ReferenceQualityAnalyzer != null) {
ReferenceQualityAnalyzer.ParameterConfigurationParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
}
if (RunsAnalyzer != null) {
RunsAnalyzer.ParameterConfigurationParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
}
if (PMOPopulationDiversityAnalyzer != null) {
PMOPopulationDiversityAnalyzer.SolutionParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
PMOPopulationDiversityAnalyzer.StoreHistoryParameter.Value.Value = true;
}
}
private void ParameterizeOperators() {
foreach (IParameterConfigurationCrossover op in Operators.OfType()) {
op.ParentsParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
op.ChildParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
}
foreach (IParameterConfigurationManipulator op in Operators.OfType()) {
op.ParameterConfigurationTreeParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
}
}
#endregion
#region Events
private void SolutionCreatorParameter_ValueChanged(object sender, EventArgs e) {
ParameterizeSolutionCreator();
ParameterizeEvaluator();
ParameterizeAnalyzer();
ParameterizeOperators();
OnSolutionCreatorChanged();
}
private void EvaluatorParameter_ValueChanged(object sender, EventArgs e) {
Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
ParameterizeEvaluator();
ParameterizeAnalyzer();
OnEvaluatorChanged();
}
private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
ParameterizeAnalyzer();
}
private void AlgorithmTypeParameter_ValueChanged(object sender, EventArgs e) {
AlgorithmType_ValueChanged(sender, e);
}
private void AlgorithmType_ValueChanged(object sender, EventArgs e) {
IAlgorithm instance = (IAlgorithm)Activator.CreateInstance(AlgorithmType.Value);
this.ProblemType.ValidTypes = ApplicationManager.Manager.GetTypes(instance.ProblemType, true).ToList();
this.ProblemType.Value = this.ProblemType.ValidTypes.Where(t => t != typeof(MetaOptimizationProblem)).FirstOrDefault();
if (ProblemType.Value != null) {
ParameterConfigurationTreeParameter.ActualValue = new ParameterConfigurationTree(CreateAlgorithm(AlgorithmType.Value, ProblemType.Value));
} else {
ParameterConfigurationTreeParameter.ActualValue = null;
}
}
private void ProblemTypeParameter_ValueChanged(object sender, EventArgs e) {
ProblemType_ValueChanged(sender, e);
}
private void ProblemType_ValueChanged(object sender, EventArgs e) {
Problems.Clear();
Problems.Type = ProblemType.Value;
ParameterConfigurationTreeParameter.ActualValue = new ParameterConfigurationTree(CreateAlgorithm(AlgorithmType.Value, ProblemType.Value));
}
#endregion
private IAlgorithm CreateAlgorithm(Type algorithmType, Type problemType) {
IAlgorithm algorithm = (IAlgorithm)Activator.CreateInstance(algorithmType);
algorithm.Problem = (IProblem)Activator.CreateInstance(problemType);
return algorithm;
}
public void ImportAlgorithm(IAlgorithm algorithm) {
AlgorithmType.Value = algorithm.GetType();
if (algorithm.Problem != null) ProblemType.Value = algorithm.Problem.GetType();
ParameterConfigurationTreeParameter.ActualValue = new ParameterConfigurationTree(algorithm);
if (algorithm.Problem != null) Problems.Add((IProblem)algorithm.Problem);
}
}
}