Index: /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/Comparators/PopulationDiversityComparator.cs
===================================================================
--- /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/Comparators/PopulationDiversityComparator.cs	(revision 11844)
+++ /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/Comparators/PopulationDiversityComparator.cs	(revision 11844)
@@ -0,0 +1,262 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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.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;
+
+namespace HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm {
+  [Item("PopulationDiversityComparator", "Compares the similarity against that of its parents (assumes the parents are subscopes to the child scope). This operator works with any number of subscopes > 0.")]
+  [StorableClass]
+  public class PopulationDiversityComparator : SingleSuccessorOperator, ISubScopesQualityComparatorOperator, ISimilarityBasedOperator {
+    [Storable]
+    public ISolutionSimilarityCalculator SimilarityCalculator { get; set; }
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> LeftSideParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["LeftSide"]; }
+    }
+    public ILookupParameter<ItemArray<DoubleValue>> RightSideParameter {
+      get { return (ILookupParameter<ItemArray<DoubleValue>>)Parameters["RightSide"]; }
+    }
+    public ILookupParameter<BoolValue> ResultParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Result"]; }
+    }
+    public ValueLookupParameter<DoubleValue> ComparisonFactorParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["ComparisonFactor"]; }
+    }
+    public ValueLookupParameter<DoubleValue> DiversityComparisonFactorParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactor"]; }
+    }
+    private ValueLookupParameter<DoubleValue> ComparisonFactorLowerBoundParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactorLowerBound"]; }
+    }
+    private ValueLookupParameter<DoubleValue> ComparisonFactorUpperBoundParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactorUpperBound"]; }
+    }
+    public IConstrainedValueParameter<IDiscreteDoubleValueModifier> ComparisonFactorModifierParameter {
+      get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["ComparisonFactorModifier"]; }
+    }
+    public ValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public ILookupParameter<IntValue> GenerationsParameter {
+      get { return (LookupParameter<IntValue>)Parameters["Generations"]; }
+    }
+    public ValueParameter<BoolValue> EnableDivCriteriaParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["EnableDivCriteria"]; }
+    }
+
+    private const string spDetailsParameterName = "SPDetails";
+    private const string divDataRowName = "DiversitySuccessCount";
+    private const string qualityDataRowName = "QualitySuccessCount";
+    private const string divFailDataRowName = "DiversityFailCount";
+    private const string qualityFailDataRowName = "QualityFailCount";
+    private const string overallCountDataRowName = "OverallCount";
+    private const string successCountDataRowName = "SuccessCount";
+
+    [Storable]
+    private int currentGeneration;
+    [Storable]
+    private int divCount;
+    [Storable]
+    private int qualityCount;
+    [Storable]
+    private int badQualityCount;
+    [Storable]
+    private int badDivCount;
+    [Storable]
+    private int overallCount;
+    [Storable]
+    private int successCount;
+
+    [StorableConstructor]
+    protected PopulationDiversityComparator(bool deserializing) : base(deserializing) { }
+    protected PopulationDiversityComparator(PopulationDiversityComparator original, Cloner cloner)
+      : base(original, cloner) {
+      SimilarityCalculator = cloner.Clone(original.SimilarityCalculator);
+      currentGeneration = original.currentGeneration;
+      divCount = original.divCount;
+      qualityCount = original.qualityCount;
+      overallCount = original.overallCount;
+      successCount = original.successCount;
+      badDivCount = original.badDivCount;
+      badQualityCount = original.badQualityCount;
+    }
+    public PopulationDiversityComparator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise"));
+      Parameters.Add(new LookupParameter<DoubleValue>("LeftSide", "The quality of the child."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("RightSide", "The qualities of the parents."));
+      Parameters.Add(new LookupParameter<BoolValue>("Result", "The result of the comparison: True means Quality is better, False means it is worse than parents."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("ComparisonFactor", "Determines if the quality should be compared to the better parent (1.0), to the worse (0.0) or to any linearly interpolated value between them."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactor", "Determines if the quality should be compared to the better parent (1.0), to the worse (0.0) or to any linearly interpolated value between them.", new DoubleValue(0.0)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactorLowerBound", "The lower bound of the comparison factor (start).", new DoubleValue(0.5)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactorUpperBound", "The upper bound of the comparison factor (end).", new DoubleValue(1.0)));
+      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<ResultCollection>("Results", "The result collection where the population diversity analysis results should be stored."));
+      Parameters.Add(new LookupParameter<IntValue>("Generations", "The current number of generations."));
+      Parameters.Add(new ValueParameter<BoolValue>("EnableDivCriteria", "Use diversity as additional offspring selection criteria.", new BoolValue(true)));
+
+      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();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PopulationDiversityComparator(this, cloner);
+    }
+
+    private void ParameterizeComparisonFactorModifiers() {
+      //TODO: does not work if Generations parameter names are changed
+      foreach (IDiscreteDoubleValueModifier modifier in ComparisonFactorModifierParameter.ValidValues) {
+        modifier.IndexParameter.ActualName = "Generations";
+        modifier.EndIndexParameter.ActualName = "MaximumGenerations";
+        modifier.EndValueParameter.ActualName = ComparisonFactorUpperBoundParameter.Name;
+        modifier.StartIndexParameter.Value = new IntValue(0);
+        modifier.StartValueParameter.ActualName = ComparisonFactorLowerBoundParameter.Name;
+        modifier.ValueParameter.ActualName = "DiversityComparisonFactor";
+      }
+    }
+
+    private IScope GetRemainingScope() {
+      var scope = ExecutionContext.Scope;
+
+      while (scope != null) {
+        if (scope.SubScopes.Any(x => x.Name == "Remaining")) {
+          return scope.SubScopes.Single(x => x.Name == "Remaining");
+        }
+        scope = scope.Parent;
+      }
+      return null;
+    }
+
+    public override IOperation Apply() {
+      ItemArray<DoubleValue> rightQualities = RightSideParameter.ActualValue;
+      if (rightQualities.Length < 1) throw new InvalidOperationException(Name + ": No subscopes found.");
+      double compFact = ComparisonFactorParameter.ActualValue.Value;
+      double diversityComFact = DiversityComparisonFactorParameter.ActualValue.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      double leftQuality = LeftSideParameter.ActualValue.Value;
+      bool resultDiversity;
+      double threshold = 0;
+
+      DataTable spDetailsTable;
+      if (ResultsParameter.ActualValue.ContainsKey(spDetailsParameterName)) {
+        spDetailsTable = (DataTable)ResultsParameter.ActualValue[spDetailsParameterName].Value;
+      } else {
+        spDetailsTable = new DataTable(spDetailsParameterName);
+        spDetailsTable.Rows.Add(new DataRow(divDataRowName));
+        spDetailsTable.Rows.Add(new DataRow(qualityDataRowName));
+        spDetailsTable.Rows.Add(new DataRow(overallCountDataRowName));
+        spDetailsTable.Rows.Add(new DataRow(successCountDataRowName));
+        spDetailsTable.Rows.Add(new DataRow(divFailDataRowName));
+        spDetailsTable.Rows.Add(new DataRow(qualityFailDataRowName));
+        ResultsParameter.ActualValue.Add(new Result(spDetailsParameterName, spDetailsTable));
+      }
+
+      if (GenerationsParameter.ActualValue.Value != currentGeneration) {
+        spDetailsTable.Rows[divDataRowName].Values.Add(divCount);
+        divCount = 0;
+        spDetailsTable.Rows[qualityDataRowName].Values.Add(qualityCount);
+        qualityCount = 0;
+        spDetailsTable.Rows[overallCountDataRowName].Values.Add(overallCount);
+        overallCount = 0;
+        spDetailsTable.Rows[successCountDataRowName].Values.Add(successCount);
+        successCount = 0;
+        spDetailsTable.Rows[qualityFailDataRowName].Values.Add(badQualityCount);
+        badQualityCount = 0;
+        spDetailsTable.Rows[divFailDataRowName].Values.Add(badDivCount);
+        badDivCount = 0;
+        currentGeneration = GenerationsParameter.ActualValue.Value;
+      }
+
+      #region Calculate threshold
+      if (rightQualities.Length == 2) {
+        var remainingScope = GetRemainingScope();
+        Scope fakeScope = new Scope();
+        fakeScope.SubScopes.Add((IScope)ExecutionContext.Scope.Clone());
+        var similarities = SimilarityCalculator.CalculateSolutionCrowdSimilarity(fakeScope, remainingScope);
+        double averageSimilarity = similarities[0].Average();
+        resultDiversity = averageSimilarity < diversityComFact;
+
+        double minQuality = Math.Min(rightQualities[0].Value, rightQualities[1].Value);
+        double maxQuality = Math.Max(rightQualities[0].Value, rightQualities[1].Value);
+        if (maximization)
+          threshold = minQuality + (maxQuality - minQuality) * compFact;
+        else
+          threshold = maxQuality - (maxQuality - minQuality) * compFact;
+      } else {
+        throw new NotImplementedException("Only 2 parents are supported.");
+      }
+      #endregion
+
+      bool result = maximization && leftQuality > threshold || !maximization && leftQuality < threshold;
+
+      //collect statistics
+      if (result) {
+        qualityCount++;
+      } else {
+        badQualityCount++;
+      }
+      if (resultDiversity) {
+        divCount++;
+      } else {
+        badDivCount++;
+      }
+      if (result && resultDiversity) {
+        successCount++;
+      }
+      overallCount++;
+
+      //use diveristiy criteria or not
+      if (EnableDivCriteriaParameter.Value.Value) {
+        result = result && resultDiversity;
+      }
+
+      BoolValue resultValue = ResultParameter.ActualValue;
+      if (resultValue == null) {
+        ResultParameter.ActualValue = new BoolValue(result);
+      } else {
+        resultValue.Value = result;
+      }
+
+      //like the placeholder, though we create child operations
+      OperationCollection next = new OperationCollection(base.Apply());
+      IOperator op = ComparisonFactorModifierParameter.Value;
+      if (op != null)
+        next.Insert(0, ExecutionContext.CreateChildOperation(op));
+      return next;
+    }
+  }
+}
Index: /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/Comparators/WeightedParentsDiversityComparator.cs
===================================================================
--- /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/Comparators/WeightedParentsDiversityComparator.cs	(revision 11844)
+++ /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/Comparators/WeightedParentsDiversityComparator.cs	(revision 11844)
@@ -0,0 +1,261 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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.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;
+
+namespace HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm {
+  [Item("WeightedParentsDiversityComparator", "Compares the similarity against that of its parents (assumes the parents are subscopes to the child scope). This operator works with any number of subscopes > 0.")]
+  [StorableClass]
+  public class WeightedParentsDiversityComparator : SingleSuccessorOperator, ISubScopesQualityComparatorOperator, ISimilarityBasedOperator {
+    [Storable]
+    public ISolutionSimilarityCalculator SimilarityCalculator { get; set; }
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> LeftSideParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["LeftSide"]; }
+    }
+    public ILookupParameter<ItemArray<DoubleValue>> RightSideParameter {
+      get { return (ILookupParameter<ItemArray<DoubleValue>>)Parameters["RightSide"]; }
+    }
+    public ILookupParameter<BoolValue> ResultParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Result"]; }
+    }
+    public ValueLookupParameter<DoubleValue> ComparisonFactorParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["ComparisonFactor"]; }
+    }
+    public ValueLookupParameter<DoubleValue> DiversityComparisonFactorParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactor"]; }
+    }
+    private ValueLookupParameter<DoubleValue> ComparisonFactorLowerBoundParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactorLowerBound"]; }
+    }
+    private ValueLookupParameter<DoubleValue> ComparisonFactorUpperBoundParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactorUpperBound"]; }
+    }
+    public IConstrainedValueParameter<IDiscreteDoubleValueModifier> ComparisonFactorModifierParameter {
+      get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["ComparisonFactorModifier"]; }
+    }
+    public ValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public ILookupParameter<IntValue> GenerationsParameter {
+      get { return (LookupParameter<IntValue>)Parameters["Generations"]; }
+    }
+    public ValueParameter<BoolValue> EnableDivCriteriaParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["EnableDivCriteria"]; }
+    }
+
+    private const string spDetailsParameterName = "SPDetails";
+    private const string divDataRowName = "DiversitySuccessCount";
+    private const string qualityDataRowName = "QualitySuccessCount";
+    private const string divFailDataRowName = "DiversityFailCount";
+    private const string qualityFailDataRowName = "QualityFailCount";
+    private const string overallCountDataRowName = "OverallCount";
+    private const string successCountDataRowName = "SuccessCount";
+
+    [Storable]
+    private int currentGeneration;
+    [Storable]
+    private int divCount;
+    [Storable]
+    private int qualityCount;
+    [Storable]
+    private int badQualityCount;
+    [Storable]
+    private int badDivCount;
+    [Storable]
+    private int overallCount;
+    [Storable]
+    private int successCount;
+
+    [StorableConstructor]
+    protected WeightedParentsDiversityComparator(bool deserializing) : base(deserializing) { }
+    protected WeightedParentsDiversityComparator(WeightedParentsDiversityComparator original, Cloner cloner)
+      : base(original, cloner) {
+      SimilarityCalculator = cloner.Clone(original.SimilarityCalculator);
+      currentGeneration = original.currentGeneration;
+      divCount = original.divCount;
+      qualityCount = original.qualityCount;
+      overallCount = original.overallCount;
+      successCount = original.successCount;
+      badDivCount = original.badDivCount;
+      badQualityCount = original.badQualityCount;
+    }
+    public WeightedParentsDiversityComparator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise"));
+      Parameters.Add(new LookupParameter<DoubleValue>("LeftSide", "The quality of the child."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("RightSide", "The qualities of the parents."));
+      Parameters.Add(new LookupParameter<BoolValue>("Result", "The result of the comparison: True means Quality is better, False means it is worse than parents."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("ComparisonFactor", "Determines if the quality should be compared to the better parent (1.0), to the worse (0.0) or to any linearly interpolated value between them."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactor", "Determines if the quality should be compared to the better parent (1.0), to the worse (0.0) or to any linearly interpolated value between them.", new DoubleValue(0.0)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactorLowerBound", "The lower bound of the comparison factor (start).", new DoubleValue(0.5)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactorUpperBound", "The upper bound of the comparison factor (end).", new DoubleValue(1.0)));
+      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<ResultCollection>("Results", "The result collection where the population diversity analysis results should be stored."));
+      Parameters.Add(new LookupParameter<IntValue>("Generations", "The current number of generations."));
+      Parameters.Add(new ValueParameter<BoolValue>("EnableDivCriteria", "Use diversity as additional offspring selection criteria.", new BoolValue(true)));
+
+      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();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new WeightedParentsDiversityComparator(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey("Generations"))
+        Parameters.Add(new LookupParameter<IntValue>("Generations", "The current number of generations."));
+      if (!Parameters.ContainsKey("Results"))
+        Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the population diversity analysis results should be stored."));
+      if (!Parameters.ContainsKey("EnableDivCriteria"))
+        Parameters.Add(new ValueParameter<BoolValue>("EnableDivCriteria", "Use diversity as additional offspring selection criteria.", new BoolValue(true)));
+    }
+
+    private void ParameterizeComparisonFactorModifiers() {
+      //TODO: does not work if Generations parameter names are changed
+      foreach (IDiscreteDoubleValueModifier modifier in ComparisonFactorModifierParameter.ValidValues) {
+        modifier.IndexParameter.ActualName = "Generations";
+        modifier.EndIndexParameter.ActualName = "MaximumGenerations";
+        modifier.EndValueParameter.ActualName = ComparisonFactorUpperBoundParameter.Name;
+        modifier.StartIndexParameter.Value = new IntValue(0);
+        modifier.StartValueParameter.ActualName = ComparisonFactorLowerBoundParameter.Name;
+        modifier.ValueParameter.ActualName = "DiversityComparisonFactor";
+      }
+    }
+
+    public override IOperation Apply() {
+      ItemArray<DoubleValue> rightQualities = RightSideParameter.ActualValue;
+      if (rightQualities.Length < 1) throw new InvalidOperationException(Name + ": No subscopes found.");
+      double compFact = ComparisonFactorParameter.ActualValue.Value;
+      double diversityComFact = DiversityComparisonFactorParameter.ActualValue.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      double leftQuality = LeftSideParameter.ActualValue.Value;
+      bool resultDiversity;
+      double threshold = 0;
+
+      DataTable spDetailsTable;
+      if (ResultsParameter.ActualValue.ContainsKey(spDetailsParameterName)) {
+        spDetailsTable = (DataTable)ResultsParameter.ActualValue[spDetailsParameterName].Value;
+      } else {
+        spDetailsTable = new DataTable(spDetailsParameterName);
+        spDetailsTable.Rows.Add(new DataRow(divDataRowName));
+        spDetailsTable.Rows.Add(new DataRow(qualityDataRowName));
+        spDetailsTable.Rows.Add(new DataRow(overallCountDataRowName));
+        spDetailsTable.Rows.Add(new DataRow(successCountDataRowName));
+        spDetailsTable.Rows.Add(new DataRow(divFailDataRowName));
+        spDetailsTable.Rows.Add(new DataRow(qualityFailDataRowName));
+        ResultsParameter.ActualValue.Add(new Result(spDetailsParameterName, spDetailsTable));
+      }
+
+      if (GenerationsParameter.ActualValue.Value != currentGeneration) {
+        spDetailsTable.Rows[divDataRowName].Values.Add(divCount);
+        divCount = 0;
+        spDetailsTable.Rows[qualityDataRowName].Values.Add(qualityCount);
+        qualityCount = 0;
+        spDetailsTable.Rows[overallCountDataRowName].Values.Add(overallCount);
+        overallCount = 0;
+        spDetailsTable.Rows[successCountDataRowName].Values.Add(successCount);
+        successCount = 0;
+        spDetailsTable.Rows[qualityFailDataRowName].Values.Add(badQualityCount);
+        badQualityCount = 0;
+        spDetailsTable.Rows[divFailDataRowName].Values.Add(badDivCount);
+        badDivCount = 0;
+        currentGeneration = GenerationsParameter.ActualValue.Value;
+      }
+
+      #region Calculate threshold
+      if (rightQualities.Length == 2) {
+        var sim1 = SimilarityCalculator.CalculateSolutionSimilarity(ExecutionContext.Scope, ExecutionContext.Scope.SubScopes[0]);
+        var sim2 = SimilarityCalculator.CalculateSolutionSimilarity(ExecutionContext.Scope, ExecutionContext.Scope.SubScopes[1]);
+        var simAvg = (sim1 + sim2) / 2.0;
+
+        //TODO: try out different things
+        //resultDiversity = simAvg < diversityComFact;
+        resultDiversity = sim1 < diversityComFact || sim2 < diversityComFact;
+
+        double minQuality = Math.Min(rightQualities[0].Value, rightQualities[1].Value);
+        double maxQuality = Math.Max(rightQualities[0].Value, rightQualities[1].Value);
+        if (maximization)
+          threshold = minQuality + (maxQuality - minQuality) * compFact;
+        else
+          threshold = maxQuality - (maxQuality - minQuality) * compFact;
+      } else {
+        throw new NotImplementedException("Only 2 parents are supported.");
+      }
+      #endregion
+
+      bool result = maximization && leftQuality > threshold || !maximization && leftQuality < threshold;
+
+      //collect statistics
+      if (result) {
+        qualityCount++;
+      } else {
+        badQualityCount++;
+      }
+      if (resultDiversity) {
+        divCount++;
+      } else {
+        badDivCount++;
+      }
+      if (result && resultDiversity) {
+        successCount++;
+      }
+      overallCount++;
+
+      //use diveristiy criteria or not
+      if (EnableDivCriteriaParameter.Value.Value) {
+        result = result && resultDiversity;
+      }
+
+      BoolValue resultValue = ResultParameter.ActualValue;
+      if (resultValue == null) {
+        ResultParameter.ActualValue = new BoolValue(result);
+      } else {
+        resultValue.Value = result;
+      }
+
+      //like the placeholder, though we create child operations
+      OperationCollection next = new OperationCollection(base.Apply());
+      IOperator op = ComparisonFactorModifierParameter.Value;
+      if (op != null)
+        next.Insert(0, ExecutionContext.CreateChildOperation(op));
+      return next;
+    }
+  }
+}
Index: /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/Comparators/WeightedParentsQualityComparator.cs
===================================================================
--- /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/Comparators/WeightedParentsQualityComparator.cs	(revision 11844)
+++ /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/Comparators/WeightedParentsQualityComparator.cs	(revision 11844)
@@ -0,0 +1,127 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm {
+  [Item("WeightedParentsQualityComparator", "Compares the quality against that of its parents (assumes the parents are subscopes to the child scope). This operator works with any number of subscopes > 0.")]
+  [StorableClass]
+  public class WeightedParentsQualityComparator : SingleSuccessorOperator, ISubScopesQualityComparatorOperator {
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> LeftSideParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["LeftSide"]; }
+    }
+    public ILookupParameter<ItemArray<DoubleValue>> RightSideParameter {
+      get { return (ILookupParameter<ItemArray<DoubleValue>>)Parameters["RightSide"]; }
+    }
+    public ILookupParameter<BoolValue> ResultParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Result"]; }
+    }
+    public ValueLookupParameter<DoubleValue> ComparisonFactorParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["ComparisonFactor"]; }
+    }
+
+    [StorableConstructor]
+    protected WeightedParentsQualityComparator(bool deserializing) : base(deserializing) { }
+    protected WeightedParentsQualityComparator(WeightedParentsQualityComparator original, Cloner cloner) : base(original, cloner) { }
+    public WeightedParentsQualityComparator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise"));
+      Parameters.Add(new LookupParameter<DoubleValue>("LeftSide", "The quality of the child."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("RightSide", "The qualities of the parents."));
+      Parameters.Add(new LookupParameter<BoolValue>("Result", "The result of the comparison: True means Quality is better, False means it is worse than parents."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("ComparisonFactor", "Determines if the quality should be compared to the better parent (1.0), to the worse (0.0) or to any linearly interpolated value between them."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new WeightedParentsQualityComparator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemArray<DoubleValue> rightQualities = RightSideParameter.ActualValue;
+      if (rightQualities.Length < 1) throw new InvalidOperationException(Name + ": No subscopes found.");
+      double compFact = ComparisonFactorParameter.ActualValue.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      double leftQuality = LeftSideParameter.ActualValue.Value;
+
+      double threshold = 0;
+
+      #region Calculate threshold
+      if (rightQualities.Length == 2) { // this case will probably be used most often
+        double minQuality = Math.Min(rightQualities[0].Value, rightQualities[1].Value);
+        double maxQuality = Math.Max(rightQualities[0].Value, rightQualities[1].Value);
+        if (maximization)
+          threshold = minQuality + (maxQuality - minQuality) * compFact;
+        else
+          threshold = maxQuality - (maxQuality - minQuality) * compFact;
+      } else if (rightQualities.Length == 1) { // case for just one parent
+        threshold = rightQualities[0].Value;
+      } else { // general case extended to 3 or more parents
+        List<double> sortedQualities = rightQualities.Select(x => x.Value).ToList();
+        sortedQualities.Sort();
+        double minimumQuality = sortedQualities.First();
+
+        double integral = 0;
+        for (int i = 0; i < sortedQualities.Count - 1; i++) {
+          integral += (sortedQualities[i] + sortedQualities[i + 1]) / 2.0; // sum of the trapezoid
+        }
+        integral -= minimumQuality * sortedQualities.Count;
+        if (integral == 0) threshold = sortedQualities[0]; // all qualities are equal
+        else {
+          double selectedArea = integral * (maximization ? compFact : (1 - compFact));
+          integral = 0;
+          for (int i = 0; i < sortedQualities.Count - 1; i++) {
+            double currentSliceArea = (sortedQualities[i] + sortedQualities[i + 1]) / 2.0;
+            double windowedSliceArea = currentSliceArea - minimumQuality;
+            if (windowedSliceArea == 0) continue;
+            integral += windowedSliceArea;
+            if (integral >= selectedArea) {
+              double factor = 1 - ((integral - selectedArea) / (windowedSliceArea));
+              threshold = sortedQualities[i] + (sortedQualities[i + 1] - sortedQualities[i]) * factor;
+              break;
+            }
+          }
+        }
+      }
+      #endregion
+
+      bool result = maximization && leftQuality > threshold || !maximization && leftQuality < threshold;
+      BoolValue resultValue = ResultParameter.ActualValue;
+      if (resultValue == null) {
+        ResultParameter.ActualValue = new BoolValue(result);
+      } else {
+        resultValue.Value = result;
+      }
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm-3.3.csproj
===================================================================
--- /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm-3.3.csproj	(revision 11843)
+++ /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm-3.3.csproj	(revision 11844)
@@ -167,4 +167,7 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Comparators\PopulationDiversityComparator.cs" />
+    <Compile Include="Comparators\WeightedParentsDiversityComparator.cs" />
+    <Compile Include="Comparators\WeightedParentsQualityComparator.cs" />
     <Compile Include="ISubScopesQualityComparatorOperator.cs" />
     <Compile Include="OffspringCollector.cs" />
@@ -178,7 +181,4 @@
     <Compile Include="VOffspringSelectionGeneticAlgorithmMainLoop.cs" />
     <Compile Include="VOffspringSelectionGeneticAlgorithmMainOperator.cs" />
-    <Compile Include="PopulationDiversityComparator.cs" />
-    <Compile Include="WeightedParentsDiversityComparator.cs" />
-    <Compile Include="WeightedParentsQualityComparator.cs" />
   </ItemGroup>
   <ItemGroup>
Index: anches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/PopulationDiversityComparator.cs
===================================================================
--- /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/PopulationDiversityComparator.cs	(revision 11843)
+++ 	(revision )
@@ -1,262 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2014 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.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;
-
-namespace HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm {
-  [Item("PopulationDiversityComparator", "Compares the similarity against that of its parents (assumes the parents are subscopes to the child scope). This operator works with any number of subscopes > 0.")]
-  [StorableClass]
-  public class PopulationDiversityComparator : SingleSuccessorOperator, ISubScopesQualityComparatorOperator, ISimilarityBasedOperator {
-    [Storable]
-    public ISolutionSimilarityCalculator SimilarityCalculator { get; set; }
-    public IValueLookupParameter<BoolValue> MaximizationParameter {
-      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
-    }
-    public ILookupParameter<DoubleValue> LeftSideParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["LeftSide"]; }
-    }
-    public ILookupParameter<ItemArray<DoubleValue>> RightSideParameter {
-      get { return (ILookupParameter<ItemArray<DoubleValue>>)Parameters["RightSide"]; }
-    }
-    public ILookupParameter<BoolValue> ResultParameter {
-      get { return (ILookupParameter<BoolValue>)Parameters["Result"]; }
-    }
-    public ValueLookupParameter<DoubleValue> ComparisonFactorParameter {
-      get { return (ValueLookupParameter<DoubleValue>)Parameters["ComparisonFactor"]; }
-    }
-    public ValueLookupParameter<DoubleValue> DiversityComparisonFactorParameter {
-      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactor"]; }
-    }
-    private ValueLookupParameter<DoubleValue> ComparisonFactorLowerBoundParameter {
-      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactorLowerBound"]; }
-    }
-    private ValueLookupParameter<DoubleValue> ComparisonFactorUpperBoundParameter {
-      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactorUpperBound"]; }
-    }
-    public IConstrainedValueParameter<IDiscreteDoubleValueModifier> ComparisonFactorModifierParameter {
-      get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["ComparisonFactorModifier"]; }
-    }
-    public ValueLookupParameter<ResultCollection> ResultsParameter {
-      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
-    }
-    public ILookupParameter<IntValue> GenerationsParameter {
-      get { return (LookupParameter<IntValue>)Parameters["Generations"]; }
-    }
-    public ValueParameter<BoolValue> EnableDivCriteriaParameter {
-      get { return (ValueParameter<BoolValue>)Parameters["EnableDivCriteria"]; }
-    }
-
-    private const string spDetailsParameterName = "SPDetails";
-    private const string divDataRowName = "DiversitySuccessCount";
-    private const string qualityDataRowName = "QualitySuccessCount";
-    private const string divFailDataRowName = "DiversityFailCount";
-    private const string qualityFailDataRowName = "QualityFailCount";
-    private const string overallCountDataRowName = "OverallCount";
-    private const string successCountDataRowName = "SuccessCount";
-
-    [Storable]
-    private int currentGeneration;
-    [Storable]
-    private int divCount;
-    [Storable]
-    private int qualityCount;
-    [Storable]
-    private int badQualityCount;
-    [Storable]
-    private int badDivCount;
-    [Storable]
-    private int overallCount;
-    [Storable]
-    private int successCount;
-
-    [StorableConstructor]
-    protected PopulationDiversityComparator(bool deserializing) : base(deserializing) { }
-    protected PopulationDiversityComparator(PopulationDiversityComparator original, Cloner cloner)
-      : base(original, cloner) {
-      SimilarityCalculator = cloner.Clone(original.SimilarityCalculator);
-      currentGeneration = original.currentGeneration;
-      divCount = original.divCount;
-      qualityCount = original.qualityCount;
-      overallCount = original.overallCount;
-      successCount = original.successCount;
-      badDivCount = original.badDivCount;
-      badQualityCount = original.badQualityCount;
-    }
-    public PopulationDiversityComparator()
-      : base() {
-      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise"));
-      Parameters.Add(new LookupParameter<DoubleValue>("LeftSide", "The quality of the child."));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("RightSide", "The qualities of the parents."));
-      Parameters.Add(new LookupParameter<BoolValue>("Result", "The result of the comparison: True means Quality is better, False means it is worse than parents."));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("ComparisonFactor", "Determines if the quality should be compared to the better parent (1.0), to the worse (0.0) or to any linearly interpolated value between them."));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactor", "Determines if the quality should be compared to the better parent (1.0), to the worse (0.0) or to any linearly interpolated value between them.", new DoubleValue(0.0)));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactorLowerBound", "The lower bound of the comparison factor (start).", new DoubleValue(0.5)));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactorUpperBound", "The upper bound of the comparison factor (end).", new DoubleValue(1.0)));
-      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<ResultCollection>("Results", "The result collection where the population diversity analysis results should be stored."));
-      Parameters.Add(new LookupParameter<IntValue>("Generations", "The current number of generations."));
-      Parameters.Add(new ValueParameter<BoolValue>("EnableDivCriteria", "Use diversity as additional offspring selection criteria.", new BoolValue(true)));
-
-      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();
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new PopulationDiversityComparator(this, cloner);
-    }
-
-    private void ParameterizeComparisonFactorModifiers() {
-      //TODO: does not work if Generations parameter names are changed
-      foreach (IDiscreteDoubleValueModifier modifier in ComparisonFactorModifierParameter.ValidValues) {
-        modifier.IndexParameter.ActualName = "Generations";
-        modifier.EndIndexParameter.ActualName = "MaximumGenerations";
-        modifier.EndValueParameter.ActualName = ComparisonFactorUpperBoundParameter.Name;
-        modifier.StartIndexParameter.Value = new IntValue(0);
-        modifier.StartValueParameter.ActualName = ComparisonFactorLowerBoundParameter.Name;
-        modifier.ValueParameter.ActualName = "DiversityComparisonFactor";
-      }
-    }
-
-    private IScope GetRemainingScope() {
-      var scope = ExecutionContext.Scope;
-
-      while (scope != null) {
-        if (scope.SubScopes.Any(x => x.Name == "Remaining")) {
-          return scope.SubScopes.Single(x => x.Name == "Remaining");
-        }
-        scope = scope.Parent;
-      }
-      return null;
-    }
-
-    public override IOperation Apply() {
-      ItemArray<DoubleValue> rightQualities = RightSideParameter.ActualValue;
-      if (rightQualities.Length < 1) throw new InvalidOperationException(Name + ": No subscopes found.");
-      double compFact = ComparisonFactorParameter.ActualValue.Value;
-      double diversityComFact = DiversityComparisonFactorParameter.ActualValue.Value;
-      bool maximization = MaximizationParameter.ActualValue.Value;
-      double leftQuality = LeftSideParameter.ActualValue.Value;
-      bool resultDiversity;
-      double threshold = 0;
-
-      DataTable spDetailsTable;
-      if (ResultsParameter.ActualValue.ContainsKey(spDetailsParameterName)) {
-        spDetailsTable = (DataTable)ResultsParameter.ActualValue[spDetailsParameterName].Value;
-      } else {
-        spDetailsTable = new DataTable(spDetailsParameterName);
-        spDetailsTable.Rows.Add(new DataRow(divDataRowName));
-        spDetailsTable.Rows.Add(new DataRow(qualityDataRowName));
-        spDetailsTable.Rows.Add(new DataRow(overallCountDataRowName));
-        spDetailsTable.Rows.Add(new DataRow(successCountDataRowName));
-        spDetailsTable.Rows.Add(new DataRow(divFailDataRowName));
-        spDetailsTable.Rows.Add(new DataRow(qualityFailDataRowName));
-        ResultsParameter.ActualValue.Add(new Result(spDetailsParameterName, spDetailsTable));
-      }
-
-      if (GenerationsParameter.ActualValue.Value != currentGeneration) {
-        spDetailsTable.Rows[divDataRowName].Values.Add(divCount);
-        divCount = 0;
-        spDetailsTable.Rows[qualityDataRowName].Values.Add(qualityCount);
-        qualityCount = 0;
-        spDetailsTable.Rows[overallCountDataRowName].Values.Add(overallCount);
-        overallCount = 0;
-        spDetailsTable.Rows[successCountDataRowName].Values.Add(successCount);
-        successCount = 0;
-        spDetailsTable.Rows[qualityFailDataRowName].Values.Add(badQualityCount);
-        badQualityCount = 0;
-        spDetailsTable.Rows[divFailDataRowName].Values.Add(badDivCount);
-        badDivCount = 0;
-        currentGeneration = GenerationsParameter.ActualValue.Value;
-      }
-
-      #region Calculate threshold
-      if (rightQualities.Length == 2) {
-        var remainingScope = GetRemainingScope();
-        Scope fakeScope = new Scope();
-        fakeScope.SubScopes.Add((IScope)ExecutionContext.Scope.Clone());
-        var similarities = SimilarityCalculator.CalculateSolutionCrowdSimilarity(fakeScope, remainingScope);
-        double averageSimilarity = similarities[0].Average();
-        resultDiversity = averageSimilarity < diversityComFact;
-
-        double minQuality = Math.Min(rightQualities[0].Value, rightQualities[1].Value);
-        double maxQuality = Math.Max(rightQualities[0].Value, rightQualities[1].Value);
-        if (maximization)
-          threshold = minQuality + (maxQuality - minQuality) * compFact;
-        else
-          threshold = maxQuality - (maxQuality - minQuality) * compFact;
-      } else {
-        throw new NotImplementedException("Only 2 parents are supported.");
-      }
-      #endregion
-
-      bool result = maximization && leftQuality > threshold || !maximization && leftQuality < threshold;
-
-      //collect statistics
-      if (result) {
-        qualityCount++;
-      } else {
-        badQualityCount++;
-      }
-      if (resultDiversity) {
-        divCount++;
-      } else {
-        badDivCount++;
-      }
-      if (result && resultDiversity) {
-        successCount++;
-      }
-      overallCount++;
-
-      //use diveristiy criteria or not
-      if (EnableDivCriteriaParameter.Value.Value) {
-        result = result && resultDiversity;
-      }
-
-      BoolValue resultValue = ResultParameter.ActualValue;
-      if (resultValue == null) {
-        ResultParameter.ActualValue = new BoolValue(result);
-      } else {
-        resultValue.Value = result;
-      }
-
-      //like the placeholder, though we create child operations
-      OperationCollection next = new OperationCollection(base.Apply());
-      IOperator op = ComparisonFactorModifierParameter.Value;
-      if (op != null)
-        next.Insert(0, ExecutionContext.CreateChildOperation(op));
-      return next;
-    }
-  }
-}
Index: anches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/WeightedParentsDiversityComparator.cs
===================================================================
--- /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/WeightedParentsDiversityComparator.cs	(revision 11843)
+++ 	(revision )
@@ -1,261 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2014 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.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;
-
-namespace HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm {
-  [Item("WeightedParentsDiversityComparator", "Compares the similarity against that of its parents (assumes the parents are subscopes to the child scope). This operator works with any number of subscopes > 0.")]
-  [StorableClass]
-  public class WeightedParentsDiversityComparator : SingleSuccessorOperator, ISubScopesQualityComparatorOperator, ISimilarityBasedOperator {
-    [Storable]
-    public ISolutionSimilarityCalculator SimilarityCalculator { get; set; }
-    public IValueLookupParameter<BoolValue> MaximizationParameter {
-      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
-    }
-    public ILookupParameter<DoubleValue> LeftSideParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["LeftSide"]; }
-    }
-    public ILookupParameter<ItemArray<DoubleValue>> RightSideParameter {
-      get { return (ILookupParameter<ItemArray<DoubleValue>>)Parameters["RightSide"]; }
-    }
-    public ILookupParameter<BoolValue> ResultParameter {
-      get { return (ILookupParameter<BoolValue>)Parameters["Result"]; }
-    }
-    public ValueLookupParameter<DoubleValue> ComparisonFactorParameter {
-      get { return (ValueLookupParameter<DoubleValue>)Parameters["ComparisonFactor"]; }
-    }
-    public ValueLookupParameter<DoubleValue> DiversityComparisonFactorParameter {
-      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactor"]; }
-    }
-    private ValueLookupParameter<DoubleValue> ComparisonFactorLowerBoundParameter {
-      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactorLowerBound"]; }
-    }
-    private ValueLookupParameter<DoubleValue> ComparisonFactorUpperBoundParameter {
-      get { return (ValueLookupParameter<DoubleValue>)Parameters["DiversityComparisonFactorUpperBound"]; }
-    }
-    public IConstrainedValueParameter<IDiscreteDoubleValueModifier> ComparisonFactorModifierParameter {
-      get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["ComparisonFactorModifier"]; }
-    }
-    public ValueLookupParameter<ResultCollection> ResultsParameter {
-      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
-    }
-    public ILookupParameter<IntValue> GenerationsParameter {
-      get { return (LookupParameter<IntValue>)Parameters["Generations"]; }
-    }
-    public ValueParameter<BoolValue> EnableDivCriteriaParameter {
-      get { return (ValueParameter<BoolValue>)Parameters["EnableDivCriteria"]; }
-    }
-
-    private const string spDetailsParameterName = "SPDetails";
-    private const string divDataRowName = "DiversitySuccessCount";
-    private const string qualityDataRowName = "QualitySuccessCount";
-    private const string divFailDataRowName = "DiversityFailCount";
-    private const string qualityFailDataRowName = "QualityFailCount";
-    private const string overallCountDataRowName = "OverallCount";
-    private const string successCountDataRowName = "SuccessCount";
-
-    [Storable]
-    private int currentGeneration;
-    [Storable]
-    private int divCount;
-    [Storable]
-    private int qualityCount;
-    [Storable]
-    private int badQualityCount;
-    [Storable]
-    private int badDivCount;
-    [Storable]
-    private int overallCount;
-    [Storable]
-    private int successCount;
-
-    [StorableConstructor]
-    protected WeightedParentsDiversityComparator(bool deserializing) : base(deserializing) { }
-    protected WeightedParentsDiversityComparator(WeightedParentsDiversityComparator original, Cloner cloner)
-      : base(original, cloner) {
-      SimilarityCalculator = cloner.Clone(original.SimilarityCalculator);
-      currentGeneration = original.currentGeneration;
-      divCount = original.divCount;
-      qualityCount = original.qualityCount;
-      overallCount = original.overallCount;
-      successCount = original.successCount;
-      badDivCount = original.badDivCount;
-      badQualityCount = original.badQualityCount;
-    }
-    public WeightedParentsDiversityComparator()
-      : base() {
-      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise"));
-      Parameters.Add(new LookupParameter<DoubleValue>("LeftSide", "The quality of the child."));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("RightSide", "The qualities of the parents."));
-      Parameters.Add(new LookupParameter<BoolValue>("Result", "The result of the comparison: True means Quality is better, False means it is worse than parents."));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("ComparisonFactor", "Determines if the quality should be compared to the better parent (1.0), to the worse (0.0) or to any linearly interpolated value between them."));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactor", "Determines if the quality should be compared to the better parent (1.0), to the worse (0.0) or to any linearly interpolated value between them.", new DoubleValue(0.0)));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactorLowerBound", "The lower bound of the comparison factor (start).", new DoubleValue(0.5)));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("DiversityComparisonFactorUpperBound", "The upper bound of the comparison factor (end).", new DoubleValue(1.0)));
-      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<ResultCollection>("Results", "The result collection where the population diversity analysis results should be stored."));
-      Parameters.Add(new LookupParameter<IntValue>("Generations", "The current number of generations."));
-      Parameters.Add(new ValueParameter<BoolValue>("EnableDivCriteria", "Use diversity as additional offspring selection criteria.", new BoolValue(true)));
-
-      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();
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new WeightedParentsDiversityComparator(this, cloner);
-    }
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      if (!Parameters.ContainsKey("Generations"))
-        Parameters.Add(new LookupParameter<IntValue>("Generations", "The current number of generations."));
-      if (!Parameters.ContainsKey("Results"))
-        Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the population diversity analysis results should be stored."));
-      if (!Parameters.ContainsKey("EnableDivCriteria"))
-        Parameters.Add(new ValueParameter<BoolValue>("EnableDivCriteria", "Use diversity as additional offspring selection criteria.", new BoolValue(true)));
-    }
-
-    private void ParameterizeComparisonFactorModifiers() {
-      //TODO: does not work if Generations parameter names are changed
-      foreach (IDiscreteDoubleValueModifier modifier in ComparisonFactorModifierParameter.ValidValues) {
-        modifier.IndexParameter.ActualName = "Generations";
-        modifier.EndIndexParameter.ActualName = "MaximumGenerations";
-        modifier.EndValueParameter.ActualName = ComparisonFactorUpperBoundParameter.Name;
-        modifier.StartIndexParameter.Value = new IntValue(0);
-        modifier.StartValueParameter.ActualName = ComparisonFactorLowerBoundParameter.Name;
-        modifier.ValueParameter.ActualName = "DiversityComparisonFactor";
-      }
-    }
-
-    public override IOperation Apply() {
-      ItemArray<DoubleValue> rightQualities = RightSideParameter.ActualValue;
-      if (rightQualities.Length < 1) throw new InvalidOperationException(Name + ": No subscopes found.");
-      double compFact = ComparisonFactorParameter.ActualValue.Value;
-      double diversityComFact = DiversityComparisonFactorParameter.ActualValue.Value;
-      bool maximization = MaximizationParameter.ActualValue.Value;
-      double leftQuality = LeftSideParameter.ActualValue.Value;
-      bool resultDiversity;
-      double threshold = 0;
-
-      DataTable spDetailsTable;
-      if (ResultsParameter.ActualValue.ContainsKey(spDetailsParameterName)) {
-        spDetailsTable = (DataTable)ResultsParameter.ActualValue[spDetailsParameterName].Value;
-      } else {
-        spDetailsTable = new DataTable(spDetailsParameterName);
-        spDetailsTable.Rows.Add(new DataRow(divDataRowName));
-        spDetailsTable.Rows.Add(new DataRow(qualityDataRowName));
-        spDetailsTable.Rows.Add(new DataRow(overallCountDataRowName));
-        spDetailsTable.Rows.Add(new DataRow(successCountDataRowName));
-        spDetailsTable.Rows.Add(new DataRow(divFailDataRowName));
-        spDetailsTable.Rows.Add(new DataRow(qualityFailDataRowName));
-        ResultsParameter.ActualValue.Add(new Result(spDetailsParameterName, spDetailsTable));
-      }
-
-      if (GenerationsParameter.ActualValue.Value != currentGeneration) {
-        spDetailsTable.Rows[divDataRowName].Values.Add(divCount);
-        divCount = 0;
-        spDetailsTable.Rows[qualityDataRowName].Values.Add(qualityCount);
-        qualityCount = 0;
-        spDetailsTable.Rows[overallCountDataRowName].Values.Add(overallCount);
-        overallCount = 0;
-        spDetailsTable.Rows[successCountDataRowName].Values.Add(successCount);
-        successCount = 0;
-        spDetailsTable.Rows[qualityFailDataRowName].Values.Add(badQualityCount);
-        badQualityCount = 0;
-        spDetailsTable.Rows[divFailDataRowName].Values.Add(badDivCount);
-        badDivCount = 0;
-        currentGeneration = GenerationsParameter.ActualValue.Value;
-      }
-
-      #region Calculate threshold
-      if (rightQualities.Length == 2) {
-        var sim1 = SimilarityCalculator.CalculateSolutionSimilarity(ExecutionContext.Scope, ExecutionContext.Scope.SubScopes[0]);
-        var sim2 = SimilarityCalculator.CalculateSolutionSimilarity(ExecutionContext.Scope, ExecutionContext.Scope.SubScopes[1]);
-        var simAvg = (sim1 + sim2) / 2.0;
-
-        //TODO: try out different things
-        //resultDiversity = simAvg < diversityComFact;
-        resultDiversity = sim1 < diversityComFact || sim2 < diversityComFact;
-
-        double minQuality = Math.Min(rightQualities[0].Value, rightQualities[1].Value);
-        double maxQuality = Math.Max(rightQualities[0].Value, rightQualities[1].Value);
-        if (maximization)
-          threshold = minQuality + (maxQuality - minQuality) * compFact;
-        else
-          threshold = maxQuality - (maxQuality - minQuality) * compFact;
-      } else {
-        throw new NotImplementedException("Only 2 parents are supported.");
-      }
-      #endregion
-
-      bool result = maximization && leftQuality > threshold || !maximization && leftQuality < threshold;
-
-      //collect statistics
-      if (result) {
-        qualityCount++;
-      } else {
-        badQualityCount++;
-      }
-      if (resultDiversity) {
-        divCount++;
-      } else {
-        badDivCount++;
-      }
-      if (result && resultDiversity) {
-        successCount++;
-      }
-      overallCount++;
-
-      //use diveristiy criteria or not
-      if (EnableDivCriteriaParameter.Value.Value) {
-        result = result && resultDiversity;
-      }
-
-      BoolValue resultValue = ResultParameter.ActualValue;
-      if (resultValue == null) {
-        ResultParameter.ActualValue = new BoolValue(result);
-      } else {
-        resultValue.Value = result;
-      }
-
-      //like the placeholder, though we create child operations
-      OperationCollection next = new OperationCollection(base.Apply());
-      IOperator op = ComparisonFactorModifierParameter.Value;
-      if (op != null)
-        next.Insert(0, ExecutionContext.CreateChildOperation(op));
-      return next;
-    }
-  }
-}
Index: anches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/WeightedParentsQualityComparator.cs
===================================================================
--- /branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/WeightedParentsQualityComparator.cs	(revision 11843)
+++ 	(revision )
@@ -1,127 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2014 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.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm {
-  [Item("WeightedParentsQualityComparator", "Compares the quality against that of its parents (assumes the parents are subscopes to the child scope). This operator works with any number of subscopes > 0.")]
-  [StorableClass]
-  public class WeightedParentsQualityComparator : SingleSuccessorOperator, ISubScopesQualityComparatorOperator {
-    public IValueLookupParameter<BoolValue> MaximizationParameter {
-      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
-    }
-    public ILookupParameter<DoubleValue> LeftSideParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["LeftSide"]; }
-    }
-    public ILookupParameter<ItemArray<DoubleValue>> RightSideParameter {
-      get { return (ILookupParameter<ItemArray<DoubleValue>>)Parameters["RightSide"]; }
-    }
-    public ILookupParameter<BoolValue> ResultParameter {
-      get { return (ILookupParameter<BoolValue>)Parameters["Result"]; }
-    }
-    public ValueLookupParameter<DoubleValue> ComparisonFactorParameter {
-      get { return (ValueLookupParameter<DoubleValue>)Parameters["ComparisonFactor"]; }
-    }
-
-    [StorableConstructor]
-    protected WeightedParentsQualityComparator(bool deserializing) : base(deserializing) { }
-    protected WeightedParentsQualityComparator(WeightedParentsQualityComparator original, Cloner cloner) : base(original, cloner) { }
-    public WeightedParentsQualityComparator()
-      : base() {
-      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise"));
-      Parameters.Add(new LookupParameter<DoubleValue>("LeftSide", "The quality of the child."));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("RightSide", "The qualities of the parents."));
-      Parameters.Add(new LookupParameter<BoolValue>("Result", "The result of the comparison: True means Quality is better, False means it is worse than parents."));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("ComparisonFactor", "Determines if the quality should be compared to the better parent (1.0), to the worse (0.0) or to any linearly interpolated value between them."));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new WeightedParentsQualityComparator(this, cloner);
-    }
-
-    public override IOperation Apply() {
-      ItemArray<DoubleValue> rightQualities = RightSideParameter.ActualValue;
-      if (rightQualities.Length < 1) throw new InvalidOperationException(Name + ": No subscopes found.");
-      double compFact = ComparisonFactorParameter.ActualValue.Value;
-      bool maximization = MaximizationParameter.ActualValue.Value;
-      double leftQuality = LeftSideParameter.ActualValue.Value;
-
-      double threshold = 0;
-
-      #region Calculate threshold
-      if (rightQualities.Length == 2) { // this case will probably be used most often
-        double minQuality = Math.Min(rightQualities[0].Value, rightQualities[1].Value);
-        double maxQuality = Math.Max(rightQualities[0].Value, rightQualities[1].Value);
-        if (maximization)
-          threshold = minQuality + (maxQuality - minQuality) * compFact;
-        else
-          threshold = maxQuality - (maxQuality - minQuality) * compFact;
-      } else if (rightQualities.Length == 1) { // case for just one parent
-        threshold = rightQualities[0].Value;
-      } else { // general case extended to 3 or more parents
-        List<double> sortedQualities = rightQualities.Select(x => x.Value).ToList();
-        sortedQualities.Sort();
-        double minimumQuality = sortedQualities.First();
-
-        double integral = 0;
-        for (int i = 0; i < sortedQualities.Count - 1; i++) {
-          integral += (sortedQualities[i] + sortedQualities[i + 1]) / 2.0; // sum of the trapezoid
-        }
-        integral -= minimumQuality * sortedQualities.Count;
-        if (integral == 0) threshold = sortedQualities[0]; // all qualities are equal
-        else {
-          double selectedArea = integral * (maximization ? compFact : (1 - compFact));
-          integral = 0;
-          for (int i = 0; i < sortedQualities.Count - 1; i++) {
-            double currentSliceArea = (sortedQualities[i] + sortedQualities[i + 1]) / 2.0;
-            double windowedSliceArea = currentSliceArea - minimumQuality;
-            if (windowedSliceArea == 0) continue;
-            integral += windowedSliceArea;
-            if (integral >= selectedArea) {
-              double factor = 1 - ((integral - selectedArea) / (windowedSliceArea));
-              threshold = sortedQualities[i] + (sortedQualities[i + 1] - sortedQualities[i]) * factor;
-              break;
-            }
-          }
-        }
-      }
-      #endregion
-
-      bool result = maximization && leftQuality > threshold || !maximization && leftQuality < threshold;
-      BoolValue resultValue = ResultParameter.ActualValue;
-      if (resultValue == null) {
-        ResultParameter.ActualValue = new BoolValue(result);
-      } else {
-        resultValue.Value = result;
-      }
-
-      return base.Apply();
-    }
-  }
-}
