Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/SchemaAnalyzer.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/SchemaAnalyzer.cs	(revision 8216)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/SchemaAnalyzer.cs	(revision 8217)
@@ -140,5 +140,5 @@
     }
 
-    private bool IsSubtour(IntArray tour, Permutation permutation) {
+    public static bool IsSubtour(IntArray tour, Permutation permutation) {
       // determine starting position for subtour match
       int idx = permutation.Select((x, index) => new { Value = x, Index = index }).Single(x => x.Value == tour[0]).Index;
@@ -157,5 +157,5 @@
     }
 
-    private class SchemaEqualityComparer : EqualityComparer<IntArray> {
+    public class SchemaEqualityComparer : EqualityComparer<IntArray> {
       public override bool Equals(IntArray x, IntArray y) {
         if (object.ReferenceEquals(x, y)) return true;
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/SchemaOccurenceInGenerationsAnalyzer.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/SchemaOccurenceInGenerationsAnalyzer.cs	(revision 8217)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/SchemaOccurenceInGenerationsAnalyzer.cs	(revision 8217)
@@ -0,0 +1,139 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.TravelingSalesman;
+
+namespace HeuristicLab.Analysis.AlgorithmBehavior {
+
+  /// <summary>
+  /// An operator that analyzes the quality of schemas.
+  /// </summary>
+  [Item("SchemaOccurenceInGenerationsAnalyzer", "An operator that analyzes broken inheritance of building blocks.")]
+  [StorableClass]
+  public sealed class SchemaOccurenceInGenerationsAnalyzer : SingleSuccessorOperator, IAnalyzer {
+    private const string ResultsParameterName = "Results";
+    private const string PopulationGraphResultParameterName = "PopulationGraph";
+    private const string SchemataParameterName = "Schemata";
+    private const string SchemaOccurenceInGenerationsMatrixParameterName = "SchemaOccurenceInGenerationsMatrix";
+    private const string QualitiesParameterName = "Qualities";
+    private const string DistanceMatrixParameterName = "DistanceMatrix";
+    private const string GenerationsParameterName = "Generations";
+
+    #region IAnalyzer Members
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    #endregion
+
+    #region Parameter properties
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DistanceMatrix>)Parameters[DistanceMatrixParameterName]; }
+    }
+    public ILookupParameter<IntValue> GenerationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
+    }
+    #endregion
+
+    #region Properties
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+    public DistanceMatrix DistanceMatrix {
+      get { return DistanceMatrixParameter.ActualValue; }
+    }
+    public HeuristicLab.Analysis.DataTable Qualities {
+      get { return ((HeuristicLab.Analysis.DataTable)ResultsParameter.ActualValue[QualitiesParameterName].Value); }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private SchemaOccurenceInGenerationsAnalyzer(bool deserializing) : base(deserializing) { }
+    private SchemaOccurenceInGenerationsAnalyzer(SchemaOccurenceInGenerationsAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public SchemaOccurenceInGenerationsAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should are stored."));
+      Parameters.Add(new LookupParameter<DistanceMatrix>(DistanceMatrixParameterName, "The distance matrix of the TSP."));
+      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "Nr of generations."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SchemaOccurenceInGenerationsAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var graph = (GenealogyGraph<Permutation>)Results[PopulationGraphResultParameterName].Value;
+      var schemata = (ItemArray<IntArray>)Results[SchemataParameterName].Value;
+
+      var schemataMatrix = new Dictionary<IntArray, string>(new HeuristicLab.Analysis.AlgorithmBehavior.SchemaAnalyzer.SchemaEqualityComparer());
+      foreach (var schema in schemata) {
+        if (!schemataMatrix.ContainsKey(schema)) {
+          string result = ExploreSchemaCountOverGenerations(graph, schema);
+          schemataMatrix.Add(schema, result);
+        }
+      }
+
+      // order schemas according to their global occurrence count
+      var sortedSchemataMatrix = schemataMatrix.OrderByDescending(x => x.Value[0]).ToDictionary(x => x.Key, x => x.Value);
+
+      var stringMatrix = new StringMatrix(sortedSchemataMatrix.Keys.Count, 2);
+      for (int i = 0; i < sortedSchemataMatrix.Keys.Count; i++) {
+        var element = sortedSchemataMatrix.ElementAt(i);
+        stringMatrix[i, 0] = new Permutation(PermutationTypes.RelativeUndirected, element.Key).ToString();
+        stringMatrix[i, 1] = element.Value;
+      }
+      stringMatrix.ColumnNames = new[] { "Schema", "SchemaCountOverGeneration" };
+
+      Results.Add(new Result(SchemaOccurenceInGenerationsMatrixParameterName, stringMatrix));
+
+      return base.Apply();
+    }
+
+    private string ExploreSchemaCountOverGenerations(GenealogyGraph<Permutation> graph, IntArray schema) {
+      int[] occurences = new int[GenerationsParameter.ActualValue.Value + 1];
+
+      foreach (var individual in graph.Values) {
+        if (SchemaAnalyzer.IsSubtour(schema, (Permutation)individual.Data)) {
+          occurences[(int)individual.Rank]++;
+        }
+      }
+
+      StringBuilder builder = new StringBuilder();
+      foreach (int x in occurences)
+        builder.Append(x.ToString() + ", ");
+
+      return builder.ToString();
+    }
+  }
+}
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/SchemaQualityAnalyzer.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/SchemaQualityAnalyzer.cs	(revision 8217)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/SchemaQualityAnalyzer.cs	(revision 8217)
@@ -0,0 +1,178 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.TravelingSalesman;
+
+namespace HeuristicLab.Analysis.AlgorithmBehavior {
+
+  /// <summary>
+  /// An operator that analyzes the quality of schemas.
+  /// </summary>
+  [Item("SchemaQualityAnalyzer", "An operator that analyzes broken inheritance of building blocks.")]
+  [StorableClass]
+  public sealed class SchemaQualityAnalyzer : SingleSuccessorOperator, IAnalyzer {
+    private const string ResultsParameterName = "Results";
+    private const string PopulationGraphResultParameterName = "PopulationGraph";
+    private const string SchemataParameterName = "Schemata";
+    private const string SchemaQualityMatrixParameterName = "SchemaQualityMatrix";
+    private const string QualitiesParameterName = "Qualities";
+    private const string DistanceMatrixParameterName = "DistanceMatrix";
+    private const string GenerationsParameterName = "Generations";
+
+    #region IAnalyzer Members
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    #endregion
+
+    #region Parameter properties
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DistanceMatrix>)Parameters[DistanceMatrixParameterName]; }
+    }
+    public ILookupParameter<IntValue> GenerationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
+    }
+    #endregion
+
+    #region Properties
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+    public DistanceMatrix DistanceMatrix {
+      get { return DistanceMatrixParameter.ActualValue; }
+    }
+    public HeuristicLab.Analysis.DataTable Qualities {
+      get { return ((HeuristicLab.Analysis.DataTable)ResultsParameter.ActualValue[QualitiesParameterName].Value); }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private SchemaQualityAnalyzer(bool deserializing) : base(deserializing) { }
+    private SchemaQualityAnalyzer(SchemaQualityAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public SchemaQualityAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should are stored."));
+      Parameters.Add(new LookupParameter<DistanceMatrix>(DistanceMatrixParameterName, "The distance matrix of the TSP."));
+      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "Nr of generations."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SchemaQualityAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var graph = (GenealogyGraph<Permutation>)Results[PopulationGraphResultParameterName].Value;
+      var schemata = (ItemArray<IntArray>)Results[SchemataParameterName].Value;
+
+      var schemataMatrix = new Dictionary<IntArray, int[]>(new HeuristicLab.Analysis.AlgorithmBehavior.SchemaAnalyzer.SchemaEqualityComparer());
+      int qualityPoints = 0;
+      int worseQualityPoints = 0;
+      foreach (var schema in schemata) {
+        if (!schemataMatrix.ContainsKey(schema)) {
+          var categories = new int[5];
+          categories[0] = ExploreGlobalSchemaOccurrence(graph, schema, out qualityPoints, out worseQualityPoints);
+          categories[1] = qualityPoints;
+          categories[2] = worseQualityPoints;
+          categories[3] = (qualityPoints != 0 && worseQualityPoints != 0) ? (int)((qualityPoints / ((double)worseQualityPoints)) * 100.0) : 0;
+          categories[4] = ExploreSchemaGradientOverGenerations(graph, schema);
+          schemataMatrix.Add(schema, categories);
+        }
+      }
+
+      // order schemas according to their global occurrence count
+      var sortedSchemataMatrix = schemataMatrix.OrderByDescending(x => x.Value[0]).ToDictionary(x => x.Key, x => x.Value);
+
+      var stringMatrix = new StringMatrix(sortedSchemataMatrix.Keys.Count, 6);
+      for (int i = 0; i < sortedSchemataMatrix.Keys.Count; i++) {
+        var element = sortedSchemataMatrix.ElementAt(i);
+        stringMatrix[i, 0] = new Permutation(PermutationTypes.RelativeUndirected, element.Key).ToString();
+        for (int j = 0; j < element.Value.Count(); j++) {
+          stringMatrix[i, j + 1] = element.Value[j].ToString();
+        }
+      }
+      stringMatrix.ColumnNames = new[] { "Schema", "GlobalSchemaOccurrence", "Better than Avg. Schemata", "Worse than Avg. Schemata", "Ratio", "Gradient" };
+
+      Results.Add(new Result(SchemaQualityMatrixParameterName, stringMatrix));
+
+      return base.Apply();
+    }
+
+    private int ExploreSchemaGradientOverGenerations(GenealogyGraph<Permutation> graph, IntArray schema) {
+      int[] occurences = new int[GenerationsParameter.ActualValue.Value + 1];
+      double gradient = 0.0;
+
+      foreach (var individual in graph.Values) {
+        if (SchemaAnalyzer.IsSubtour(schema, (Permutation)individual.Data)) {
+          occurences[(int)individual.Rank]++;
+        }
+      }
+
+      for (int i = 0; i < occurences.Length - 1; i++) {
+        int occurence = occurences[i + 1] - occurences[i];
+
+        if (occurences[i + 1] != 0 && occurences[i] != 0) {
+          if (occurence != 0) {
+            gradient += occurences[i + 1] - occurences[i];
+          } else {
+            gradient += 0.5; //TODO: scale this
+          }
+        }
+      }
+
+      return (int)Math.Round(gradient);
+    }
+
+    private int ExploreGlobalSchemaOccurrence(GenealogyGraph<Permutation> graph, IntArray schema, out int qualityPoint, out int worstQualityPoint) {
+      int occurrences = 0;
+      qualityPoint = 0;
+      worstQualityPoint = 0;
+      foreach (var individual in graph.Values) {
+        if (SchemaAnalyzer.IsSubtour(schema, (Permutation)individual.Data)) {
+          occurrences++;
+
+          Permutation p = (Permutation)individual.Data;
+          double pQuality = TSPDistanceMatrixEvaluator.Apply(DistanceMatrix, p);
+
+          if (Qualities.Rows["CurrentAverageQuality"].Values[(int)individual.Rank] > pQuality) {
+            qualityPoint += 1;
+          } else {
+            worstQualityPoint += 1;
+          }
+        }
+      }
+      return occurrences;
+    }
+  }
+}
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/HeuristicLab.Analysis.AlgorithmBehavior-3.3.csproj
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/HeuristicLab.Analysis.AlgorithmBehavior-3.3.csproj	(revision 8216)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/HeuristicLab.Analysis.AlgorithmBehavior-3.3.csproj	(revision 8217)
@@ -38,29 +38,50 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
     <Reference Include="HeuristicLab.Collections-3.3">
       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Common-3.3">
       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
-    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
     <Reference Include="HeuristicLab.Core-3.3">
       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
-    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
-    <Reference Include="HeuristicLab.Encodings.PermutationEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.PermutationEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
     <Reference Include="HeuristicLab.Operators-3.3">
       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Optimization-3.3">
       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Parameters-3.3">
       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Persistence-3.3">
       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
-    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.TravelingSalesman-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
@@ -76,4 +97,6 @@
     <Compile Include="Analyzers\BuildingBlockAnalyzer.cs" />
     <Compile Include="Analyzers\BrokenInteritanceSchemaAnalyzer.cs" />
+    <Compile Include="Analyzers\SchemaOccurenceInGenerationsAnalyzer.cs" />
+    <Compile Include="Analyzers\SchemaQualityAnalyzer.cs" />
     <Compile Include="Analyzers\SchemaAnalyzer.cs" />
     <Compile Include="Analyzers\GenealogyAnalyzer.cs" />
