Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaCreator.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaCreator.cs	(revision 15482)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaCreator.cs	(revision 15906)
@@ -39,22 +39,31 @@
   public class SchemaCreator : EvolutionTrackingOperator<ISymbolicExpressionTree> {
     #region parameter names
+    // criteria to trigger schema-based diversification
     private const string MinimumSchemaLengthParameterName = "MinimumSchemaLength";
     private const string MinimumSchemaFrequencyParameterName = "MinimumSchemaFrequency";
     private const string MinimumPhenotypicSimilarityParameterName = "MinimumPhenotypicSimilarity";
-    private const string ReplacementRatioParameterName = "ReplacementRatio";
-    private const string RandomReplacementParameterName = "RandomReplacement";
+    // parameters controlling the diversification strategy
+    private const string UseAdaptiveMutationRateParameterName = "UseAdaptiveMutationRate"; // dynamically control mutation rate
+    private const string MutationRateUpdateRuleParameterName = "ReplacementRatioUpdateRule";
+    private const string MutationRateParameterName = "MutationRate"; // fixed mutation rate when not using adaptive update
+    private const string ExclusiveMatchingParameterName = "ExclusiveMatching"; // an individual can belong to only 1 schema 
+    private const string ParentsRatio = "ParentsRatio"; // use best % parents to generate schemas from
+    private const string StrictSchemaMatchingParameterName = "StrictSchemaMatching"; // use strict node comparison (for constant values and variable weights)
+    private const string SchemaDefinitionParameterName = "SchemaDefinition"; // which schema definition to use: {=}, {#} or {=,#}
+    private const string SchemaManipulatorParameterName = "SchemaManipulator"; // mutation operator to apply within schemas
+
+    // control parallel behaviour
     private const string ExecuteInParallelParameterName = "ExecuteInParallel";
     private const string MaxDegreeOfParalellismParameterName = "MaxDegreeOfParallelism";
-    private const string PercentageOfPopulationParameterName = "PercentageOfPopulationToDiversify";
     private const string ScaleEstimatedValuesParameterName = "ScaleEstimatedValues";
-    private const string ExclusiveMatchingParameterName = "ExclusiveMatching";
+
+    private const string UpdateCounterParameterName = "UpdateCounter";
+    private const string UpdateIntervalParameterName = "UpdateInterval";
+
+    #region information parameters 
     private const string NumberOfChangedTreesParameterName = "NumberOfChangedTrees";
     private const string NumberOfSchemasParameterName = "NumberOfSchemas";
     private const string AverageSchemaLengthParameterName = "AverageSchemaLength";
-    private const string UseAdaptiveReplacementRatioParameterName = "UseAdaptiveReplacementRatio";
-    private const string ReplacementRatioUpdateRuleParameterName = "ReplacementRatioUpdateRule";
-    private const string StrictSchemaMatchingParameterName = "StrictSchemaMatching";
-    private const string SchemaDefinitionParameterName = "SchemaDefinition";
-    private const string SchemaManipulatorParameterName = "SchemaManipulator";
+    #endregion
     #endregion
 
@@ -66,9 +75,9 @@
       get { return (IConstrainedValueParameter<StringValue>)Parameters[SchemaDefinitionParameterName]; }
     }
-    public IConstrainedValueParameter<StringValue> ReplacementRatioUpdateRuleParameter {
-      get { return (IConstrainedValueParameter<StringValue>)Parameters[ReplacementRatioUpdateRuleParameterName]; }
-    }
-    public IFixedValueParameter<BoolValue> UseAdaptiveReplacementRatioParameter {
-      get { return (IFixedValueParameter<BoolValue>)Parameters[UseAdaptiveReplacementRatioParameterName]; }
+    public IConstrainedValueParameter<StringValue> MutationRateUpdateRuleParameter {
+      get { return (IConstrainedValueParameter<StringValue>)Parameters[MutationRateUpdateRuleParameterName]; }
+    }
+    public IFixedValueParameter<BoolValue> UseAdaptiveMutationRateParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[UseAdaptiveMutationRateParameterName]; }
     }
     public IFixedValueParameter<BoolValue> StrictSchemaMatchingParameter {
@@ -81,6 +90,6 @@
       get { return (IFixedValueParameter<BoolValue>)Parameters[ScaleEstimatedValuesParameterName]; }
     }
