#region License Information
/* HeuristicLab
* Copyright (C) 2002-2015 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.Linq;
using HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm;
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.Selection;
namespace HeuristicLab.Algorithms.ALPS.OffspringSelection {
[Item("AlpsOffspringSelectionGeneticAlgorithmMainLoop", "An ALPS OS GA Main Loop Operator.")]
[StorableClass]
public sealed class AlpsOffspringSelectionGeneticAlgorithmMainLoop : AlgorithmOperator {
#region Parameter Properties
public ValueLookupParameter MaximizationParameter {
get { return (ValueLookupParameter)Parameters["Maximization"]; }
}
public ScopeTreeLookupParameter QualityParameter {
get { return (ScopeTreeLookupParameter)Parameters["Quality"]; }
}
public ILookupParameter MaximumGenerationsParameter {
get { return (ILookupParameter)Parameters["MaximumGenerations"]; }
}
public ILookupParameter AnalyzerParameter {
get { return (ILookupParameter)Parameters["Analyzer"]; }
}
public ILookupParameter LayerAnalyzerParameter {
get { return (ILookupParameter)Parameters["LayerAnalyzer"]; }
}
public LookupParameter ComparisonFactorParameter {
get { return (LookupParameter)Parameters["ComparisonFactor"]; }
}
public ValueLookupParameter ComparisonFactorStartParameter {
get { return (ValueLookupParameter)Parameters["ComparisonFactorStart"]; }
}
public ValueLookupParameter ComparisonFactorModifierParameter {
get { return (ValueLookupParameter)Parameters["ComparisonFactorModifier"]; }
}
#endregion
public OffspringSelectionGeneticAlgorithmMainOperator MainOperator {
get { return OperatorGraph.Iterate().OfType().First(); }
}
public EldersEmigrator EldersEmigrator {
get { return OperatorGraph.Iterate().OfType().First(); }
}
public LayerUpdator LayerUpdator {
get { return OperatorGraph.Iterate().OfType().First(); }
}
[StorableConstructor]
private AlpsOffspringSelectionGeneticAlgorithmMainLoop(bool deserializing)
: base(deserializing) { }
private AlpsOffspringSelectionGeneticAlgorithmMainLoop(AlpsOffspringSelectionGeneticAlgorithmMainLoop original, Cloner cloner)
: base(original, cloner) { }
public override IDeepCloneable Clone(Cloner cloner) {
return new AlpsOffspringSelectionGeneticAlgorithmMainLoop(this, cloner);
}
public AlpsOffspringSelectionGeneticAlgorithmMainLoop()
: base() {
Parameters.Add(new ValueLookupParameter("Maximization", "True if the problem is a maximization problem, otherwise false."));
Parameters.Add(new ScopeTreeLookupParameter("Quality", "The value which represents the quality of a solution."));
Parameters.Add(new LookupParameter("MaximumGenerations", "The maximum number of generations that the algorithm should process."));
Parameters.Add(new LookupParameter("Analyzer", "The operator used to the analyze all individuals."));
Parameters.Add(new LookupParameter("LayerAnalyzer", "The operator used to analyze each layer."));
Parameters.Add(new LookupParameter("ComparisonFactor", "The comparison factor is used to determine whether the offspring should be compared to the better parent, the worse parent or a quality value linearly interpolated between them. It is in the range [0;1]."));
Parameters.Add(new ValueLookupParameter("ComparisonFactorStart", "The initial value for the comparison factor."));
Parameters.Add(new ValueLookupParameter("ComparisonFactorModifier", "The operator used to modify the comparison factor."));
var variableCreator = new VariableCreator() { Name = "Initialize" };
var initializeComparisonFactor = new Assigner() { Name = "Initialize ComparisonFactor" };
var initLayerAnalyzerProcessor = new SubScopesProcessor();
var layerVariableCreator = new VariableCreator() { Name = "Initialize Layer" };
var initLayerAnalyzerPlaceholder = new Placeholder() { Name = "LayerAnalyzer (Placeholder)" };
var initAnalyzerPlaceholder = new Placeholder() { Name = "Analyzer (Placeholder)" };
var resultsCollector = new ResultsCollector();
var matingPoolPreProcessor = new UniformSubScopesProcessor() { Name = "MatingPoolPreProcessor" };
var matingPoolPreSorter = new SubScopesSorter() { Name = "MatingPoolPreSorter" };
var matingPoolCreator = new MatingPoolCreator() { Name = "Create Mating Pools" };
var matingPoolProcessor = new LayerUniformSubScopesProcessor();
var initializeLayer = new Assigner() { Name = "Reset LayerEvaluatedSolutions" };
var mainOperator = CreatePreparedOSGAMainOperator();
var generationsIcrementor = new IntCounter() { Name = "Increment Generations" };
var evaluatedSolutionsReducer = new DataReducer() { Name = "Increment EvaluatedSolutions" };
var eldersEmigrator = new EldersEmigrator() { Name = "Emigrate Elders" };
var updateComparisonFactor = new Placeholder() { Name = "Update ComparisonFactor (Placeholder)" };
var layerUpdator = new LayerUpdator(mainOperator) { Name = "Update Layers" };
var layerAnalyzerProcessor = new LayerUniformSubScopesProcessor();
var layerAnalyzerPlaceholder = new Placeholder() { Name = "LayerAnalyzer (Placeholder)" };
var analyzerPlaceholder = new Placeholder() { Name = "Analyzer (Placeholder)" };
var termination = new TerminationOperator();
OperatorGraph.InitialOperator = variableCreator;
variableCreator.CollectedValues.Add(new ValueParameter("Generations", new IntValue(0)));
variableCreator.CollectedValues.Add(new ValueParameter("GenerationsSinceLastRefresh", new IntValue(0)));
variableCreator.CollectedValues.Add(new ValueParameter("OpenLayers", new IntValue(1)));
variableCreator.Successor = initializeComparisonFactor;
initializeComparisonFactor.LeftSideParameter.ActualName = "ComparisonFactor";
initializeComparisonFactor.RightSideParameter.ActualName = "ComparisonFactorStart";
initializeComparisonFactor.Successor = initLayerAnalyzerProcessor;
initLayerAnalyzerProcessor.Operators.Add(layerVariableCreator);
initLayerAnalyzerProcessor.Successor = initAnalyzerPlaceholder;
layerVariableCreator.CollectedValues.Add(new ValueParameter("LayerEvaluatedSolutions"));
layerVariableCreator.CollectedValues.Add(new ValueParameter("LayerResults"));
layerVariableCreator.CollectedValues.Add(new ValueParameter("SelectionPressure", new DoubleValue(0)));
layerVariableCreator.CollectedValues.Add(new ValueParameter("CurrentSuccessRatio", new DoubleValue(0)));
layerVariableCreator.Successor = initLayerAnalyzerPlaceholder;
initLayerAnalyzerPlaceholder.OperatorParameter.ActualName = LayerAnalyzerParameter.Name;
initLayerAnalyzerPlaceholder.Successor = null;
initAnalyzerPlaceholder.OperatorParameter.ActualName = AnalyzerParameter.Name;
initAnalyzerPlaceholder.Successor = resultsCollector;
resultsCollector.CollectedValues.Add(new LookupParameter("Generations"));
resultsCollector.CollectedValues.Add(new ScopeTreeLookupParameter("LayerResults", "Result set for each layer", "LayerResults"));
resultsCollector.CollectedValues.Add(new LookupParameter("OpenLayers"));
resultsCollector.CollectedValues.Add(new LookupParameter("Current Comparison Factor", null, ComparisonFactorParameter.Name));
resultsCollector.CollectedValues.Add(new LookupParameter("Current Selection Pressure", "Displays the rising selection pressure during a generation.", "SelectionPressure"));
resultsCollector.CollectedValues.Add(new LookupParameter("Current Success Ratio", "Indicates how many successful children were already found during a generation (relative to the population size).", "CurrentSuccessRatio"));
resultsCollector.CopyValue = new BoolValue(false);
resultsCollector.Successor = matingPoolPreProcessor;
matingPoolPreProcessor.Operator = matingPoolPreSorter;
matingPoolPreProcessor.Successor = matingPoolCreator;
matingPoolPreSorter.ValueParameter.ActualName = QualityParameter.Name;
matingPoolPreSorter.DescendingParameter.ActualName = MaximizationParameter.Name;
matingPoolCreator.Successor = matingPoolProcessor;
matingPoolProcessor.Parallel.Value = true;
matingPoolProcessor.Operator = initializeLayer;
matingPoolProcessor.Successor = generationsIcrementor;
initializeLayer.LeftSideParameter.ActualName = "LayerEvaluatedSolutions";
initializeLayer.RightSideParameter.Value = new IntValue(0);
initializeLayer.Successor = mainOperator;
generationsIcrementor.ValueParameter.ActualName = "Generations";
generationsIcrementor.Increment = new IntValue(1);
generationsIcrementor.Successor = evaluatedSolutionsReducer;
evaluatedSolutionsReducer.ParameterToReduce.ActualName = "LayerEvaluatedSolutions";
evaluatedSolutionsReducer.TargetParameter.ActualName = "EvaluatedSolutions";
evaluatedSolutionsReducer.ReductionOperation.Value = new ReductionOperation(ReductionOperations.Sum);
evaluatedSolutionsReducer.TargetOperation.Value = new ReductionOperation(ReductionOperations.Sum);
evaluatedSolutionsReducer.Successor = updateComparisonFactor;
updateComparisonFactor.OperatorParameter.ActualName = "ComparisonFactorModifier";
updateComparisonFactor.Successor = eldersEmigrator;
eldersEmigrator.Successor = layerUpdator;
layerUpdator.Successor = layerAnalyzerProcessor;
layerAnalyzerProcessor.Operator = layerAnalyzerPlaceholder;
layerAnalyzerProcessor.Successor = analyzerPlaceholder;
layerAnalyzerPlaceholder.OperatorParameter.ActualName = LayerAnalyzerParameter.Name;
analyzerPlaceholder.OperatorParameter.ActualName = AnalyzerParameter.Name;
analyzerPlaceholder.Successor = termination;
termination.ContinueBranch = matingPoolPreProcessor;
}
private OffspringSelectionGeneticAlgorithmMainOperator CreatePreparedOSGAMainOperator() {
var mainLoop = new OffspringSelectionGeneticAlgorithmMainOperator();
// Increment ages of all individuals after replacement (merging of elites)
var elitesMerger = mainLoop.OperatorGraph.Iterate().OfType().Last();
var incrementAgeProcessor = new UniformSubScopesProcessor();
var ageIncrementor = new IntCounter() { Name = "Increment Age" };
elitesMerger.Successor = incrementAgeProcessor;
incrementAgeProcessor.Operator = ageIncrementor;
incrementAgeProcessor.Successor = null;
ageIncrementor.ValueParameter.ActualName = "Age";
ageIncrementor.Increment = new IntValue(1);
// Insert AgeCalculator between crossover and its successor
var crossovers = mainLoop.OperatorGraph.Iterate().OfType().Where(o => o.OperatorParameter.ActualName == "Crossover");
foreach (var crossover in crossovers) {
var crossoverSuccessor = crossover.Successor;
var ageCalculator = new DataReducer() { Name = "Calculate Age" };
crossover.Successor = ageCalculator;
ageCalculator.ParameterToReduce.ActualName = "Age";
ageCalculator.TargetParameter.ActualName = "Age";
ageCalculator.ReductionOperation.Value = null;
ageCalculator.ReductionOperation.ActualName = "AgeInheritanceReduction";
ageCalculator.TargetOperation.Value = new ReductionOperation(ReductionOperations.Assign);
ageCalculator.Successor = crossoverSuccessor;
}
// When counting the evaluated solutions, write in LayerEvaluatedSolutions
var subScopesCounters = mainLoop.OperatorGraph.Iterate().OfType();
foreach (var subScopesCounter in subScopesCounters) {
subScopesCounter.ValueParameter.ActualName = "LayerEvaluatedSolutions";
}
// Parameterize
foreach (var stochasticOperator in mainLoop.OperatorGraph.Iterate().OfType())
stochasticOperator.RandomParameter.ActualName = "LocalRandom";
foreach (var stochasticBranch in mainLoop.OperatorGraph.Iterate().OfType())
stochasticBranch.RandomParameter.ActualName = "LocalRandom";
return mainLoop;
}
}
}