Index: /trunk/sources/HeuristicLab 3.3.sln
===================================================================
--- /trunk/sources/HeuristicLab 3.3.sln	(revision 3378)
+++ /trunk/sources/HeuristicLab 3.3.sln	(revision 3379)
@@ -1235,5 +1235,4 @@
 		{125D3006-67F5-48CB-913E-73C0548F17FA}.Services|x86.ActiveCfg = Release|x86
 		{F5C0ECAC-EDBA-4024-872A-1F74AFCB20B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{F5C0ECAC-EDBA-4024-872A-1F74AFCB20B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{F5C0ECAC-EDBA-4024-872A-1F74AFCB20B4}.Debug|x64.ActiveCfg = Debug|x64
 		{F5C0ECAC-EDBA-4024-872A-1F74AFCB20B4}.Debug|x64.Build.0 = Debug|x64
@@ -1250,5 +1249,4 @@
 		{F5C0ECAC-EDBA-4024-872A-1F74AFCB20B4}.Services|x86.ActiveCfg = Release|x86
 		{30DD3DA2-CA57-49DD-A5BA-50CEF19DB45F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{30DD3DA2-CA57-49DD-A5BA-50CEF19DB45F}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{30DD3DA2-CA57-49DD-A5BA-50CEF19DB45F}.Debug|x64.ActiveCfg = Debug|x64
 		{30DD3DA2-CA57-49DD-A5BA-50CEF19DB45F}.Debug|x64.Build.0 = Debug|x64
Index: /trunk/sources/HeuristicLab 3.3/Files.txt
===================================================================
--- /trunk/sources/HeuristicLab 3.3/Files.txt	(revision 3378)
+++ /trunk/sources/HeuristicLab 3.3/Files.txt	(revision 3379)
@@ -8,4 +8,5 @@
 HeuristicLab.Algorithms.LocalSearch\3.3:HeuristicLab.Algorithms.LocalSearch-3.3.dll
 HeuristicLab.Algorithms.MultipopulationAlgorithm\3.3:HeuristicLab.Algorithms.MultipopulationAlgorithm-3.3.dll
+HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm\3.3:HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm-3.3.dll
 HeuristicLab.Algorithms.ParticleSwarmOptimization\3.3:HeuristicLab.Algorithms.ParticleSwarmOptimization-3.3.dll
 HeuristicLab.Algorithms.SimulatedAnnealing\3.3:HeuristicLab.Algorithms.SimulatedAnnealing-3.3.dll
Index: /trunk/sources/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/OffspringSelectionGeneticAlgorithm.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/OffspringSelectionGeneticAlgorithm.cs	(revision 3378)
+++ /trunk/sources/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/OffspringSelectionGeneticAlgorithm.cs	(revision 3379)
@@ -38,5 +38,5 @@
   /// An offspring selection genetic algorithm.
   /// </summary>
-  [Item("Offspring Selection Genetic Algorithm", "An offspring selection genetic algorithm (Affenzeller, M. and Wagner, S. 2005. Offspring Selection: A New Self-Adaptive Selection Scheme for Genetic Algorithms. Adaptive and Natural Computing Algorithms, pp. 218-221, Springer).")]
+  [Item("Offspring Selection Genetic Algorithm", "An offspring selection genetic algorithm (Affenzeller, M. et al. 2009. Genetic Algorithms and Genetic Programming - Modern Concepts and Practical Applications. CRC Press).")]
   [Creatable("Algorithms")]
   [StorableClass]
@@ -80,4 +80,22 @@
       get { return (ValueParameter<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"]; }
+    }
+    private ConstrainedValueParameter<IDiscreteDoubleValueModifier> ComparisonFactorModifierParameter {
+      get { return (ConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["ComparisonFactorModifier"]; }
+    }
+    private ValueLookupParameter<DoubleValue> MaximumSelectionPressureParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["MaximumSelectionPressure"]; }
+    }
+    private ValueLookupParameter<BoolValue> OffspringSelectionBeforeMutationParameter {
+      get { return (ValueLookupParameter<BoolValue>)Parameters["OffspringSelectionBeforeMutation"]; }
+    }
     #endregion
 
@@ -119,4 +137,28 @@
       set { MaximumGenerationsParameter.Value = value; }
     }
+    private DoubleValue SuccessRatio {
+      get { return SuccessRatioParameter.Value; }
+      set { SuccessRatioParameter.Value = value; }
+    }
+    private DoubleValue ComparisonFactorLowerBound {
+      get { return ComparisonFactorLowerBoundParameter.Value; }
+      set { ComparisonFactorLowerBoundParameter.Value = value; }
+    }
+    private DoubleValue ComparisonFactorUpperBound {
+      get { return ComparisonFactorUpperBoundParameter.Value; }
+      set { ComparisonFactorUpperBoundParameter.Value = value; }
+    }
+    private IDiscreteDoubleValueModifier ComparisonFactorModifier {
+      get { return ComparisonFactorModifierParameter.Value; }
+      set { ComparisonFactorModifierParameter.Value = value; }
+    }
+    private DoubleValue MaximumSelectionPressure {
+      get { return MaximumSelectionPressureParameter.Value; }
+      set { MaximumSelectionPressureParameter.Value = value; }
+    }
+    private BoolValue OffspringSelectionBeforeMutation {
+      get { return OffspringSelectionBeforeMutationParameter.Value; }
+      set { OffspringSelectionBeforeMutationParameter.Value = value; }
+    }
     private RandomCreator RandomCreator {
       get { return (RandomCreator)OperatorGraph.InitialOperator; }
@@ -132,6 +174,9 @@
       get { return selectors; }
     }
+    private List<IDiscreteDoubleValueModifier> comparisonFactorModifiers;
     #endregion
 
+    [StorableConstructor]
+    private OffspringSelectionGeneticAlgorithm(bool deserializing) : base(deserializing) { }
     public OffspringSelectionGeneticAlgorithm()
       : base() {
@@ -145,4 +190,10 @@
       Parameters.Add(new ValueParameter<IntValue>("Elites", "The numer of elite solutions which are kept in each generation.", new IntValue(1)));
       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 ConstrainedValueParameter<IDiscreteDoubleValueModifier>("ComparisonFactorModifier", "The operator used to modify the comparison factor."));
+      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)));
 
       RandomCreator randomCreator = new RandomCreator();