-    public IFixedValueParameter<PercentValue> PercentageOfPopulationParameter {
-      get { return (IFixedValueParameter<PercentValue>)Parameters[PercentageOfPopulationParameterName]; }
+    public IFixedValueParameter<PercentValue> ParentsRatioParameter {
+      get { return (IFixedValueParameter<PercentValue>)Parameters[ParentsRatio]; }
     }
     public IFixedValueParameter<IntValue> MinimumSchemaLengthParameter {
@@ -99,6 +108,6 @@
       get { return (IFixedValueParameter<PercentValue>)Parameters[MinimumPhenotypicSimilarityParameterName]; }
     }
-    public IFixedValueParameter<PercentValue> ReplacementRatioParameter {
-      get { return (IFixedValueParameter<PercentValue>)Parameters[ReplacementRatioParameterName]; }
+    public IFixedValueParameter<PercentValue> MutationRateParameter {
+      get { return (IFixedValueParameter<PercentValue>)Parameters[MutationRateParameterName]; }
     }
     public IValueParameter<IntValue> NumberOfSchemasParameter {
@@ -110,4 +119,10 @@
     public IValueParameter<IntValue> NumberOfChangedTreesParameter {
       get { return (IValueParameter<IntValue>)Parameters[NumberOfChangedTreesParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> UpdateCounterParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> UpdateIntervalParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
     }
     #endregion
@@ -117,10 +132,21 @@
     public int MaxDegreeOfParallelism { get { return MaxDegreeOfParallelismParameter.Value.Value; } }
     public bool ExecuteInParallel { get { return ExecuteInParallelParameter.Value.Value; } }
-    public double PercentageOfPopulation { get { return PercentageOfPopulationParameter.Value.Value; } }
+    public double PercentageOfPopulation { get { return ParentsRatioParameter.Value.Value; } }
     public bool StrictSchemaMatching { get { return StrictSchemaMatchingParameter.Value.Value; } }
+    public IntValue UpdateCounter { get { return UpdateCounterParameter.Value; } }
+    public IntValue UpdateInterval { get { return UpdateIntervalParameter.Value; } }
+
     #endregion
 
     private UpdateQualityOperator updateQualityOperator;
     private DiversificationStatisticsOperator diversificationStatisticsOperator;
+
+    public override void InitializeState() {
+      base.InitializeState();
+      NumberOfChangedTreesParameter.Value.Value = 0;
+      NumberOfChangedTreesParameter.Value.Value = 0;
+      AverageSchemaLengthParameter.Value.Value = 0;
+      UpdateCounter.Value = 0;
+    }
 
     public override void ClearState() {
@@ -128,4 +154,5 @@
       NumberOfChangedTreesParameter.Value.Value = 0;
       AverageSchemaLengthParameter.Value.Value = 0;
+      UpdateCounter.Value = 0;
       base.ClearState();
     }
@@ -136,7 +163,6 @@
       Parameters.Add(new FixedValueParameter<PercentValue>(MinimumSchemaFrequencyParameterName, new PercentValue(0.01)));
       Parameters.Add(new FixedValueParameter<PercentValue>(MinimumPhenotypicSimilarityParameterName, new PercentValue(0.9)));
-      Parameters.Add(new FixedValueParameter<PercentValue>(ReplacementRatioParameterName, new PercentValue(0.9)));
-      Parameters.Add(new FixedValueParameter<PercentValue>(PercentageOfPopulationParameterName, new PercentValue(1)));
-      Parameters.Add(new FixedValueParameter<BoolValue>(RandomReplacementParameterName, new BoolValue(false)));
+      Parameters.Add(new FixedValueParameter<PercentValue>(MutationRateParameterName, new PercentValue(0.9)));
+      Parameters.Add(new FixedValueParameter<PercentValue>(ParentsRatio, new PercentValue(1)));
       Parameters.Add(new FixedValueParameter<BoolValue>(ExecuteInParallelParameterName, new BoolValue(false)));
       Parameters.Add(new FixedValueParameter<IntValue>(MaxDegreeOfParalellismParameterName, new IntValue(-1)));
@@ -147,8 +173,10 @@
       Parameters.Add(new ValueParameter<IntValue>(NumberOfSchemasParameterName, new IntValue(0)));
       Parameters.Add(new ValueParameter<DoubleValue>(AverageSchemaLengthParameterName, new DoubleValue(0)));
-      Parameters.Add(new FixedValueParameter<BoolValue>(UseAdaptiveReplacementRatioParameterName, new BoolValue(true)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(UseAdaptiveMutationRateParameterName, new BoolValue(true)));
+      Parameters.Add(new FixedValueParameter<IntValue>(UpdateCounterParameterName, new IntValue(0)));
+      Parameters.Add(new FixedValueParameter<IntValue>(UpdateIntervalParameterName, new IntValue(1)));
 
       // add update rules
-      var replacementRatioUpdateRules = new ItemSet<StringValue>(new[] {
+      var mutationRateUpdateRules = new ItemSet<StringValue>(new[] {
         new StringValue("f(x) = x"),
         new StringValue("f(x) = tanh(x)"),
@@ -158,7 +186,7 @@
         new StringValue("f(x) = 1-sqrt(1-x)")
       });
-      var replacementRatioUpdateRuleParameter = new ConstrainedValueParameter<StringValue>(ReplacementRatioUpdateRuleParameterName, replacementRatioUpdateRules);
-      replacementRatioUpdateRuleParameter.Value = replacementRatioUpdateRules.First();
-      Parameters.Add(replacementRatioUpdateRuleParameter);
+      var mutationRateUpdateRuleParameter = new ConstrainedValueParameter<StringValue>(MutationRateUpdateRuleParameterName, mutationRateUpdateRules);
+      mutationRateUpdateRuleParameter.Value = mutationRateUpdateRules.First();
+      Parameters.Add(mutationRateUpdateRuleParameter);
 
       // add schema definitions
@@ -208,4 +236,9 @@
 
     public override IOperation Apply() {
+      UpdateCounter.Value++;
+      if (UpdateCounter.Value != UpdateInterval.Value)
+        return base.Apply();
+      UpdateCounter.Value = 0;
+
       // apply only when at least one generation has passed
       var gen = Generations.Value;
@@ -213,5 +246,4 @@
         return base.Apply();
 
-      var n = (int)Math.Round(ExecutionContext.Scope.SubScopes.Count * PercentageOfPopulation);
 
       var updateEstimatedValues = new OperationCollection { Parallel = true };
@@ -219,15 +251,20 @@
         updateQualityOperator = new UpdateQualityOperator();
 
-      foreach (var s in ExecutionContext.Scope.SubScopes.Where(s => !s.Variables.ContainsKey("EstimatedValues"))) {
+      var scope = ExecutionContext.Scope;
+
+      foreach (var s in scope.SubScopes.Where(s => !s.Variables.ContainsKey("EstimatedValues"))) {
         updateEstimatedValues.Add(ExecutionContext.CreateChildOperation(updateQualityOperator, s));
       }
 
-      var replacementRule = ReplacementRatioUpdateRuleParameter.Value.Value;
+      var updateRule = MutationRateUpdateRuleParameter.Value.Value;
       var schemaManipulator = SchemaManipulatorParameter.Value;
 
       var evaluateSchemas = new OperationCollection();
 
+      Func<IScope, double> getQuality = s => ((DoubleValue)s.Variables["Quality"].Value).Value;
+
+      var bestN = (int)Math.Round(scope.SubScopes.Count * PercentageOfPopulation);
+      var scopes = new ScopeList(scope.SubScopes.OrderByDescending(getQuality).Take(bestN));
       // for now, only consider crossover offspring
-      var scopes = new ScopeList(ExecutionContext.Scope.SubScopes.OrderByDescending(x => ((DoubleValue)x.Variables["Quality"].Value).Value).Take(n));
       var vertices = from s in scopes
                      let t = (ISymbolicExpressionTree)s.Variables["SymbolicExpressionTree"].Value
@@ -236,14 +273,14 @@
                      select v;
 
-      List<ISymbolicExpressionTree> schemas;
+      IEnumerable<ISymbolicExpressionTree> schemas;
       switch (SchemaDefinitionParameter.Value.Value) {
         case "=":
-          schemas = GenerateAnyNodeSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching).ToList();
+          schemas = GenerateAnyNodeSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching);
           break;
         case "#":
-          schemas = GenerateAnySubtreeSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching).ToList();
+          schemas = GenerateAnySubtreeSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching);
           break;
         case "=,#":
-          schemas = GenerateCombinedSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching).ToList();
+          schemas = GenerateCombinedSchemas(vertices, MinimumSchemaLength, 0, StrictSchemaMatching);
           break;
         default:
@@ -255,8 +292,18 @@
 
       #region create schemas and add subscopes representing the individuals
+      double avgLength = 0;
+      int count = 0;
       foreach (var schema in schemas) {
-        evaluateSchemas.Add(ExecutionContext.CreateChildOperation(new SchemaEvaluator { Schema = schema, ReplacementRule = replacementRule, SchemaManipulator = schemaManipulator }, ExecutionContext.Scope));
+        avgLength += schema.Length;
+        ++count;
+        evaluateSchemas.Add(ExecutionContext.CreateChildOperation(new SchemaEvaluator { Schema = schema, MutationRateUpdateRule = updateRule, SchemaManipulator = schemaManipulator }, scope));
       }
+      avgLength /= count;
       #endregion
+
+      // set parameters for statistics
+      AverageSchemaLengthParameter.Value = new DoubleValue(avgLength);
+      NumberOfSchemasParameter.Value = new IntValue(count);
+      NumberOfChangedTreesParameter.Value = new IntValue(0);
 
       if (diversificationStatisticsOperator == null)
@@ -264,9 +311,4 @@
 
       var calculateStatistics = ExecutionContext.CreateChildOperation(diversificationStatisticsOperator);
-
-      // set parameters for statistics
-      AverageSchemaLengthParameter.Value = new DoubleValue(schemas.Average(x => x.Length));
-      NumberOfSchemasParameter.Value = new IntValue(schemas.Count);
-      NumberOfChangedTreesParameter.Value = new IntValue(0);
 
       // return an operation collection containing all the scope operations + base.Apply()
