#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 HeuristicLab.Common;
using HeuristicLab.Core;
using HeuristicLab.Data;
using HeuristicLab.Operators;
using HeuristicLab.Optimization;
using HeuristicLab.Optimization.Operators;
using HeuristicLab.Parameters;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
using HeuristicLab.Random;
using System;
using System.Linq;
namespace HeuristicLab.Analysis.FitnessLandscape {
[Item("Local Analysis", "A local analysis algorithm.")]
[StorableClass]
public abstract class LocalAnalysis : HeuristicOptimizationEngineAlgorithm, IStorableContent where T : class, IOperator, new() {
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
public IFixedValueParameter SeedParameter {
get { return (IFixedValueParameter)Parameters["Seed"]; }
}
public IFixedValueParameter SetSeedRandomlyParameter {
get { return (IFixedValueParameter)Parameters["SetSeedRandomly"]; }
}
public IConstrainedValueParameter MutatorParameter {
get { return (IConstrainedValueParameter)Parameters["Mutator"]; }
}
public IFixedValueParameter MaximumIterationsParameter {
get { return (IFixedValueParameter)Parameters["MaximumIterations"]; }
}
public IFixedValueParameter RepetitionsParameter {
get { return (IFixedValueParameter)Parameters["Repetitions"]; }
}
public IValueParameter AnalyzerParameter {
get { return (IValueParameter)Parameters["Analyzer"]; }
}
public IFixedValueParameter SelectorParameter {
get { return (IFixedValueParameter)Parameters["Selector"]; }
}
#endregion
#region Properties
protected RandomCreator GlobalRandomCreator {
get { return (RandomCreator)OperatorGraph.InitialOperator; }
}
protected UniformSubScopesProcessor FirstUniformSubScopesProcessor {
get { return (UniformSubScopesProcessor)((SubScopesCreator)GlobalRandomCreator.Successor).Successor; }
}
protected LocalRandomCreator IteratedRandomCreator {
get { return (LocalRandomCreator)FirstUniformSubScopesProcessor.Operator; }
}
protected VariableCreator VariableCreator {
get { return (VariableCreator)IteratedRandomCreator.Successor; }
}
protected UniformSubScopesProcessor SecondUniformSubScopesProcessor {
get { return (UniformSubScopesProcessor)FirstUniformSubScopesProcessor.Successor; }
}
protected SolutionsCreator SolutionsCreator {
get { return (SolutionsCreator)SecondUniformSubScopesProcessor.Operator; }
}
protected LocalAnalysisMainLoop MainLoop {
get { return (LocalAnalysisMainLoop)SolutionsCreator.Successor; }
}
[Storable]
private QualityTrailMultiAnalyzer qualityTrailAnalyzer;
#endregion
[StorableConstructor]
protected LocalAnalysis(bool deserializing) : base(deserializing) { }
protected LocalAnalysis(LocalAnalysis original, Cloner cloner)
: base(original, cloner) {
qualityTrailAnalyzer = cloner.Clone(original.qualityTrailAnalyzer);
RegisterEventHandlers();
}
protected LocalAnalysis(T selector)
: base() {
Parameters.Add(new FixedValueParameter("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
Parameters.Add(new FixedValueParameter("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 FixedValueParameter("MaximumIterations", "The maximum number of generations which should be processed.", new IntValue(100)));
Parameters.Add(new FixedValueParameter("Repetitions", "The number of repetitions that should be performed.", new IntValue(10)));
Parameters.Add(new ValueParameter("Analyzer", "The operator used to analyze the solution and moves.", new MultiAnalyzer()));
Parameters.Add(new FixedValueParameter("Selector", "Selection operator.", selector));
RandomCreator randomCreator = new RandomCreator();
SubScopesCreator ssc = new SubScopesCreator();
UniformSubScopesProcessor ussp1 = new UniformSubScopesProcessor();
UniformSubScopesProcessor ussp2 = new UniformSubScopesProcessor();
LocalRandomCreator lrc = new LocalRandomCreator();
VariableCreator variableCreator = new VariableCreator();
SolutionsCreator solutionsCreator = new SolutionsCreator();
LocalAnalysisMainLoop laMainLoop = new LocalAnalysisMainLoop();
ResultsCollector collector = new ResultsCollector();
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 = ssc;
ssc.NumberOfSubScopesParameter.Value = null;
ssc.NumberOfSubScopesParameter.ActualName = RepetitionsParameter.Name;
ssc.Successor = ussp1;
ussp1.Depth = new IntValue(1);
ussp1.Parallel = new BoolValue(false);
ussp1.Operator = lrc;
ussp1.Successor = ussp2;
lrc.GlobalRandomParameter.ActualName = randomCreator.RandomParameter.ActualName;
lrc.LocalRandomParameter.ActualName = "IteratedRandom";
lrc.Successor = variableCreator;
var iterResults = new ValueParameter("IteratedResults", new ResultCollection());
variableCreator.CollectedValues.Add(iterResults);
variableCreator.Successor = null;
ussp2.Depth = new IntValue(1);
ussp2.Parallel = new BoolValue(true);
ussp2.Operator = solutionsCreator;
ussp2.Successor = collector;
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 = lrc.LocalRandomParameter.ActualName;
laMainLoop.ResultsParameter.ActualName = iterResults.Name;
laMainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
qualityTrailAnalyzer = new QualityTrailMultiAnalyzer();
qualityTrailAnalyzer.UpdateIntervalParameter.Value = null;
qualityTrailAnalyzer.UpdateIntervalParameter.ActualName = MaximumIterationsParameter.Name;
AnalyzerParameter.Value.Operators.Add(qualityTrailAnalyzer, true);
collector.CollectedValues.Add(new ScopeTreeLookupParameter("IteratedResults", 1));
collector.ResultsParameter.ActualName = "Results";
collector.CopyValue = new BoolValue(false);
collector.Successor = null;
RegisterEventHandlers();
}
public override void Prepare() {
if (Problem != null) base.Prepare();
}
protected override void OnStopped() {
var iteratedResults = Results.SingleOrDefault(x => x.Name == "IteratedResults");
if (iteratedResults != null) {
var rc = iteratedResults.Value as ItemArray;
if (rc != null) {
var results = rc.FirstOrDefault();
if (results != null) {
var toAvg = results.Select(x => x.Name).ToDictionary(x => x, x => 0.0);
foreach (var r in rc) {
foreach (var v in r) {
if (!toAvg.ContainsKey(v.Name)) continue;
var value = v.Value as IntValue;
if (value != null) toAvg[v.Name] += value.Value;
else {
var doubleValue = v.Value as DoubleValue;
if (doubleValue != null) toAvg[v.Name] += doubleValue.Value;
}
}
}
foreach (var r in toAvg.Keys.OrderBy(x => x)) {
Results.Add(new Result(r, new DoubleValue(toAvg[r] / RepetitionsParameter.Value.Value)));
}
}
}
}
base.OnStopped();
}
#region Events
protected override void OnProblemChanged() {
base.OnProblemChanged();
UpdateMutators();
Parameterize();
Problem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
}
protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
base.Problem_SolutionCreatorChanged(sender, e);
Parameterize();
}
protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
base.Problem_EvaluatorChanged(sender, e);
Parameterize();
Problem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
}
protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
UpdateMutators();
Parameterize();
base.Problem_OperatorsChanged(sender, e);
}
private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
Parameterize();
}
#endregion
#region Helpers
private void RegisterEventHandlers() {
if (Problem != null) {
Problem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
}
}
private void UpdateMutators() {
var selected = MutatorParameter.Value;
MutatorParameter.ValidValues.Clear();
foreach (var m in Problem.Operators.OfType()) {
MutatorParameter.ValidValues.Add(m);
if (selected != null && selected.GetType() == m.GetType()) MutatorParameter.Value = m;
}
}
protected virtual void Parameterize() {
if (Problem == null) return;
MainLoop.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
MainLoop.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
MainLoop.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
foreach (var sOp in Problem.Operators.OfType()) {
sOp.RandomParameter.ActualName = IteratedRandomCreator.LocalRandomParameter.ActualName;
}
foreach (var iOp in Problem.Operators.OfType()) {
iOp.IterationsParameter.ActualName = "Iterations";
iOp.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
}
var sEval = Problem.Evaluator as IStochasticOperator;
if (sEval != null) sEval.RandomParameter.ActualName = IteratedRandomCreator.LocalRandomParameter.ActualName;
var sCrea = Problem.SolutionCreator as IStochasticOperator;
if (sCrea != null) sCrea.RandomParameter.ActualName = IteratedRandomCreator.LocalRandomParameter.ActualName;
var sSel = SelectorParameter.Value as IStochasticOperator;
if (sSel != null) sSel.RandomParameter.ActualName = IteratedRandomCreator.LocalRandomParameter.ActualName;
var sel = SelectorParameter.Value as ISelector;
if (sel != null) {
sel.NumberOfSelectedSubScopesParameter.Value = new IntValue(1);
sel.CopySelected = new BoolValue(false);
var sos = sel as ISingleObjectiveSelector;
if (sos != null) {
sos.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
sos.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
}
}
foreach (var op in Problem.Operators.OfType()) {
var resultsParam = op.Parameters.SingleOrDefault(x => x.Name == "Results");
var lookupParam = resultsParam as ILookupParameter;
if (lookupParam == null) continue;
lookupParam.ActualName = "IteratedResults";
}
}
#endregion
}
}