@@ -161,4 +212,5 @@
       solutionsCreator.Successor = mainLoop;
 
+      mainLoop.PopulationSizeParameter.ActualName = PopulationSizeParameter.Name;
       mainLoop.SelectorParameter.ActualName = SelectorParameter.Name;
       mainLoop.CrossoverParameter.ActualName = CrossoverParameter.Name;
@@ -172,6 +224,4 @@
       Initialize();
     }
-    [StorableConstructor]
-    private OffspringSelectionGeneticAlgorithm(bool deserializing) : base(deserializing) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -192,5 +242,5 @@
       foreach (IOperator op in Problem.Operators) ParameterizeStochasticOperator(op);
       ParameterizeSolutionsCreator();
-      ParameterizeGeneticAlgorithmMainLoop();
+      ParameterizMainLoop();
       ParameterizeSelectors();
       UpdateCrossovers();
@@ -209,5 +259,5 @@
       ParameterizeStochasticOperator(Problem.Evaluator);
       ParameterizeSolutionsCreator();
-      ParameterizeGeneticAlgorithmMainLoop();
+      ParameterizMainLoop();
       ParameterizeSelectors();
       Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
@@ -216,5 +266,5 @@
     protected override void Problem_VisualizerChanged(object sender, EventArgs e) {
       ParameterizeStochasticOperator(Problem.Visualizer);
-      ParameterizeGeneticAlgorithmMainLoop();
+      ParameterizMainLoop();
       if (Problem.Visualizer != null) Problem.Visualizer.VisualizationParameter.ActualNameChanged += new EventHandler(Visualizer_VisualizationParameter_ActualNameChanged);
       base.Problem_VisualizerChanged(sender, e);
@@ -235,15 +285,17 @@
     private void PopulationSizeParameter_ValueChanged(object sender, EventArgs e) {
       PopulationSize.ValueChanged += new EventHandler(PopulationSize_ValueChanged);
+      MainLoop.PopulationSizeParameter.Value = new IntValue(PopulationSize.Value - Elites.Value);
       ParameterizeSelectors();
     }
     private void PopulationSize_ValueChanged(object sender, EventArgs e) {
+      MainLoop.PopulationSizeParameter.Value = new IntValue(PopulationSize.Value - Elites.Value);
       ParameterizeSelectors();
     }
     private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
-      ParameterizeGeneticAlgorithmMainLoop();
+      ParameterizMainLoop();
       ParameterizeSelectors();
     }
     private void Visualizer_VisualizationParameter_ActualNameChanged(object sender, EventArgs e) {
-      ParameterizeGeneticAlgorithmMainLoop();
+      ParameterizMainLoop();
     }
     #endregion
@@ -254,4 +306,6 @@
       InitializeSelectors();
       UpdateSelectors();
+      InitializeComparisonFactorModifiers();
+      UpdateComparisonFactorModifiers();
       PopulationSizeParameter.ValueChanged += new EventHandler(PopulationSizeParameter_ValueChanged);
       PopulationSize.ValueChanged += new EventHandler(PopulationSize_ValueChanged);
