Index: branches/ALPS/HeuristicLab.Algorithms.ALPS.OffspringSelection/3.3/AlpsOffspringSelectionGeneticAlgorithm.cs
===================================================================
--- branches/ALPS/HeuristicLab.Algorithms.ALPS.OffspringSelection/3.3/AlpsOffspringSelectionGeneticAlgorithm.cs	(revision 12331)
+++ branches/ALPS/HeuristicLab.Algorithms.ALPS.OffspringSelection/3.3/AlpsOffspringSelectionGeneticAlgorithm.cs	(revision 12331)
@@ -0,0 +1,431 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm;
+using HeuristicLab.Analysis;
+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.PluginInfrastructure;
+using HeuristicLab.Random;
+using HeuristicLab.Selection;
+
+namespace HeuristicLab.Algorithms.ALPS.OffspringSelection {
+  [Item("ALPS Offspring Selection Genetic Algorithm", "A genetic algorithm with an age-layered population structure and Offspring Selection.")]
+  [Creatable("Algorithms")]
+  [StorableClass]
+  public sealed class AlpsOffspringSelectionGeneticAlgorithm : Alps {
+    #region Parameter Properties
+    private IValueParameter<IntArray> PopulationSizeParameter {
+      get { return (IValueParameter<IntArray>)Parameters["PopulationSize"]; }
+    }
+    public IConstrainedValueParameter<ISelector> SelectorParameter {
+      get { return (IConstrainedValueParameter<ISelector>)Parameters["Selector"]; }
+    }
+    public IConstrainedValueParameter<ICrossover> CrossoverParameter {
+      get { return (IConstrainedValueParameter<ICrossover>)Parameters["Crossover"]; }
+    }
+    private IValueParameter<PercentValue> MutationProbabilityParameter {
+      get { return (IValueParameter<PercentValue>)Parameters["MutationProbability"]; }
+    }
+    public IConstrainedValueParameter<IManipulator> MutatorParameter {
+      get { return (IConstrainedValueParameter<IManipulator>)Parameters["Mutator"]; }
+    }
+    private IValueParameter<IntValue> ElitesParameter {
+      get { return (IValueParameter<IntValue>)Parameters["Elites"]; }
+    }
+    private IFixedValueParameter<BoolValue> ReevaluateElitesParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters["ReevaluateElites"]; }
+    }
+    private IValueParameter<IntValue> MaximumGenerationsParameter {
+      get { return (IValueParameter<IntValue>)Parameters["MaximumGenerations"]; }
+    }
+    private ValueLookupParameter<DoubleValue> SuccessRatioParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["SuccessRatio"]; }
+    }
+    private ValueLookupParameter<DoubleValue> ComparisonFactorLowerBoundParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["ComparisonFactorLowerBound"]; }
+    }
+    private ValueLookupParameter<DoubleValue> ComparisonFactorUpperBoundParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["ComparisonFactorUpperBound"]; }
+    }
+    public IConstrainedValueParameter<IDiscreteDoubleValueModifier> ComparisonFactorModifierParameter {
+      get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["ComparisonFactorModifier"]; }
+    }
+    private ValueLookupParameter<DoubleValue> MaximumSelectionPressureParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["MaximumSelectionPressure"]; }
+    }
+    private ValueLookupParameter<BoolValue> OffspringSelectionBeforeMutationParameter {
+      get { return (ValueLookupParameter<BoolValue>)Parameters["OffspringSelectionBeforeMutation"]; }
+    }
+    private ValueLookupParameter<IntValue> SelectedParentsParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["SelectedParents"]; }
+    }
+    private ValueParameter<IntValue> MaximumEvaluatedSolutionsParameter {
+      get { return (ValueParameter<IntValue>)Parameters["MaximumEvaluatedSolutions"]; }
+    }
+    private IFixedValueParameter<BoolValue> FillPopulationWithParentsParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters["FillPopulationWithParents"]; }
+    }
+    #endregion
+
+    #region Properties
+    public IntArray PopulationSize {
+      get { return PopulationSizeParameter.Value; }
+      set { PopulationSizeParameter.Value = value; }
+    }
+    public ISelector Selector {
+      get { return SelectorParameter.Value; }
+      set { SelectorParameter.Value = value; }
+    }
+    public ICrossover Crossover {
+      get { return CrossoverParameter.Value; }
+      set { CrossoverParameter.Value = value; }
+    }
+    public PercentValue MutationProbability {
+      get { return MutationProbabilityParameter.Value; }
+      set { MutationProbabilityParameter.Value = value; }
+    }
+    public IManipulator Mutator {
+      get { return MutatorParameter.Value; }
+      set { MutatorParameter.Value = value; }
+    }
+    public IntValue Elites {
+      get { return ElitesParameter.Value; }
+      set { ElitesParameter.Value = value; }
+    }
+    public bool ReevaluteElites {
+      get { return ReevaluateElitesParameter.Value.Value; }
+      set { ReevaluateElitesParameter.Value.Value = value; }
+    }
+    public IntValue MaximumGenerations {
+      get { return MaximumGenerationsParameter.Value; }
+      set { MaximumGenerationsParameter.Value = value; }
+    }
+    public DoubleValue SuccessRatio {
+      get { return SuccessRatioParameter.Value; }
+      set { SuccessRatioParameter.Value = value; }
+    }
+    public DoubleValue ComparisonFactorLowerBound {
+      get { return ComparisonFactorLowerBoundParameter.Value; }
+      set { ComparisonFactorLowerBoundParameter.Value = value; }
+    }
+    public DoubleValue ComparisonFactorUpperBound {
+      get { return ComparisonFactorUpperBoundParameter.Value; }
+      set { ComparisonFactorUpperBoundParameter.Value = value; }
+    }
+    public IDiscreteDoubleValueModifier ComparisonFactorModifier {
+      get { return ComparisonFactorModifierParameter.Value; }
+      set { ComparisonFactorModifierParameter.Value = value; }
+    }
+    public DoubleValue MaximumSelectionPressure {
+      get { return MaximumSelectionPressureParameter.Value; }
+      set { MaximumSelectionPressureParameter.Value = value; }
+    }
+    public BoolValue OffspringSelectionBeforeMutation {
+      get { return OffspringSelectionBeforeMutationParameter.Value; }
+      set { OffspringSelectionBeforeMutationParameter.Value = value; }
+    }
+    public IntValue SelectedParents {
+      get { return SelectedParentsParameter.Value; }
+      set { SelectedParentsParameter.Value = value; }
+    }
+    public IntValue MaximumEvaluatedSolutions {
+      get { return MaximumEvaluatedSolutionsParameter.Value; }
+      set { MaximumEvaluatedSolutionsParameter.Value = value; }
+    }
+    public bool FillPopulationWithParents {
+      get { return FillPopulationWithParentsParameter.Value.Value; }
+      set { FillPopulationWithParentsParameter.Value.Value = value; }
+    }
+
+    private AlpsOffspringSelectionGeneticAlgorithmMainLoop MainLoop {
+      get { return OperatorGraph.Iterate().OfType<AlpsOffspringSelectionGeneticAlgorithmMainLoop>().First(); }
+    }
+    #endregion
+
+    [Storable]
+    private ValueAnalyzer selectionPressureAnalyzer;
+    [Storable]
+    private SuccessfulOffspringAnalyzer successfulOffspringAnalyzer;
+
+    [StorableConstructor]
+    private AlpsOffspringSelectionGeneticAlgorithm(bool deserializing)
+      : base(deserializing) { }
+    private AlpsOffspringSelectionGeneticAlgorithm(AlpsOffspringSelectionGeneticAlgorithm original, Cloner cloner)
+      : base(original, cloner) {
+      selectionPressureAnalyzer = cloner.Clone(original.selectionPressureAnalyzer);
+      successfulOffspringAnalyzer = cloner.Clone(original.successfulOffspringAnalyzer);
+      Initialize();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AlpsOffspringSelectionGeneticAlgorithm(this, cloner);
+    }
+
+    public AlpsOffspringSelectionGeneticAlgorithm()
+      : base() {
+      Parameters.Add(new ValueParameter<IntArray>("PopulationSize", "The size of the population of solutions each layer.", new IntArray(new[] { 100 })));
+      Parameters.Add(new ConstrainedValueParameter<ISelector>("Selector", "The operator used to select solutions for reproduction."));
+      Parameters.Add(new ConstrainedValueParameter<ICrossover>("Crossover", "The operator used to cross solutions."));
+      Parameters.Add(new ValueParameter<PercentValue>("MutationProbability", "The probability that the mutation operator is applied on a solution.", new PercentValue(0.05)));
+      Parameters.Add(new OptionalConstrainedValueParameter<IManipulator>("Mutator", "The operator used to mutate solutions."));
+      Parameters.Add(new ValueParameter<IntValue>("Elites", "The numer of elite solutions which are kept in each generation.", new IntValue(1)));
+      Parameters.Add(new FixedValueParameter<BoolValue>("ReevaluateElites", "Flag to determine if elite individuals should be reevaluated (i.e., if stochastic fitness functions are used.)", new BoolValue(false)) { Hidden = true });
+      Parameters.Add(new ValueParameter<IntValue>("MaximumGenerations", "The maximum number of generations which should be processed.", new IntValue(1000)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("SuccessRatio", "The ratio of successful to total children that should be achieved.", new DoubleValue(1)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("ComparisonFactorLowerBound", "The lower bound of the comparison factor (start).", new DoubleValue(0)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("ComparisonFactorUpperBound", "The upper bound of the comparison factor (end).", new DoubleValue(1)));
+      Parameters.Add(new OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>("ComparisonFactorModifier", "The operator used to modify the comparison factor.", new ItemSet<IDiscreteDoubleValueModifier>(new IDiscreteDoubleValueModifier[] { new LinearDiscreteDoubleValueModifier() }), new LinearDiscreteDoubleValueModifier()));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("MaximumSelectionPressure", "The maximum selection pressure that terminates the algorithm.", new DoubleValue(100)));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("OffspringSelectionBeforeMutation", "True if the offspring selection step should be applied before mutation, false if it should be applied after mutation.", new BoolValue(false)));
+      Parameters.Add(new ValueLookupParameter<IntValue>("SelectedParents", "How much parents should be selected each time the offspring selection step is performed until the population is filled. This parameter should be about the same or twice the size of PopulationSize for smaller problems, and less for large problems.", new IntValue(200)));
+      Parameters.Add(new ValueParameter<IntValue>("MaximumEvaluatedSolutions", "The maximum number of evaluated solutions (approximately).", new IntValue(int.MaxValue)));
+      Parameters.Add(new FixedValueParameter<BoolValue>("FillPopulationWithParents", "True if the population should be filled with parent individual or false if worse children should be used when the maximum selection pressure is exceeded.", new BoolValue(false)) { Hidden = true });
+
+      var globalRandomCreator = new RandomCreator();
+      var layer0Creator = new SubScopesCreator() { Name = "Create Layer Zero" };
+      var layer0Processor = new LayerUniformSubScopesProcessor();
+      var localRandomCreator = new LocalRandomCreator();
+      var layerVariableCreator = new VariableCreator();
+      var layerSolutionsCreator = new SolutionsCreator();
+      var initializeAgeProcessor = new UniformSubScopesProcessor();
+      var initializeAge = new VariableCreator() { Name = "Initialize Age" };
+      var initializeLayerPopulationSize = new SubScopesCounter() { Name = "Init LayerPopulationCounter" };
+      var initializeLocalEvaluatedSolutions = new Assigner() { Name = "Initialize LayerEvaluatedSolutions" };
+      var initializeGlobalEvaluatedSolutions = new DataReducer() { Name = "Initialize EvaluatedSolutions" };
+      var resultsCollector = new ResultsCollector();
+      var mainLoop = new AlpsOffspringSelectionGeneticAlgorithmMainLoop();
+
+      OperatorGraph.InitialOperator = globalRandomCreator;
+
+      globalRandomCreator.RandomParameter.ActualName = "GlobalRandom";
+      globalRandomCreator.SeedParameter.Value = null;
+      globalRandomCreator.SetSeedRandomlyParameter.Value = null;
+      globalRandomCreator.Successor = layer0Creator;
+
+      layer0Creator.NumberOfSubScopesParameter.Value = new IntValue(1);
+      layer0Creator.Successor = layer0Processor;
+
+      layer0Processor.Operator = localRandomCreator;
+      layer0Processor.Successor = initializeGlobalEvaluatedSolutions;
+
+      localRandomCreator.Successor = layerVariableCreator;
+
+      layerVariableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Layer", new IntValue(0)));
+      layerVariableCreator.Successor = layerSolutionsCreator;
+
+      layerSolutionsCreator.NumberOfSolutionsParameter.ActualName = PopulationSizeParameter.Name;
+      layerSolutionsCreator.Successor = initializeAgeProcessor;
+
+      initializeAgeProcessor.Operator = initializeAge;
+      initializeAgeProcessor.Successor = initializeLayerPopulationSize;
+
+      initializeLayerPopulationSize.ValueParameter.ActualName = "LayerPopulationSize";
+      initializeLayerPopulationSize.Successor = initializeLocalEvaluatedSolutions;
+
+      initializeAge.CollectedValues.Add(new ValueParameter<IntValue>("Age", new IntValue(0)));
+      initializeAge.Successor = null;
+
+      initializeLocalEvaluatedSolutions.LeftSideParameter.ActualName = "LayerEvaluatedSolutions";
+      initializeLocalEvaluatedSolutions.RightSideParameter.ActualName = "LayerPopulationSize";
+      initializeLocalEvaluatedSolutions.Successor = null;
+
+      initializeGlobalEvaluatedSolutions.ReductionOperation.Value.Value = ReductionOperations.Sum;
+      initializeGlobalEvaluatedSolutions.TargetOperation.Value.Value = ReductionOperations.Assign;
+      initializeGlobalEvaluatedSolutions.ParameterToReduce.ActualName = "LayerEvaluatedSolutions";
+      initializeGlobalEvaluatedSolutions.TargetParameter.ActualName = "EvaluatedSolutions";
+      initializeGlobalEvaluatedSolutions.Successor = resultsCollector;
+
+      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Evaluated Solutions", null, "EvaluatedSolutions"));
+      resultsCollector.Successor = mainLoop;
+
+      mainLoop.ComparisonFactorModifierParameter.ActualName = ComparisonFactorModifierParameter.Name;
+      mainLoop.ComparisonFactorParameter.ActualName = "ComparisonFactor";
+      mainLoop.ComparisonFactorStartParameter.ActualName = ComparisonFactorLowerBoundParameter.Name;
+
+
+      foreach (var selector in ApplicationManager.Manager.GetInstances<ISelector>().Where(s => !(s is IMultiObjectiveSelector)).OrderBy(s => Name))
+        SelectorParameter.ValidValues.Add(selector);
+      var tournamentSelector = SelectorParameter.ValidValues.OfType<TournamentSelector>().FirstOrDefault();
+      if (tournamentSelector != null) {
+        tournamentSelector.GroupSizeParameter.Value = new IntValue(4);
+        SelectorParameter.Value = tournamentSelector;
+      }
+      ParameterizeSelectors();
+
+      foreach (IDiscreteDoubleValueModifier modifier in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name))
+        ComparisonFactorModifierParameter.ValidValues.Add(modifier);
+      IDiscreteDoubleValueModifier linearModifier = ComparisonFactorModifierParameter.ValidValues.FirstOrDefault(x => x.GetType().Name.Equals("LinearDiscreteDoubleValueModifier"));
+      if (linearModifier != null) ComparisonFactorModifierParameter.Value = linearModifier;
+      ParameterizeComparisonFactorModifiers();
+
+      selectionPressureAnalyzer = new ValueAnalyzer();
+      successfulOffspringAnalyzer = new SuccessfulOffspringAnalyzer();
+      selectionPressureAnalyzer.Name = "SelectionPressure Analyzer";
+      selectionPressureAnalyzer.ResultsParameter.ActualName = "Results";
+      selectionPressureAnalyzer.ValueParameter.ActualName = "SelectionPressure";
+      selectionPressureAnalyzer.ValueParameter.Depth = 0;
+      selectionPressureAnalyzer.ValuesParameter.ActualName = "Selection Pressure History";
+      successfulOffspringAnalyzer.ResultsParameter.ActualName = "Results";
+      successfulOffspringAnalyzer.GenerationsParameter.ActualName = "Generations";
+      successfulOffspringAnalyzer.SuccessfulOffspringFlagParameter.Value.Value = "SuccessfulOffspring";
+      successfulOffspringAnalyzer.DepthParameter.Value = new IntValue(1);
+
+      Initialize();
+    }
+
+    #region Events
+    protected override void OnProblemChanged() {
+      base.OnProblemChanged();
+      ParameterizeSolutionsCreator();
+      ParameterizeMainLoop();
+      ParameterizeSelectors();
+      ParameterizeIterationBasedOperators();
+      UpdateCrossovers();
+      UpdateMutators();
+    }
+    protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
+      base.Problem_SolutionCreatorChanged(sender, e);
+      ParameterizeSolutionsCreator();
+    }
+    protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
+      base.Problem_EvaluatorChanged(sender, e);
+      ParameterizeSolutionsCreator();
+      ParameterizeMainLoop();
+      ParameterizeSelectors();
+    }
+    protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
+      base.Problem_OperatorsChanged(sender, e);
+      ParameterizeIterationBasedOperators();
+      UpdateCrossovers();
+      UpdateMutators();
+    }
+    protected override void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
+      base.Evaluator_QualityParameter_ActualNameChanged(sender, e);
+      ParameterizeMainLoop();
+      ParameterizeSelectors();
+    }
+    #endregion
+    #region Parameterization
+    private void Initialize() {
+    }
+    private void ParameterizeSolutionsCreator() {
+      MainLoop.LayerUpdator.SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
+      MainLoop.LayerUpdator.SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
+    }
+    private void ParameterizeMainLoop() {
+      MainLoop.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+      MainLoop.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+      MainLoop.MainOperator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
+      MainLoop.MainOperator.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+      MainLoop.MainOperator.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+      MainLoop.LayerUpdator.SolutionsCreator.NumberOfSolutionsParameter.ActualName = PopulationSizeParameter.Name;
+    }
+    private void ParameterizeSelectors() {
+      foreach (var selector in SelectorParameter.ValidValues) {
+        selector.CopySelected = new BoolValue(true);
+        selector.NumberOfSelectedSubScopesParameter.Value = null;
+        selector.NumberOfSelectedSubScopesParameter.ActualName = SelectedParentsParameter.Name;
+        selector.NumberOfSelectedSubScopesParameter.Hidden = true;
+        ParameterizeStochasticOperatorForLayer(selector);
+      }
+      if (Problem != null) {
+        foreach (var selector in SelectorParameter.ValidValues.OfType<ISingleObjectiveSelector>()) {
+          selector.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+          selector.MaximizationParameter.Hidden = true;
+          selector.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+          selector.QualityParameter.Hidden = true;
+        }
+      }
+    }
+    private void ParameterizeComparisonFactorModifiers() {
+      foreach (IDiscreteDoubleValueModifier modifier in ComparisonFactorModifierParameter.ValidValues) {
+        modifier.IndexParameter.ActualName = "Generations";
+        modifier.EndIndexParameter.ActualName = MaximumGenerationsParameter.Name;
+        modifier.EndValueParameter.ActualName = ComparisonFactorUpperBoundParameter.Name;
+        modifier.StartIndexParameter.Value = new IntValue(0);
+        modifier.StartValueParameter.ActualName = ComparisonFactorLowerBoundParameter.Name;
+        modifier.ValueParameter.ActualName = "ComparisonFactor";
+      }
+    }
+    private void ParameterizeIterationBasedOperators() {
+      if (Problem != null) {
+        foreach (var @operator in Problem.Operators.OfType<IIterationBasedOperator>()) {
+          @operator.IterationsParameter.ActualName = "Generations";
+          @operator.IterationsParameter.Hidden = true;
+          @operator.MaximumIterationsParameter.ActualName = MaximumGenerationsParameter.Name;
+          @operator.MaximumIterationsParameter.Hidden = true;
+        }
+      }
+    }
+
+    protected override ReductionOperations GetAgeInheritanceReduction(AgeInheritance ageInheritance) {
+      switch (ageInheritance) {
+        case ALPS.AgeInheritance.Older: return ReductionOperations.Max;
+        case ALPS.AgeInheritance.Agerage: return ReductionOperations.Avg;
+        case ALPS.AgeInheritance.Younger: return ReductionOperations.Min;
+        default: throw new NotSupportedException("AgeInheritance " + ageInheritance + " is not supported.");
+      }
+    }
+    #endregion
+
+    #region Updates
+    private void UpdateCrossovers() {
+      var oldCrossover = CrossoverParameter.Value;
+      var defaultCrossover = Problem.Operators.OfType<ICrossover>().FirstOrDefault();
+      CrossoverParameter.ValidValues.Clear();
+      foreach (var crossover in Problem.Operators.OfType<ICrossover>().OrderBy(c => c.Name)) {
+        ParameterizeStochasticOperatorForLayer(crossover);
+        CrossoverParameter.ValidValues.Add(crossover);
+      }
+      if (oldCrossover != null) {
+        var crossover = CrossoverParameter.ValidValues.FirstOrDefault(c => c.GetType() == oldCrossover.GetType());
+        if (crossover != null)
+          CrossoverParameter.Value = crossover;
+        else
+          oldCrossover = null;
+      }
+      if (oldCrossover == null && defaultCrossover != null)
+        CrossoverParameter.Value = defaultCrossover;
+    }
+    private void UpdateMutators() {
+      var oldMutator = MutatorParameter.Value;
+      MutatorParameter.ValidValues.Clear();
+      foreach (var mutator in Problem.Operators.OfType<IManipulator>().OrderBy(m => m.Name)) {
+        ParameterizeStochasticOperatorForLayer(mutator);
+        MutatorParameter.ValidValues.Add(mutator);
+      }
+      if (oldMutator != null) {
+        var mutator = MutatorParameter.ValidValues.FirstOrDefault(m => m.GetType() == oldMutator.GetType());
+        if (mutator != null)
+          MutatorParameter.Value = mutator;
+      }
+    }
+    #endregion
+  }
+}
Index: branches/ALPS/HeuristicLab.Algorithms.ALPS.OffspringSelection/3.3/AlpsOffspringSelectionGeneticAlgorithmMainLoop.cs
===================================================================
--- branches/ALPS/HeuristicLab.Algorithms.ALPS.OffspringSelection/3.3/AlpsOffspringSelectionGeneticAlgorithmMainLoop.cs	(revision 12331)
+++ branches/ALPS/HeuristicLab.Algorithms.ALPS.OffspringSelection/3.3/AlpsOffspringSelectionGeneticAlgorithmMainLoop.cs	(revision 12331)
@@ -0,0 +1,247 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#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<BoolValue> MaximizationParameter {
+      get { return (ValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<IntValue> MaximumGenerationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["MaximumGenerations"]; }
+    }
+    public ILookupParameter<IOperator> AnalyzerParameter {
+      get { return (ILookupParameter<IOperator>)Parameters["Analyzer"]; }
+    }
+    public ILookupParameter<IOperator> LayerAnalyzerParameter {
+      get { return (ILookupParameter<IOperator>)Parameters["LayerAnalyzer"]; }
+    }
+    public LookupParameter<DoubleValue> ComparisonFactorParameter {
+      get { return (LookupParameter<DoubleValue>)Parameters["ComparisonFactor"]; }
+    }
+    public ValueLookupParameter<DoubleValue> ComparisonFactorStartParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["ComparisonFactorStart"]; }
+    }
+    public ValueLookupParameter<IOperator> ComparisonFactorModifierParameter {
+      get { return (ValueLookupParameter<IOperator>)Parameters["ComparisonFactorModifier"]; }
+    }
+    #endregion
+
+    public OffspringSelectionGeneticAlgorithmMainOperator MainOperator {
+      get { return OperatorGraph.Iterate().OfType<OffspringSelectionGeneticAlgorithmMainOperator>().First(); }
+    }
+    public EldersEmigrator EldersEmigrator {
+      get { return OperatorGraph.Iterate().OfType<EldersEmigrator>().First(); }
+    }
+    public LayerUpdator LayerUpdator {
+      get { return OperatorGraph.Iterate().OfType<LayerUpdator>().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<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The value which represents the quality of a solution."));
+      Parameters.Add(new LookupParameter<IntValue>("MaximumGenerations", "The maximum number of generations that the algorithm should process."));
+      Parameters.Add(new LookupParameter<IOperator>("Analyzer", "The operator used to the analyze all individuals."));
+      Parameters.Add(new LookupParameter<IOperator>("LayerAnalyzer", "The operator used to analyze each layer."));
+      Parameters.Add(new LookupParameter<DoubleValue>("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<DoubleValue>("ComparisonFactorStart", "The initial value for the comparison factor."));
+      Parameters.Add(new ValueLookupParameter<IOperator>("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 generationsComparator = new Comparator() { Name = "Generations >= MaximumGenerations" };
+      var terminateBranch = new ConditionalBranch() { Name = "Terminate?" };
+
+      OperatorGraph.InitialOperator = variableCreator;
+
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Generations", new IntValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("GenerationsSinceLastRefresh", new IntValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("OpenLayers", new IntValue(1)));
+      variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("SelectionPressure", new DoubleValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("CurrentSuccessRatio", new DoubleValue(0)));
+      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<IntValue>("LayerEvaluatedSolutions"));
+      layerVariableCreator.CollectedValues.Add(new ValueParameter<ResultCollection>("LayerResults"));
+      layerVariableCreator.Successor = initLayerAnalyzerPlaceholder;
+
+      initLayerAnalyzerPlaceholder.OperatorParameter.ActualName = LayerAnalyzerParameter.Name;
+      initLayerAnalyzerPlaceholder.Successor = null;
+
+      initAnalyzerPlaceholder.OperatorParameter.ActualName = AnalyzerParameter.Name;
+      initAnalyzerPlaceholder.Successor = resultsCollector;
+
+      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Generations"));
+      resultsCollector.CollectedValues.Add(new ScopeTreeLookupParameter<ResultCollection>("LayerResults", "Result set for each layer", "LayerResults"));
+      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("OpenLayers"));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Comparison Factor", null, ComparisonFactorParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Selection Pressure", "Displays the rising selection pressure during a generation.", "SelectionPressure"));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("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 = generationsComparator;
+
+      generationsComparator.Comparison = new Comparison(ComparisonType.GreaterOrEqual);
+      generationsComparator.LeftSideParameter.ActualName = "Generations";
+      generationsComparator.RightSideParameter.ActualName = MaximumGenerationsParameter.Name;
+      generationsComparator.ResultParameter.ActualName = "TerminateGenerations";
+      generationsComparator.Successor = terminateBranch;
+
+      terminateBranch.ConditionParameter.ActualName = "TerminateGenerations";
+      terminateBranch.FalseBranch = matingPoolPreProcessor;
+    }
+
+    private OffspringSelectionGeneticAlgorithmMainOperator CreatePreparedOSGAMainOperator() {
+      var mainLoop = new OffspringSelectionGeneticAlgorithmMainOperator();
+
+      // Increment ages of all individuals after replacement (merging of elites)
+      var elitesMerger = mainLoop.OperatorGraph.Iterate().OfType<MergingReducer>().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<Placeholder>().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<SubScopesCounter>();
+      foreach (var subScopesCounter in subScopesCounters) {
+        subScopesCounter.ValueParameter.ActualName = "LayerEvaluatedSolutions";
+      }
+
+      // Parameterize
+      foreach (var stochasticOperator in mainLoop.OperatorGraph.Iterate().OfType<IStochasticOperator>())
+        stochasticOperator.RandomParameter.ActualName = "LocalRandom";
+      foreach (var stochasticBranch in mainLoop.OperatorGraph.Iterate().OfType<StochasticBranch>())
+        stochasticBranch.RandomParameter.ActualName = "LocalRandom";
+
+      return mainLoop;
+    }
+  }
+}
Index: branches/ALPS/HeuristicLab.Algorithms.ALPS.OffspringSelection/3.3/HeuristicLab.Algorithms.ALPS.OffspringSelection-3.3.csproj
===================================================================
--- branches/ALPS/HeuristicLab.Algorithms.ALPS.OffspringSelection/3.3/HeuristicLab.Algorithms.ALPS.OffspringSelection-3.3.csproj	(revision 12330)
+++ branches/ALPS/HeuristicLab.Algorithms.ALPS.OffspringSelection/3.3/HeuristicLab.Algorithms.ALPS.OffspringSelection-3.3.csproj	(revision 12331)
@@ -73,4 +73,12 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+    </Reference>
     <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -113,4 +121,12 @@
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
     </Reference>
+    <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Selection-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Selection-3.3.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
@@ -118,4 +134,6 @@
   <ItemGroup>
     <None Include="Plugin.cs.frame" />
+    <Compile Include="AlpsOffspringSelectionGeneticAlgorithm.cs" />
+    <Compile Include="AlpsOffspringSelectionGeneticAlgorithmMainLoop.cs" />
     <Compile Include="Plugin.cs" />
     <None Include="Properties\AssemblyInfo.cs.frame" />
