#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.Optimization.Operators;
using HeuristicLab.Parameters;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
using HeuristicLab.PluginInfrastructure;
using HeuristicLab.Random;
namespace HeuristicLab.Analysis.FitnessLandscape {
[Item("Local Analysis", "A local analysis algorithm.")]
[Creatable("Algorithms")]
[StorableClass]
public sealed class LocalAnalysis : HeuristicOptimizationEngineAlgorithm, IStorableContent {
public string Filename { get; set; }
#region Problem Properties
public override Type ProblemType {
get { return typeof(ISingleObjectiveHeuristicOptimizationProblem); }
}
public new ISingleObjectiveHeuristicOptimizationProblem Problem {
get { return (ISingleObjectiveHeuristicOptimizationProblem)base.Problem; }
set { base.Problem = value; }
}
#endregion
#region Parameter Properties
private ValueParameter SeedParameter {
get { return (ValueParameter)Parameters["Seed"]; }
}
private ValueParameter SetSeedRandomlyParameter {
get { return (ValueParameter)Parameters["SetSeedRandomly"]; }
}
public IConstrainedValueParameter MutatorParameter {
get { return (IConstrainedValueParameter)Parameters["Mutator"]; }
}
public IConstrainedValueParameter SelectorParameter {
get { return (IConstrainedValueParameter)Parameters["Selector"]; }
}
private ValueParameter MaximumIterationsParameter {
get { return (ValueParameter)Parameters["MaximumIterations"]; }
}
private ValueParameter SampleSizeParameter {
get { return (ValueParameter)Parameters["SampleSize"]; }
}
private ValueParameter AnalyzerParameter {
get { return (ValueParameter)Parameters["Analyzer"]; }
}
#endregion
#region Properties
private RandomCreator RandomCreator {
get { return (RandomCreator)OperatorGraph.InitialOperator; }
}
private SolutionsCreator SolutionsCreator {
get { return (SolutionsCreator)RandomCreator.Successor; }
}
private LocalAnalysisMainLoop MainLoop {
get { return (LocalAnalysisMainLoop)SolutionsCreator.Successor; }
}
[Storable]
private BestAverageWorstQualityAnalyzer qualityAnalyzer;
[Storable]
private QualityTrailMultiAnalyzer qualityTrailAnalyzer;
#endregion
[StorableConstructor]
private LocalAnalysis(bool deserializing) : base(deserializing) { }
private LocalAnalysis(LocalAnalysis original, Cloner cloner)
: base(original, cloner) {
qualityAnalyzer = (BestAverageWorstQualityAnalyzer)cloner.Clone(original.qualityAnalyzer);
qualityTrailAnalyzer = (QualityTrailMultiAnalyzer)cloner.Clone(original.qualityTrailAnalyzer);
Initialize();
}
public LocalAnalysis()
: base() {
Parameters.Add(new ValueParameter("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
Parameters.Add(new ValueParameter("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
Parameters.Add(new ConstrainedValueParameter("Mutator", "Mutation operator."));
Parameters.Add(new ConstrainedValueParameter("Selector", "Selection operator."));
Parameters.Add(new ValueParameter("MaximumIterations", "The maximum number of generations which should be processed.", new IntValue(10000)));
Parameters.Add(new ValueParameter("SampleSize", "Number of moves that MultiMoveGenerators should create. This is ignored for Exhaustive- and SingleMoveGenerators.", new IntValue(1)));
Parameters.Add(new ValueParameter("Analyzer", "The operator used to analyze the solution and moves.", new MultiAnalyzer()));
RandomCreator randomCreator = new RandomCreator();
SolutionsCreator solutionsCreator = new SolutionsCreator();
LocalAnalysisMainLoop laMainLoop = new LocalAnalysisMainLoop();
OperatorGraph.InitialOperator = randomCreator;
randomCreator.RandomParameter.ActualName = "Random";
randomCreator.SeedParameter.ActualName = SeedParameter.Name;
randomCreator.SeedParameter.Value = null;
randomCreator.SetSeedRandomlyParameter.ActualName = SetSeedRandomlyParameter.Name;
randomCreator.SetSeedRandomlyParameter.Value = null;
randomCreator.Successor = solutionsCreator;
solutionsCreator.NumberOfSolutions = new IntValue(1);
solutionsCreator.Successor = laMainLoop;
laMainLoop.MutatorParameter.ActualName = MutatorParameter.Name;
laMainLoop.SelectorParameter.ActualName = SelectorParameter.Name;
laMainLoop.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
laMainLoop.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
laMainLoop.ResultsParameter.ActualName = "Results";
laMainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
qualityTrailAnalyzer = new QualityTrailMultiAnalyzer();
ParameterizeAnalyzers();
UpdateAnalyzers();
Initialize();
}
public override IDeepCloneable Clone(Cloner cloner) {
return new LocalAnalysis(this, cloner);
}
public override void Prepare() {
if (Problem != null)
base.Prepare();
}
#region Events
protected override void OnProblemChanged() {
ParameterizeStochasticOperator(Problem.SolutionCreator);
ParameterizeStochasticOperator(Problem.Evaluator);
foreach (IOperator op in Problem.Operators.OfType()) ParameterizeStochasticOperator(op);
ParameterizeSolutionsCreator();
ParameterizeMainLoop();
UpdateMutators();
UpdateSelectors();
UpdateAnalyzers();
ParameterizeSelector();
ParameterizeAnalyzers();
ParameterizeIterationBasedOperators();
Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
base.OnProblemChanged();
}
protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
ParameterizeStochasticOperator(Problem.SolutionCreator);
ParameterizeSolutionsCreator();
base.Problem_SolutionCreatorChanged(sender, e);
}
protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
ParameterizeStochasticOperator(Problem.Evaluator);
ParameterizeSolutionsCreator();
ParameterizeMainLoop();
ParameterizeSelector();
ParameterizeAnalyzers();
Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
base.Problem_EvaluatorChanged(sender, e);
}
protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
foreach (IOperator op in Problem.Operators.OfType()) ParameterizeStochasticOperator(op);
UpdateMutators();
UpdateSelectors();
UpdateAnalyzers();
ParameterizeMainLoop();
ParameterizeSelector();
ParameterizeAnalyzers();
ParameterizeIterationBasedOperators();
base.Problem_OperatorsChanged(sender, e);
}
private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
ParameterizeMainLoop();
ParameterizeSelector();
}
private void MutatorParameter_ValueChanged(object sender, EventArgs e) {
ParameterizeMainLoop();
ParameterizeSelector();
ParameterizeAnalyzers();
}
#endregion
#region Helpers
[StorableHook(HookType.AfterDeserialization)]
private void Initialize() {
if (Problem != null) {
Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
}
MutatorParameter.ValueChanged += MutatorParameter_ValueChanged;
}
private void UpdateSelectors() {
SelectorParameter.ValidValues.Clear();
foreach (var s in ApplicationManager.Manager.GetInstances())
SelectorParameter.ValidValues.Add(s);
}
private void UpdateMutators() {
MutatorParameter.ValidValues.Clear();
foreach (var m in Problem.Operators.OfType()) {
MutatorParameter.ValidValues.Add(m);
}
}
private void UpdateAnalyzers() {
AnalyzerParameter.Value.Operators.Clear();
if (Problem != null) {
foreach (IAnalyzer analyzer in Problem.Operators.OfType()) {
foreach (IScopeTreeLookupParameter param in analyzer.Parameters.OfType())
param.Depth = 0;
AnalyzerParameter.Value.Operators.Add(analyzer);
}
}
AnalyzerParameter.Value.Operators.Add(qualityAnalyzer);
AnalyzerParameter.Value.Operators.Add(qualityTrailAnalyzer);
}
private void ParameterizeSolutionsCreator() {
SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
}
private void ParameterizeMainLoop() {
MainLoop.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
MainLoop.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
MainLoop.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
}
private void ParameterizeStochasticOperator(IOperator op) {
if (op is IStochasticOperator)
((IStochasticOperator)op).RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
}
private void ParameterizeSelector() {
if (Problem != null) {
foreach (var op in SelectorParameter.ValidValues) {
op.NumberOfSelectedSubScopesParameter.Value = new IntValue(1);
op.CopySelected = new BoolValue(false);
ISingleObjectiveSelector sos = op as ISingleObjectiveSelector;
if (sos != null) {
sos.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
sos.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
}
IStochasticOperator so = op as IStochasticOperator;
if (so != null) {
so.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
}
}
}
}
private void ParameterizeAnalyzers() {
qualityAnalyzer.ResultsParameter.ActualName = "Results";
if (Problem != null) {
qualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
qualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
}
}
private void ParameterizeIterationBasedOperators() {
if (Problem != null) {
foreach (IIterationBasedOperator op in Problem.Operators.OfType()) {
op.IterationsParameter.ActualName = "Iterations";
op.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
}
}
}
#endregion
}
}