@@ -270,5 +324,5 @@
       SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
     }
-    private void ParameterizeGeneticAlgorithmMainLoop() {
+    private void ParameterizMainLoop() {
       MainLoop.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
       MainLoop.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
@@ -288,4 +342,9 @@
       ParameterizeSelectors();
     }
+    private void InitializeComparisonFactorModifiers() {
+      comparisonFactorModifiers = new List<IDiscreteDoubleValueModifier>();
+      comparisonFactorModifiers.AddRange(ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name));
+      ParameterizeComparisonFactorModifiers();
+    }
     private void ParameterizeSelectors() {
       foreach (ISelector selector in Selectors) {
@@ -301,4 +360,14 @@
       }
     }
+    private void ParameterizeComparisonFactorModifiers() {
+      foreach (IDiscreteDoubleValueModifier modifier in comparisonFactorModifiers) {
+        modifier.IndexParameter.ActualName = "Generations"; // FIXME: hmmm, not so good, this variable is defined within the main loop
+        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"; // FIXME: hmmm, not so good, this variable is defined within the main loop
+      }
+    }
     private void UpdateSelectors() {
       ISelector oldSelector = SelectorParameter.Value;
@@ -314,4 +383,14 @@
         if (selector != null) SelectorParameter.Value = selector;
       }
+    }
+    private void UpdateComparisonFactorModifiers() {
+      IDiscreteDoubleValueModifier oldModifier = ComparisonFactorModifier;
+      ComparisonFactorModifierParameter.ValidValues.Clear();
+      foreach (IDiscreteDoubleValueModifier modifier in comparisonFactorModifiers)
+        ComparisonFactorModifierParameter.ValidValues.Add(modifier);
+      if (oldModifier != null) {
+        IDiscreteDoubleValueModifier modifier = ComparisonFactorModifierParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldModifier.GetType());
+        if (modifier != null) ComparisonFactorModifierParameter.Value = modifier;
+      } else if (ComparisonFactorModifierParameter.ValidValues.Count > 0) ComparisonFactorModifierParameter.Value = ComparisonFactorModifierParameter.ValidValues.First();
     }
     private void UpdateCrossovers() {
Index: /trunk/sources/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/OffspringSelectionGeneticAlgorithmMainLoop.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/OffspringSelectionGeneticAlgorithmMainLoop.cs	(revision 3378)
+++ /trunk/sources/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/OffspringSelectionGeneticAlgorithmMainLoop.cs	(revision 3379)
@@ -181,4 +181,5 @@
 
       variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Generations", new IntValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("SelectionPressure", new DoubleValue(0)));
       variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("CurrentSuccessRatio", new DoubleValue(0)));
 
Index: /trunk/sources/HeuristicLab.Optimization.Operators/3.3/OffspringSelector.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization.Operators/3.3/OffspringSelector.cs	(revision 3378)
+++ /trunk/sources/HeuristicLab.Optimization.Operators/3.3/OffspringSelector.cs	(revision 3379)
@@ -38,5 +38,5 @@
     }
     public ValueLookupParameter<DoubleValue> MaximumSelectionPressureParameter {
-      get { return (ValueLookupParameter<DoubleValue>)Parameters["MaximiumSelectionPressure"]; }
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["MaximumSelectionPressure"]; }
     }
     public ValueLookupParameter<DoubleValue> SuccessRatioParameter {
@@ -49,6 +49,6 @@
       get { return (LookupParameter<DoubleValue>)Parameters["CurrentSuccessRatio"]; }
     }
