#region License Information
/* HeuristicLab
* Copyright (C) 2002-2019 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.Operators;
using HeuristicLab.Parameters;
using HEAL.Attic;
using HeuristicLab.Selection;
namespace HeuristicLab.Algorithms.NSGA2 {
///
/// An operator that represents the mainloop of the NSGA-II
///
[Item("NSGA2MainLoop", "An operator which represents the main loop of the NSGA-II algorithm.")]
[StorableType("F81EA9B1-0A1A-4597-BF2C-C830C32D3394")]
public class NSGA2MainLoop : AlgorithmOperator {
#region Parameter properties
public ValueLookupParameter RandomParameter {
get { return (ValueLookupParameter)Parameters["Random"]; }
}
public ValueLookupParameter MaximizationParameter {
get { return (ValueLookupParameter)Parameters["Maximization"]; }
}
public ScopeTreeLookupParameter QualitiesParameter {
get { return (ScopeTreeLookupParameter)Parameters["Qualities"]; }
}
public ValueLookupParameter PopulationSizeParameter {
get { return (ValueLookupParameter)Parameters["PopulationSize"]; }
}
public ValueLookupParameter SelectorParameter {
get { return (ValueLookupParameter)Parameters["Selector"]; }
}
public ValueLookupParameter CrossoverProbabilityParameter {
get { return (ValueLookupParameter)Parameters["CrossoverProbability"]; }
}
public ValueLookupParameter CrossoverParameter {
get { return (ValueLookupParameter)Parameters["Crossover"]; }
}
public ValueLookupParameter MutationProbabilityParameter {
get { return (ValueLookupParameter)Parameters["MutationProbability"]; }
}
public ValueLookupParameter MutatorParameter {
get { return (ValueLookupParameter)Parameters["Mutator"]; }
}
public ValueLookupParameter EvaluatorParameter {
get { return (ValueLookupParameter)Parameters["Evaluator"]; }
}
public ValueLookupParameter MaximumGenerationsParameter {
get { return (ValueLookupParameter)Parameters["MaximumGenerations"]; }
}
public ValueLookupParameter ResultsParameter {
get { return (ValueLookupParameter)Parameters["Results"]; }
}
public ValueLookupParameter AnalyzerParameter {
get { return (ValueLookupParameter)Parameters["Analyzer"]; }
}
public LookupParameter EvaluatedSolutionsParameter {
get { return (LookupParameter)Parameters["EvaluatedSolutions"]; }
}
public IValueLookupParameter DominateOnEqualQualitiesParameter {
get { return (ValueLookupParameter)Parameters["DominateOnEqualQualities"]; }
}
#endregion
[StorableConstructor]
protected NSGA2MainLoop(StorableConstructorFlag _) : base(_) { }
[StorableHook(HookType.AfterDeserialization)]
private void AfterDeserialization() {
// BackwardsCompatibility3.3
#region Backwards compatible code, remove with 3.4
if (!Parameters.ContainsKey("DominateOnEqualQualities"))
Parameters.Add(new ValueLookupParameter("DominateOnEqualQualities", "Flag which determines wether solutions with equal quality values should be treated as dominated."));
#endregion
}
protected NSGA2MainLoop(NSGA2MainLoop original, Cloner cloner) : base(original, cloner) { }
public NSGA2MainLoop()
: base() {
Initialize();
}
private void Initialize() {
#region Create parameters
Parameters.Add(new ValueLookupParameter("Random", "A pseudo random number generator."));
Parameters.Add(new ValueLookupParameter("Maximization", "True if an objective should be maximized, or false if it should be minimized."));
Parameters.Add(new ScopeTreeLookupParameter("Qualities", "The vector of quality values."));
Parameters.Add(new ValueLookupParameter("PopulationSize", "The population size."));
Parameters.Add(new ValueLookupParameter("Selector", "The operator used to select solutions for reproduction."));
Parameters.Add(new ValueLookupParameter("CrossoverProbability", "The probability that the crossover operator is applied on a solution."));
Parameters.Add(new ValueLookupParameter("Crossover", "The operator used to cross solutions."));
Parameters.Add(new ValueLookupParameter("MutationProbability", "The probability that the mutation operator is applied on a solution."));
Parameters.Add(new ValueLookupParameter("Mutator", "The operator used to mutate solutions."));
Parameters.Add(new ValueLookupParameter("Evaluator", "The operator used to evaluate solutions. This operator is executed in parallel, if an engine is used which supports parallelization."));
Parameters.Add(new ValueLookupParameter("MaximumGenerations", "The maximum number of generations which should be processed."));
Parameters.Add(new ValueLookupParameter("Results", "The variable collection where results should be stored."));
Parameters.Add(new ValueLookupParameter("Analyzer", "The operator used to analyze each generation."));
Parameters.Add(new LookupParameter("EvaluatedSolutions", "The number of times solutions have been evaluated."));
Parameters.Add(new ValueLookupParameter("DominateOnEqualQualities", "Flag which determines wether solutions with equal quality values should be treated as dominated."));
#endregion
#region Create operators
VariableCreator variableCreator = new VariableCreator();
ResultsCollector resultsCollector1 = new ResultsCollector();
Placeholder analyzer1 = new Placeholder();
Placeholder selector = new Placeholder();
SubScopesProcessor subScopesProcessor1 = new SubScopesProcessor();
ChildrenCreator childrenCreator = new ChildrenCreator();
UniformSubScopesProcessor uniformSubScopesProcessor1 = new UniformSubScopesProcessor();
StochasticBranch crossoverStochasticBranch = new StochasticBranch();
Placeholder crossover = new Placeholder();
ParentCopyCrossover noCrossover = new ParentCopyCrossover();
StochasticBranch mutationStochasticBranch = new StochasticBranch();
Placeholder mutator = new Placeholder();
SubScopesRemover subScopesRemover = new SubScopesRemover();
UniformSubScopesProcessor uniformSubScopesProcessor2 = new UniformSubScopesProcessor();
Placeholder evaluator = new Placeholder();
SubScopesCounter subScopesCounter = new SubScopesCounter();
MergingReducer mergingReducer = new MergingReducer();
RankAndCrowdingSorter rankAndCrowdingSorter = new RankAndCrowdingSorter();
LeftSelector leftSelector = new LeftSelector();
RightReducer rightReducer = new RightReducer();
IntCounter intCounter = new IntCounter();
Comparator comparator = new Comparator();
Placeholder analyzer2 = new Placeholder();
ConditionalBranch conditionalBranch = new ConditionalBranch();
variableCreator.CollectedValues.Add(new ValueParameter("Generations", new IntValue(0)));
resultsCollector1.CollectedValues.Add(new LookupParameter("Generations"));
resultsCollector1.ResultsParameter.ActualName = ResultsParameter.Name;
analyzer1.Name = "Analyzer";
analyzer1.OperatorParameter.ActualName = AnalyzerParameter.Name;
selector.Name = "Selector";
selector.OperatorParameter.ActualName = SelectorParameter.Name;
childrenCreator.ParentsPerChild = new IntValue(2);
crossoverStochasticBranch.ProbabilityParameter.ActualName = CrossoverProbabilityParameter.Name;
crossoverStochasticBranch.RandomParameter.ActualName = RandomParameter.Name;
crossover.Name = "Crossover";
crossover.OperatorParameter.ActualName = CrossoverParameter.Name;
noCrossover.Name = "Clone parent";
noCrossover.RandomParameter.ActualName = RandomParameter.Name;
mutationStochasticBranch.ProbabilityParameter.ActualName = MutationProbabilityParameter.Name;
mutationStochasticBranch.RandomParameter.ActualName = RandomParameter.Name;
mutator.Name = "Mutator";
mutator.OperatorParameter.ActualName = MutatorParameter.Name;
subScopesRemover.RemoveAllSubScopes = true;
uniformSubScopesProcessor2.Parallel.Value = true;
evaluator.Name = "Evaluator";
evaluator.OperatorParameter.ActualName = EvaluatorParameter.Name;
subScopesCounter.Name = "Increment EvaluatedSolutions";
subScopesCounter.ValueParameter.ActualName = EvaluatedSolutionsParameter.Name;
rankAndCrowdingSorter.DominateOnEqualQualitiesParameter.ActualName = DominateOnEqualQualitiesParameter.Name;
rankAndCrowdingSorter.CrowdingDistanceParameter.ActualName = "CrowdingDistance";
rankAndCrowdingSorter.RankParameter.ActualName = "Rank";
leftSelector.CopySelected = new BoolValue(false);
leftSelector.NumberOfSelectedSubScopesParameter.ActualName = PopulationSizeParameter.Name;
intCounter.Increment = new IntValue(1);
intCounter.ValueParameter.ActualName = "Generations";
comparator.Comparison = new Comparison(ComparisonType.GreaterOrEqual);
comparator.LeftSideParameter.ActualName = "Generations";
comparator.ResultParameter.ActualName = "Terminate";
comparator.RightSideParameter.ActualName = MaximumGenerationsParameter.Name;
analyzer2.Name = "Analyzer";
analyzer2.OperatorParameter.ActualName = "Analyzer";
conditionalBranch.ConditionParameter.ActualName = "Terminate";
#endregion
#region Create operator graph
OperatorGraph.InitialOperator = variableCreator;
variableCreator.Successor = resultsCollector1;
resultsCollector1.Successor = analyzer1;
analyzer1.Successor = selector;
selector.Successor = subScopesProcessor1;
subScopesProcessor1.Operators.Add(new EmptyOperator());
subScopesProcessor1.Operators.Add(childrenCreator);
subScopesProcessor1.Successor = mergingReducer;
childrenCreator.Successor = uniformSubScopesProcessor1;
uniformSubScopesProcessor1.Operator = crossoverStochasticBranch;
uniformSubScopesProcessor1.Successor = uniformSubScopesProcessor2;
crossoverStochasticBranch.FirstBranch = crossover;
crossoverStochasticBranch.SecondBranch = noCrossover;
crossoverStochasticBranch.Successor = mutationStochasticBranch;
crossover.Successor = null;
noCrossover.Successor = null;
mutationStochasticBranch.FirstBranch = mutator;
mutationStochasticBranch.SecondBranch = null;
mutationStochasticBranch.Successor = subScopesRemover;
mutator.Successor = null;
subScopesRemover.Successor = null;
uniformSubScopesProcessor2.Operator = evaluator;
uniformSubScopesProcessor2.Successor = subScopesCounter;
evaluator.Successor = null;
subScopesCounter.Successor = null;
mergingReducer.Successor = rankAndCrowdingSorter;
rankAndCrowdingSorter.Successor = leftSelector;
leftSelector.Successor = rightReducer;
rightReducer.Successor = intCounter;
intCounter.Successor = comparator;
comparator.Successor = analyzer2;
analyzer2.Successor = conditionalBranch;
conditionalBranch.FalseBranch = selector;
conditionalBranch.TrueBranch = null;
conditionalBranch.Successor = null;
#endregion
}
public override IDeepCloneable Clone(Cloner cloner) {
return new NSGA2MainLoop(this, cloner);
}
}
}