-    public SubScopesLookupParameter<BoolValue> SuccessfulOffspringParameter {
-      get { return (SubScopesLookupParameter<BoolValue>)Parameters["SuccessfulOffspring"]; }
+    public SelectedSubScopesLookupParameter<BoolValue> SuccessfulOffspringParameter {
+      get { return (SelectedSubScopesLookupParameter<BoolValue>)Parameters["SuccessfulOffspring"]; }
     }
     public LookupParameter<ItemList<IScope>> WinnersParameter {
@@ -74,5 +74,5 @@
       Parameters.Add(new ValueLookupParameter<DoubleValue>("SelectionPressure", "The amount of selection pressure currently necessary to fulfill the success ratio."));
       Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentSuccessRatio", "The current success ratio indicates how much of the successful offspring have already been generated."));
-      Parameters.Add(new SubScopesLookupParameter<BoolValue>("SuccessfulOffspring", "True if the offspring was successful, otherwise false."));
+      Parameters.Add(new SelectedSubScopesLookupParameter<BoolValue>("SuccessfulOffspring", "True if the offspring was successful, otherwise false."));
       Parameters.Add(new LookupParameter<ItemList<IScope>>("Winners", "Temporary store of the successful offspring."));
       Parameters.Add(new LookupParameter<ItemList<IScope>>("LuckyLosers", "Temporary store of the lucky losers."));
@@ -145,6 +145,6 @@
         scope.SubScopes.Remove(parents);
         scope.SubScopes.Remove(children);
-        for (int i = 0; i < parents.SubScopes.Count; i++)
-          scope.SubScopes.Add(parents.SubScopes[i]);
+        while(parents.SubScopes.Count > 0)
+          scope.SubScopes.Add(parents.SubScopes[0]);
 
         IOperator moreOffspring = OffspringCreatorParameter.ActualValue as IOperator;
Index: /trunk/sources/HeuristicLab.Parameters/3.3/HeuristicLab.Parameters-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Parameters/3.3/HeuristicLab.Parameters-3.3.csproj	(revision 3378)
+++ /trunk/sources/HeuristicLab.Parameters/3.3/HeuristicLab.Parameters-3.3.csproj	(revision 3379)
@@ -86,4 +86,5 @@
     <None Include="HeuristicLabParametersPlugin.cs.frame" />
     <Compile Include="ConstrainedValueParameter.cs" />
+    <Compile Include="SelectedSubScopesLookupParameter.cs" />
     <Compile Include="OptionalConstrainedValueParameter.cs" />
     <Compile Include="ValueParameter.cs" />
Index: /trunk/sources/HeuristicLab.Parameters/3.3/SelectedSubScopesLookupParameter.cs
===================================================================
--- /trunk/sources/HeuristicLab.Parameters/3.3/SelectedSubScopesLookupParameter.cs	(revision 3379)
+++ /trunk/sources/HeuristicLab.Parameters/3.3/SelectedSubScopesLookupParameter.cs	(revision 3379)
@@ -0,0 +1,81 @@
+#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Parameters {
+  /// <summary>
+  /// A generic parameter representing instances of type T which are collected from the sub-scopes of the current scope.
+  /// </summary>
+  [Item("SelectedSubScopesLookupParameter<T>", "A generic parameter representing instances of type T which are collected from or written to the sub-scopes of the current scope's selected sub-scope.")]
+  [StorableClass]
+  public class SelectedSubScopesLookupParameter<T> : LookupParameter<ItemArray<T>> where T : class, IItem {
+    public SelectedSubScopesLookupParameter() : base() { }
+    public SelectedSubScopesLookupParameter(string name) : base(name) { }
+    public SelectedSubScopesLookupParameter(string name, string description) : base(name, description) { }
+
+    protected override IItem GetActualValue() {
+      string name = LookupParameter<ItemArray<T>>.TranslateName(Name, ExecutionContext);
+      if (ExecutionContext.Scope.SubScopes.Count < 2) throw new InvalidOperationException(Name + ": Scope does not have sub-scopes Remaining and Selected");
+      IScope scope = ExecutionContext.Scope.SubScopes[1];
+      ItemArray<T> values = new ItemArray<T>(scope.SubScopes.Count);
+      IVariable var;
+      T value;
+
+      for (int i = 0; i < values.Length; i++) {
+        scope.SubScopes[i].Variables.TryGetValue(name, out var);
+        if (var != null) {
+          value = var.Value as T;
+          if ((var.Value != null) && (value == null))
+            throw new InvalidOperationException(
+              string.Format("Type mismatch. Variable \"{0}\" does not contain a \"{1}\".",
+                            name,
+                            typeof(T).GetPrettyName())
+            );
+          values[i] = value;
+        }
+      }
+      return values;
+    }
+    protected override void SetActualValue(IItem value) {
+      ItemArray<T> values = value as ItemArray<T>;
+      if (values == null)
+        throw new InvalidOperationException(
+          string.Format("Type mismatch. Value is not a \"{0}\".",
+                        typeof(ItemArray<T>).GetPrettyName())
+        );
+
+      string name = LookupParameter<ItemArray<T>>.TranslateName(Name, ExecutionContext);
+      if (ExecutionContext.Scope.SubScopes.Count < 2) throw new InvalidOperationException(Name + ": Scope does not have sub-scopes Remaining and Selected");
+      IScope scope = ExecutionContext.Scope.SubScopes[1];
+      IVariable var;
+
+      for (int i = 0; i < values.Length; i++) {
+        scope.SubScopes[i].Variables.TryGetValue(name, out var);
+        if (var != null) var.Value = values[i];
+        else scope.SubScopes[i].Variables.Add(new Variable(name, values[i]));
+      }
+    }
+  }
+}
