Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/AlgorithmBehaviorHelpers.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/AlgorithmBehaviorHelpers.cs	(revision 8227)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/AlgorithmBehaviorHelpers.cs	(revision 8227)
@@ -0,0 +1,92 @@
+﻿#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+
+namespace HeuristicLab.Analysis.AlgorithmBehavior {
+  public static class AlgorithmBehaviorHelpers {
+    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;
+      bool isSubtour = true;
+      for (int i = 1; i < tour.Length; i++) {
+        if (tour[i] == permutation[(idx + 1) % permutation.Length]) { // check right side
+          idx = (idx + 1) % permutation.Length;
+        } else if (tour[i] == permutation[(idx - 1 + permutation.Length) % permutation.Length]) { // check left side
+          idx = (idx - 1 + permutation.Length) % permutation.Length;
+        } else {
+          isSubtour = false;
+          break;
+        }
+      }
+      return isSubtour;
+    }
+
+    public static ItemArray<IntArray> ExtractSubtours(Permutation permutation) {
+      var subtours = new List<IntArray>();
+      for (int i = 2; i <= permutation.Count() / 2; i++) { // increase schema length from 2 to n/2
+        for (int j = 0; j < permutation.Count(); j++) { // visit all positions in the permutation
+          var schema = new IntArray(i);
+          for (int k = 0; k < i; k++) schema[k] = permutation[(j + k) % permutation.Length]; // copy edge to schema
+          subtours.Add(schema);
+        }
+      }
+      return new ItemArray<IntArray>(subtours);
+    }
+
+    public static string CalculateBrokenInheritanceOccurrences(IntArray schema, GenealogyGraphNode individual) {
+      ISet<int> generations = new SortedSet<int>();
+      if (IsMatch(schema, ((Permutation)individual.Data).ToArray())) generations.Add(0);
+      var filteredDescendants = individual.Descendants().Where(x => IsMatch(schema, ((Permutation)x.Data).ToArray()));
+      if (filteredDescendants.Any()) {
+        foreach (var descendant in filteredDescendants) {
+          generations.Add((int)descendant.Rank);
+        }
+      }
+
+      StringBuilder sb = new StringBuilder();
+      if (generations.Any()) {
+        for (int i = 0; i < generations.Count; i++) {
+          if (i != 0) sb.Append(", ");
+          sb.Append(generations.ElementAt(i));
+        }
+      } else {
+        sb.Append("none");
+      }
+      return sb.ToString();
+    }
+
+    // attention: brute force matching
+    // should be replaced with KMP, BM or RK
+    public static bool IsMatch(IntArray pattern, int[] tour) {
+      bool match = false;
+      for (int i = 0; i <= tour.Length - pattern.Length && !match; i++) {
+        for (int j = 0; j < pattern.Length && (match = pattern[j] == tour[i + j] || pattern[j] == -1); j++) ;
+      }
+      return match;
+    }
+  }
+}
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/BestIndividualSchemaAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/BestIndividualSchemaAnalyzer.cs	(revision 8226)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/BestIndividualSchemaAnalyzer.cs	(revision 8227)
@@ -26,7 +26,7 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.TravelingSalesman;
 
 namespace HeuristicLab.Analysis.AlgorithmBehavior {
-  using HeuristicLab.Problems.TravelingSalesman;
 
   /// <summary>
@@ -66,5 +66,5 @@
     public BestIndividualSchemaAnalyzer()
       : base() {
-      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should are stored."));
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
     }
 
@@ -74,5 +74,5 @@
 
     public override IOperation Apply() {
-      var subtours = SchemaAnalyzer.ExtractSubtours(BestSolution.Permutation);
+      var subtours = AlgorithmBehaviorHelpers.ExtractSubtours(BestSolution.Permutation);
       Results.Add(new Result(SchemataParameterName, subtours));
       return base.Apply();
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/BrokenInheritanceWildcardAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/BrokenInheritanceWildcardAnalyzer.cs	(revision 8227)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/BrokenInheritanceWildcardAnalyzer.cs	(revision 8227)
@@ -0,0 +1,101 @@
+﻿#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 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;
+
+namespace HeuristicLab.Analysis.AlgorithmBehavior {
+
+  /// <summary>
+  /// An operator that analyzes broken inheritance of wildcards.
+  /// </summary>
+  [Item("BrokenInheritanceWildcardAnalyzer", "An operator that analyzes broken inheritance of wildcards.")]
+  [StorableClass]
+  public sealed class BrokenInheritanceWildcardAnalyzer : SingleSuccessorOperator, IAnalyzer {
+    private const string ResultsParameterName = "Results";
+    private const string PopulationGraphResultName = "PopulationGraph";
+    private const string WildcardsResultName = "Wildcards";
+    private const string BrokenInteritanceWildcardOccurrenceMatrixParameterName = "BrokenInteritanceWildcardOccurrenceMatrix";
+
+    #region IAnalyzer Members
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    #endregion
+
+    #region Parameter properties
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    #endregion
+
+    #region Properties
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private BrokenInheritanceWildcardAnalyzer(bool deserializing) : base(deserializing) { }
+    private BrokenInheritanceWildcardAnalyzer(BrokenInheritanceWildcardAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public BrokenInheritanceWildcardAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BrokenInheritanceWildcardAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var graph = (GenealogyGraph<Permutation>)Results[PopulationGraphResultName].Value;
+      var wildcards = (ItemArray<IntArray>)Results[WildcardsResultName].Value;
+      var generationZero = graph.Values.Where(x => x.Rank == 0);
+
+      var buildingBlockMatrix = new StringMatrix(wildcards.Count(), generationZero.Count());
+      var rowNames = new List<string>();
+      var columnNames = new List<string>();
+      for (int i = 0; i < wildcards.Count(); i++) {
+        var wildcard = wildcards[i];
+        rowNames.Add(new Permutation(PermutationTypes.RelativeUndirected, wildcard).ToString());
+        for (int j = 0; j < generationZero.Count(); j++) {
+          var individual = generationZero.ElementAt(j);
+          if (i == 0) columnNames.Add(((Permutation)individual.Data).ToString());
+          buildingBlockMatrix[i, j] = AlgorithmBehaviorHelpers.CalculateBrokenInheritanceOccurrences(wildcard, individual);
+        }
+      }
+
+      buildingBlockMatrix.RowNames = rowNames;
+      buildingBlockMatrix.ColumnNames = columnNames;
+      Results.Add(new Result(BrokenInteritanceWildcardOccurrenceMatrixParameterName, buildingBlockMatrix));
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/BrokenInteritanceSchemaAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/BrokenInteritanceSchemaAnalyzer.cs	(revision 8226)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/BrokenInteritanceSchemaAnalyzer.cs	(revision 8227)
@@ -34,13 +34,13 @@
 
   /// <summary>
-  /// An operator that analyzes broken inheritance of building blocks.
+  /// An operator that analyzes broken inheritance of schemata.
   /// </summary>
-  [Item("BrokenInteritanceSchemaAnalyzer", "An operator that analyzes broken inheritance of building blocks.")]
+  [Item("BrokenInteritanceSchemaAnalyzer", "An operator that analyzes broken inheritance of schemata.")]
   [StorableClass]
   public sealed class BrokenInteritanceSchemaAnalyzer : SingleSuccessorOperator, IAnalyzer {
     private const string ResultsParameterName = "Results";
-    private const string PopulationGraphResultParameterName = "PopulationGraph";
-    private const string SchemataParameterName = "Schemata";
-    private const string BrokenInteritanceSchemaOccurrenceName = "BrokenInteritanceSchemaOccurrenceMatrix";
+    private const string PopulationGraphResultName = "PopulationGraph";
+    private const string SchemataResultName = "Schemata";
+    private const string BrokenInteritanceSchemaOccurrenceMatrixResultName = "BrokenInteritanceSchemaOccurrenceMatrix";
 
     #region IAnalyzer Members
@@ -67,5 +67,5 @@
     public BrokenInteritanceSchemaAnalyzer()
       : base() {
-      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should are stored."));
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
     }
 
@@ -75,6 +75,6 @@
 
     public override IOperation Apply() {
-      var graph = (GenealogyGraph<Permutation>)Results[PopulationGraphResultParameterName].Value;
-      var schemata = (ItemArray<IntArray>)Results[SchemataParameterName].Value;
+      var graph = (GenealogyGraph<Permutation>)Results[PopulationGraphResultName].Value;
+      var schemata = (ItemArray<IntArray>)Results[SchemataResultName].Value;
       var generationZero = graph.Values.Where(x => x.Rank == 0);
 
@@ -88,28 +88,13 @@
           var individual = generationZero.ElementAt(j);
           if (i == 0) brokenColumnNames.Add(((Permutation)individual.Data).ToString());
-          brokenInteritanceSchemaOccurrenceMatrix[i, j] = CalculateBrokenInheritanceOccurrences(schema, individual).ToString();
+          brokenInteritanceSchemaOccurrenceMatrix[i, j] = AlgorithmBehaviorHelpers.CalculateBrokenInheritanceOccurrences(schema, individual);
         }
       }
       brokenInteritanceSchemaOccurrenceMatrix.RowNames = brokenRowNames;
       brokenInteritanceSchemaOccurrenceMatrix.ColumnNames = brokenColumnNames;
-      Results.Add(new Result(BrokenInteritanceSchemaOccurrenceName, brokenInteritanceSchemaOccurrenceMatrix));
+      Results.Add(new Result(BrokenInteritanceSchemaOccurrenceMatrixResultName, brokenInteritanceSchemaOccurrenceMatrix));
 
       return base.Apply();
     }
-
-    private int CalculateBrokenInheritanceOccurrences(IntArray schema, GenealogyGraphNode individual) {
-      var filteredDescendants = individual.Descendants().Where(x => IsMatch(schema, ((Permutation)x.Data).ToArray()));
-      return filteredDescendants.Any() ? (int)filteredDescendants.Max(x => x.Rank) : 0;
-    }
-
-    // attention: brute force matching
-    // should be replaced with KMP, BM or RK
-    private bool IsMatch(IntArray pattern, int[] tour) {
-      bool match = false;
-      for (int i = 0; i <= tour.Length - pattern.Length && !match; i++) {
-        for (int j = 0; j < pattern.Length && (match = pattern[j] == tour[i + j] || pattern[j] == -1); j++) ;
-      }
-      return match;
-    }
   }
 }
Index: anches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/BuildingBlockAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/BuildingBlockAnalyzer.cs	(revision 8226)
+++ 	(revision )
@@ -1,263 +1,0 @@
-﻿#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.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Analysis.AlgorithmBehavior {
-  using System;
-  using System.Collections.Generic;
-  using HeuristicLab.Data;
-  using HeuristicLab.Encodings.PermutationEncoding;
-  using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
-
-  /// <summary>
-  /// An operator that analyzes building blocks.
-  /// </summary>
-  [Item("BuildingBlockAnalyzer", "An operator that analyzes building blocks.")]
-  [StorableClass]
-  public sealed class BuildingBlockAnalyzer : SingleSuccessorOperator, IAnalyzer {
-    private const string GlobalTraceMapParameterName = "GlobalTraceMap";
-    private const string ResultsParameterName = "Results";
-    private const string PopulationGraphResultParameterName = "PopulationGraph";
-    private const string BuildingBlockSchemaMatrixParameterName = "BuildingBlockSchemaMatrix";
-    private const string BrokenInteritanceSchemaOccurrenceName = "BrokenInteritanceSchemaOccurrenceMatrix";
-    private const string UnbrokenInteritanceSchemaOccurrenceName = "UnbrokenInteritanceSchemaOccurrence";
-    private const string BuildingBlockPatternMatrixParameterName = "BuildingBlockPatternMatrix";
-
-    #region IAnalyzer Members
-    public bool EnabledByDefault {
-      get { return true; }
-    }
-    #endregion
-
-    #region Parameter properties
-    public ILookupParameter<TraceMapType> GlobalTraceMapParameter {
-      get { return (ILookupParameter<TraceMapType>)Parameters[GlobalTraceMapParameterName]; }
-    }
-    public ILookupParameter<ResultCollection> ResultsParameter {
-      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
-    }
-    #endregion
-
-    #region Properties
-    public TraceMapType GlobalTraceMap {
-      get { return GlobalTraceMapParameter.ActualValue; }
-    }
-    public ResultCollection Results {
-      get { return ResultsParameter.ActualValue; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    private BuildingBlockAnalyzer(bool deserializing) : base(deserializing) { }
-    private BuildingBlockAnalyzer(BuildingBlockAnalyzer original, Cloner cloner) : base(original, cloner) { }
-    public BuildingBlockAnalyzer()
-      : base() {
-      Parameters.Add(new LookupParameter<TraceMapType>(GlobalTraceMapParameterName, "A global cache containing the whole genealogy."));
-      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should are stored."));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new BuildingBlockAnalyzer(this, cloner);
-    }
-
-    public override IOperation Apply() {
-      var graph = (GenealogyGraph<Permutation>)Results[PopulationGraphResultParameterName].Value;
-      var generationZero = graph.Values.Where(x => x.Rank == 0);
-
-      // extract all subtours for each individual in generation zero
-      var subtours = new Dictionary<Permutation, IList<int[]>>();
-      foreach (var individual in generationZero) {
-        subtours[(Permutation)individual.Data] = ExtractSubtours((Permutation)individual.Data);
-      }
-
-      // process all schemata
-      var schemataMatrix = new Dictionary<int[], int[]>(new SchemaEqualityComparer());
-      foreach (var entry in subtours) {
-        foreach (var schema in entry.Value) {
-          if (!schemataMatrix.ContainsKey(schema)) {
-            var categories = new int[3];
-            categories[0] = ExploreGlobalSchemaOccurrence(graph, schema);
-            categories[1] = -1;
-            categories[2] = -1;
-            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);
-      IList<string> rowNames = new List<string>();
-      var schemataStringMatrix = new StringMatrix(sortedSchemataMatrix.Keys.Count, 3);
-      for (int i = 0; i < sortedSchemataMatrix.Keys.Count; i++) {
-        var element = sortedSchemataMatrix.ElementAt(i);
-        rowNames.Add(new Permutation(PermutationTypes.RelativeUndirected, element.Key).ToString());
-        for (int j = 0; j < element.Value.Count(); j++) {
-          schemataStringMatrix[i, j] = element.Value[j].ToString();
-        }
-      }
-      schemataStringMatrix.RowNames = rowNames;
-      schemataStringMatrix.ColumnNames = new[] { "GlobalSchemaOccurrence", "<unused>", "<unused>" };
-      Results.Add(new Result(BuildingBlockSchemaMatrixParameterName, schemataStringMatrix));
-
-      var brokenInteritanceSchemaOccurrenceMatrix = new StringMatrix(sortedSchemataMatrix.Keys.Count, generationZero.Count());
-      IList<string> brokenRowNames = new List<string>();
-      IList<string> brokenColumnNames = new List<string>();
-      for (int i = 0; i < sortedSchemataMatrix.Keys.Count; i++) {
-        var entry = sortedSchemataMatrix.ElementAt(i);
-        brokenRowNames.Add(new Permutation(PermutationTypes.RelativeUndirected, entry.Key).ToString());
-        for (int j = 0; j < generationZero.Count(); j++) {
-          var individual = generationZero.ElementAt(j);
-          if (i == 0) brokenColumnNames.Add(((Permutation)individual.Data).ToString());
-          brokenInteritanceSchemaOccurrenceMatrix[i, j] = CalculateBrokenInheritanceOccurrences(entry.Key, individual).ToString();
-        }
-      }
-      brokenInteritanceSchemaOccurrenceMatrix.RowNames = brokenRowNames;
-      brokenInteritanceSchemaOccurrenceMatrix.ColumnNames = brokenColumnNames;
-      Results.Add(new Result(BrokenInteritanceSchemaOccurrenceName, brokenInteritanceSchemaOccurrenceMatrix));
-
-      var unbrokenInteritanceSchemaOccurrenceMatrix = new StringMatrix(sortedSchemataMatrix.Keys.Count, generationZero.Count());
-      IList<string> unbrokenRowNames = new List<string>();
-      IList<string> unbrokenColumnNames = new List<string>();
-      for (int i = 0; i < sortedSchemataMatrix.Keys.Count; i++) {
-        var entry = sortedSchemataMatrix.ElementAt(i);
-        unbrokenRowNames.Add(new Permutation(PermutationTypes.RelativeUndirected, entry.Key).ToString());
-        for (int j = 0; j < generationZero.Count(); j++) {
-          var individual = generationZero.ElementAt(j);
-          if (i == 0) unbrokenColumnNames.Add(((Permutation)individual.Data).ToString());
-          unbrokenInteritanceSchemaOccurrenceMatrix[i, j] = CalculateUnbrokenInheritanceOccurrences(entry.Key, individual).ToString();
-        }
-      }
-      unbrokenInteritanceSchemaOccurrenceMatrix.RowNames = unbrokenRowNames;
-      unbrokenInteritanceSchemaOccurrenceMatrix.ColumnNames = brokenColumnNames;
-      Results.Add(new Result(UnbrokenInteritanceSchemaOccurrenceName, unbrokenInteritanceSchemaOccurrenceMatrix));
-
-      return base.Apply();
-    }
-
-    private int CalculateBrokenInheritanceOccurrences(int[] schema, GenealogyGraphNode individual) {
-      // TODO
-      return -1;
-    }
-
-    private int CalculateUnbrokenInheritanceOccurrences(int[] schema, GenealogyGraphNode individual) {
-      var filteredDescendants = individual.Descendants().Where(x => IsMatch(schema, ((Permutation)x.Data).ToArray()));
-      return filteredDescendants.Any() ? (int)filteredDescendants.Max(x => x.Rank) : 0;
-    }
-
-    private int ExploreGlobalSchemaOccurrence(GenealogyGraph<Permutation> graph, int[] schema) {
-      int occurrences = 0;
-      foreach (var individual in graph.Values)
-        if (IsSubtour(schema, (Permutation)individual.Data)) occurrences++;
-      return occurrences;
-    }
-
-    private IList<int[]> ExtractSubtours(Permutation permutation) {
-      var subtours = new List<int[]>();
-      for (int i = 2; i <= permutation.Count() / 2; i++) { // increase schema length from 2 to n/2
-        for (int j = 0; j < permutation.Count(); j++) { // visit all positions in the permutation
-          var schema = new int[i];
-          for (int k = 0; k < i; k++) schema[k] = permutation[(j + k) % permutation.Length]; // copy edge to schema
-          subtours.Add(schema);
-        }
-      }
-      return subtours;
-    }
-
-    private bool IsSubtour(int[] 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;
-      bool isSubtour = true;
-      for (int i = 1; i < tour.Length; i++) {
-        if (tour[i] == permutation[(idx + 1) % permutation.Length]) { // check right side
-          idx = (idx + 1) % permutation.Length;
-        } else if (tour[i] == permutation[(idx - 1 + permutation.Length) % permutation.Length]) { // check left side
-          idx = (idx - 1 + permutation.Length) % permutation.Length;
-        } else {
-          isSubtour = false;
-          break;
-        }
-      }
-      return isSubtour;
-    }
-
-    // attention: brute force matching
-    // should be replaced with KMP, BM or RK
-    private bool IsMatch(int[] pattern, int[] tour) {
-      bool match = false;
-      for (int i = 0; i <= tour.Length - pattern.Length && !match; i++) {
-        for (int j = 0; j < pattern.Length && (match = pattern[j] == tour[i + j] || pattern[j] == -1); j++) ;
-      }
-      return match;
-    }
-
-    private IList<int[]> GenerateWildcardSchemata(int[] schema) {
-      string formatString = "{0:d" + schema.Length + "}";
-      var combs = new List<bool[]>();
-      string comb = string.Empty;
-
-      // create all desired wildcard combinations
-      int i = 0;
-      int wildcardCount = 0; // first wildcard combination contains no wildcards
-      while (wildcardCount < schema.Length) {
-        if (wildcardCount > schema.Length / 8 && wildcardCount < schema.Length / 2)
-          combs.Add(comb.Select(x => x == '1').ToArray()); // '1' becomes true which indicates a wildcard
-        wildcardCount = (comb = string.Format(formatString, Convert.ToString(++i, 2))).Count(x => x == '1');
-      }
-
-      // create all desired wildcard instances
-      var wildcardSchemata = new List<int[]>();
-      foreach (var c in combs) {
-        wildcardSchemata.Add(schema.Select((x, index) => c[index] ? -1 : x).ToArray()); // -1 is a wildcard in the schema
-      }
-
-      return wildcardSchemata;
-    }
-
-
-    private class SchemaEqualityComparer : EqualityComparer<int[]> {
-      public override bool Equals(int[] x, int[] y) {
-        if (object.ReferenceEquals(x, y)) return true;
-        if (x == null || y == null || x.Length != y.Length) return false;
-        EqualityComparer<int> comparer = EqualityComparer<int>.Default;
-        bool match = true;
-        for (int i = 0; i < x.Length && match; i++) // check normal tour
-          if (!comparer.Equals(x[i], y[i])) match = false;
-        if (!match) {
-          match = true;
-          for (int i = x.Length - 1; i >= 0 && match; i--) // check inverse tour
-            if (!comparer.Equals(x[i], y[i])) match = false;
-        }
-        return match;
-      }
-
-      public override int GetHashCode(int[] obj) {
-        return 0; // return the same hash code for each object, otherwise Equals will not be called
-      }
-    }
-  }
-}
Index: anches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/SchemaAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/SchemaAnalyzer.cs	(revision 8226)
+++ 	(revision )
@@ -1,179 +1,0 @@
-﻿#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.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Analysis.AlgorithmBehavior {
-  using System.Collections.Generic;
-  using HeuristicLab.Data;
-  using HeuristicLab.Encodings.PermutationEncoding;
-  using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
-
-  /// <summary>
-  /// An operator that analyzes schemata.
-  /// </summary>
-  [Item("SchemaAnalyzer", "An operator that analyzes schemata.")]
-  [StorableClass]
-  public sealed class SchemaAnalyzer : SingleSuccessorOperator, IAnalyzer {
-    private const string GlobalTraceMapParameterName = "GlobalTraceMap";
-    private const string ResultsParameterName = "Results";
-    private const string PopulationGraphResultParameterName = "PopulationGraph";
-    private const string SchemaMatrixParameterName = "SchemaMatrix";
-    private const string SchemataParameterName = "Schemata";
-
-    #region IAnalyzer Members
-    public bool EnabledByDefault {
-      get { return true; }
-    }
-    #endregion
-
-    #region Parameter properties
-    public ILookupParameter<TraceMapType> GlobalTraceMapParameter {
-      get { return (ILookupParameter<TraceMapType>)Parameters[GlobalTraceMapParameterName]; }
-    }
-    public ILookupParameter<ResultCollection> ResultsParameter {
-      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
-    }
-    #endregion
-
-    #region Properties
-    public TraceMapType GlobalTraceMap {
-      get { return GlobalTraceMapParameter.ActualValue; }
-    }
-    public ResultCollection Results {
-      get { return ResultsParameter.ActualValue; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    private SchemaAnalyzer(bool deserializing) : base(deserializing) { }
-    private SchemaAnalyzer(SchemaAnalyzer original, Cloner cloner) : base(original, cloner) { }
-    public SchemaAnalyzer()
-      : base() {
-      Parameters.Add(new LookupParameter<TraceMapType>(GlobalTraceMapParameterName, "A global cache containing the whole genealogy."));
-      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should are stored."));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SchemaAnalyzer(this, cloner);
-    }
-
-    public override IOperation Apply() {
-      var graph = (GenealogyGraph<Permutation>)Results[PopulationGraphResultParameterName].Value;
-      var generationZero = graph.Values.Where(x => x.Rank == 0);
-
-      // extract all subtours for each individual in generation zero
-      var subtours = new Dictionary<Permutation, ItemArray<IntArray>>();
-      foreach (var individual in generationZero) {
-        subtours[(Permutation)individual.Data] = ExtractSubtours((Permutation)individual.Data);
-      }
-
-      // process all schemata
-      var schemataMatrix = new Dictionary<IntArray, int>(new SchemaEqualityComparer());
-      foreach (var entry in subtours) {
-        foreach (var schema in entry.Value) {
-          if (!schemataMatrix.ContainsKey(schema)) {
-            schemataMatrix.Add(schema, ExploreGlobalSchemaOccurrence(graph, schema));
-          }
-        }
-      }
-
-      // order schemas according to their global occurrence count
-      var sortedSchemataMatrix = schemataMatrix.OrderByDescending(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
-      IList<string> rowNames = new List<string>();
-      var schemataStringMatrix = new StringMatrix(sortedSchemataMatrix.Keys.Count, 1);
-      for (int i = 0; i < sortedSchemataMatrix.Keys.Count; i++) {
-        var element = sortedSchemataMatrix.ElementAt(i);
-        rowNames.Add(new Permutation(PermutationTypes.RelativeUndirected, element.Key).ToString());
-        schemataStringMatrix[i, 0] = element.Value.ToString();
-      }
-      schemataStringMatrix.RowNames = rowNames;
-      schemataStringMatrix.ColumnNames = new[] { "GlobalSchemaOccurrence" };
-
-      Results.Add(new Result(SchemataParameterName, new ItemArray<IntArray>(schemataMatrix.Keys)));
-      Results.Add(new Result(SchemaMatrixParameterName, schemataStringMatrix));
-
-      return base.Apply();
-    }
-
-    private int ExploreGlobalSchemaOccurrence(GenealogyGraph<Permutation> graph, IntArray schema) {
-      int occurrences = 0;
-      foreach (var individual in graph.Values)
-        if (IsSubtour(schema, (Permutation)individual.Data)) occurrences++;
-      return occurrences;
-    }
-
-    public static ItemArray<IntArray> ExtractSubtours(Permutation permutation) {
-      var subtours = new List<IntArray>();
-      for (int i = 2; i <= permutation.Count() / 2; i++) { // increase schema length from 2 to n/2
-        for (int j = 0; j < permutation.Count(); j++) { // visit all positions in the permutation
-          var schema = new IntArray(i);
-          for (int k = 0; k < i; k++) schema[k] = permutation[(j + k) % permutation.Length]; // copy edge to schema
-          subtours.Add(schema);
-        }
-      }
-      return new ItemArray<IntArray>(subtours);
-    }
-
-    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;
-      bool isSubtour = true;
-      for (int i = 1; i < tour.Length; i++) {
-        if (tour[i] == permutation[(idx + 1) % permutation.Length]) { // check right side
-          idx = (idx + 1) % permutation.Length;
-        } else if (tour[i] == permutation[(idx - 1 + permutation.Length) % permutation.Length]) { // check left side
-          idx = (idx - 1 + permutation.Length) % permutation.Length;
-        } else {
-          isSubtour = false;
-          break;
-        }
-      }
-      return isSubtour;
-    }
-
-    public class SchemaEqualityComparer : EqualityComparer<IntArray> {
-      public override bool Equals(IntArray x, IntArray y) {
-        if (object.ReferenceEquals(x, y)) return true;
-        if (x == null || y == null || x.Length != y.Length) return false;
-        bool match = true;
-        for (int i = 0; i < x.Length && match; i++) // check normal tour
-          if (x[i] != y[i]) match = false;
-        if (!match) {
-          match = true;
-          for (int i = x.Length - 1; i >= 0 && match; i--) // check inverse tour
-            if (x[i] != y[i]) match = false;
-        }
-        return match;
-      }
-
-      public override int GetHashCode(IntArray obj) {
-        return 0; // return the same hash code for each object, otherwise Equals will not be called
-      }
-    }
-  }
-}
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 8226)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/SchemaOccurenceInGenerationsAnalyzer.cs	(revision 8227)
@@ -84,5 +84,5 @@
     public SchemaOccurenceInGenerationsAnalyzer()
       : base() {
-      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should are stored."));
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
       Parameters.Add(new LookupParameter<DistanceMatrix>(DistanceMatrixParameterName, "The distance matrix of the TSP."));
       Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "Nr of generations."));
@@ -97,5 +97,5 @@
       var schemata = (ItemArray<IntArray>)Results[SchemataParameterName].Value;
 
-      var schemataMatrix = new Dictionary<IntArray, string>(new HeuristicLab.Analysis.AlgorithmBehavior.SchemaAnalyzer.SchemaEqualityComparer());
+      var schemataMatrix = new Dictionary<IntArray, string>(new SchemaEqualityComparer());
       foreach (var schema in schemata) {
         if (!schemataMatrix.ContainsKey(schema)) {
@@ -125,5 +125,5 @@
 
       foreach (var individual in graph.Values) {
-        if (SchemaAnalyzer.IsSubtour(schema, (Permutation)individual.Data)) {
+        if (AlgorithmBehaviorHelpers.IsSubtour(schema, (Permutation)individual.Data)) {
           occurences[(int)individual.Rank]++;
         }
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 8226)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Analyzers/SchemaQualityAnalyzer.cs	(revision 8227)
@@ -84,5 +84,5 @@
     public SchemaQualityAnalyzer()
       : base() {
-      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should are stored."));
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
       Parameters.Add(new LookupParameter<DistanceMatrix>(DistanceMatrixParameterName, "The distance matrix of the TSP."));
       Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "Nr of generations."));
@@ -97,5 +97,5 @@
       var schemata = (ItemArray<IntArray>)Results[SchemataParameterName].Value;
 
-      var schemataMatrix = new Dictionary<IntArray, int[]>(new HeuristicLab.Analysis.AlgorithmBehavior.SchemaAnalyzer.SchemaEqualityComparer());
+      var schemataMatrix = new Dictionary<IntArray, int[]>(new SchemaEqualityComparer());
       int qualityPoints = 0;
       int worseQualityPoints = 0;
@@ -135,5 +135,5 @@
 
       foreach (var individual in graph.Values) {
-        if (SchemaAnalyzer.IsSubtour(schema, (Permutation)individual.Data)) {
+        if (AlgorithmBehaviorHelpers.IsSubtour(schema, (Permutation)individual.Data)) {
           occurences[(int)individual.Rank]++;
         }
@@ -160,5 +160,5 @@
       worstQualityPoint = 0;
       foreach (var individual in graph.Values) {
-        if (SchemaAnalyzer.IsSubtour(schema, (Permutation)individual.Data)) {
+        if (AlgorithmBehaviorHelpers.IsSubtour(schema, (Permutation)individual.Data)) {
           occurrences++;
 
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Creators/SchemataCreator.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Creators/SchemataCreator.cs	(revision 8227)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Creators/SchemataCreator.cs	(revision 8227)
@@ -0,0 +1,130 @@
+﻿#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 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;
+
+namespace HeuristicLab.Analysis.AlgorithmBehavior {
+  using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
+
+  /// <summary>
+  /// An operator that analyzes schemata.
+  /// </summary>
+  [Item("SchemataCreator", "An operator that builds schemata.")]
+  [StorableClass]
+  public sealed class SchemataCreator : SingleSuccessorOperator, IAnalyzer {
+    private const string GlobalTraceMapParameterName = "GlobalTraceMap";
+    private const string ResultsParameterName = "Results";
+    private const string PopulationGraphResultParameterName = "PopulationGraph";
+    private const string SchemaMatrixParameterName = "SchemaMatrix";
+    private const string SchemataParameterName = "Schemata";
+
+    #region IAnalyzer Members
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    #endregion
+
+    #region Parameter properties
+    public ILookupParameter<TraceMapType> GlobalTraceMapParameter {
+      get { return (ILookupParameter<TraceMapType>)Parameters[GlobalTraceMapParameterName]; }
+    }
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    #endregion
+
+    #region Properties
+    public TraceMapType GlobalTraceMap {
+      get { return GlobalTraceMapParameter.ActualValue; }
+    }
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private SchemataCreator(bool deserializing) : base(deserializing) { }
+    private SchemataCreator(SchemataCreator original, Cloner cloner) : base(original, cloner) { }
+    public SchemataCreator()
+      : base() {
+      Parameters.Add(new LookupParameter<TraceMapType>(GlobalTraceMapParameterName, "A global cache containing the whole genealogy."));
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SchemataCreator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var graph = (GenealogyGraph<Permutation>)Results[PopulationGraphResultParameterName].Value;
+      var generationZero = graph.Values.Where(x => x.Rank == 0);
+
+      // extract all subtours for each individual in generation zero
+      var subtours = new Dictionary<Permutation, ItemArray<IntArray>>();
+      foreach (var individual in generationZero) {
+        subtours[(Permutation)individual.Data] = AlgorithmBehaviorHelpers.ExtractSubtours((Permutation)individual.Data);
+      }
+
+      // process all schemata
+      var schemataMatrix = new Dictionary<IntArray, int>(new SchemaEqualityComparer());
+      foreach (var entry in subtours) {
+        foreach (var schema in entry.Value) {
+          if (!schemataMatrix.ContainsKey(schema)) {
+            schemataMatrix.Add(schema, ExploreGlobalSchemaOccurrence(graph, schema));
+          }
+        }
+      }
+
+      // order schemas according to their global occurrence count
+      var sortedSchemataMatrix = schemataMatrix.OrderByDescending(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
+      IList<string> rowNames = new List<string>();
+      var schemataStringMatrix = new StringMatrix(sortedSchemataMatrix.Keys.Count, 1);
+      for (int i = 0; i < sortedSchemataMatrix.Keys.Count; i++) {
+        var element = sortedSchemataMatrix.ElementAt(i);
+        rowNames.Add(new Permutation(PermutationTypes.RelativeUndirected, element.Key).ToString());
+        schemataStringMatrix[i, 0] = element.Value.ToString();
+      }
+      schemataStringMatrix.RowNames = rowNames;
+      schemataStringMatrix.ColumnNames = new[] { "GlobalSchemaOccurrence" };
+
+      Results.Add(new Result(SchemataParameterName, new ItemArray<IntArray>(schemataMatrix.Keys)));
+      Results.Add(new Result(SchemaMatrixParameterName, schemataStringMatrix));
+
+      return base.Apply();
+    }
+
+    private int ExploreGlobalSchemaOccurrence(GenealogyGraph<Permutation> graph, IntArray schema) {
+      int occurrences = 0;
+      foreach (var individual in graph.Values)
+        if (AlgorithmBehaviorHelpers.IsSubtour(schema, (Permutation)individual.Data)) occurrences++;
+      return occurrences;
+    }
+  }
+}
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Creators/WildcardsCreator.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Creators/WildcardsCreator.cs	(revision 8227)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/Creators/WildcardsCreator.cs	(revision 8227)
@@ -0,0 +1,110 @@
+﻿#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.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis.AlgorithmBehavior {
+
+  /// <summary>
+  /// An operator that analyzes wildcards.
+  /// </summary>
+  [Item("WildcardsCreator", "An operator that builds wildcards.")]
+  [StorableClass]
+  public sealed class WildcardsCreator : SingleSuccessorOperator, IAnalyzer {
+    private const string ResultsParameterName = "Results";
+    private const string SchemataResultName = "Schemata";
+    private const string WildcardsResultName = "Wildcards";
+
+    #region IAnalyzer Members
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    #endregion
+
+    #region Parameter properties
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    #endregion
+
+    #region Properties
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private WildcardsCreator(bool deserializing) : base(deserializing) { }
+    private WildcardsCreator(WildcardsCreator original, Cloner cloner) : base(original, cloner) { }
+    public WildcardsCreator()
+      : base() {
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new WildcardsCreator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var schemata = (ItemArray<IntArray>)Results[SchemataResultName].Value;
+      var wildcards = new List<IntArray>();
+      foreach (var schema in schemata) {
+        wildcards.AddRange(GenerateWildcardSchemata(schema));
+      }
+
+      Results.Add(new Result(WildcardsResultName, new ItemArray<IntArray>(wildcards)));
+
+      return base.Apply();
+    }
+
+    private IList<IntArray> GenerateWildcardSchemata(IntArray schema) {
+      string formatString = "{0:d" + schema.Length + "}";
+      var combs = new List<bool[]>();
+      string comb = string.Empty;
+
+      // create all desired wildcard combinations
+      int i = 0;
+      int wildcardCount = 0; // first wildcard combination contains no wildcards
+      while (wildcardCount < schema.Length) {
+        wildcardCount = (comb = string.Format(formatString, Convert.ToInt32(Convert.ToString(i++, 2)))).Count(x => x == '1');
+        if (wildcardCount > schema.Length / 8 && wildcardCount <= schema.Length / 2) // only include wildcards within certain limits
+          combs.Add(comb.Select(x => x == '1').ToArray()); // '1' becomes true which indicates a wildcard
+      }
+
+      // create all desired wildcard instances
+      var wildcardSchemata = new List<IntArray>();
+      foreach (var c in combs) {
+        wildcardSchemata.Add(new IntArray(schema.Select((x, index) => c[index] ? -1 : x).ToArray())); // -1 is a wildcard in the schema
+      }
+
+      return wildcardSchemata;
+    }
+  }
+}
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 8226)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/HeuristicLab.Analysis.AlgorithmBehavior-3.3.csproj	(revision 8227)
@@ -95,10 +95,12 @@
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Analyzers\BuildingBlockAnalyzer.cs" />
+    <Compile Include="AlgorithmBehaviorHelpers.cs" />
+    <Compile Include="Analyzers\BrokenInheritanceWildcardAnalyzer.cs" />
     <Compile Include="Analyzers\BrokenInteritanceSchemaAnalyzer.cs" />
     <Compile Include="Analyzers\BestIndividualSchemaAnalyzer.cs" />
     <Compile Include="Analyzers\SchemaOccurenceInGenerationsAnalyzer.cs" />
     <Compile Include="Analyzers\SchemaQualityAnalyzer.cs" />
-    <Compile Include="Analyzers\SchemaAnalyzer.cs" />
+    <Compile Include="Creators\SchemataCreator.cs" />
+    <Compile Include="Creators\WildcardsCreator.cs" />
     <Compile Include="Analyzers\GenealogyAnalyzer.cs" />
     <Compile Include="GenealogyGraph.cs" />
@@ -106,4 +108,5 @@
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SchemaEqualityComparer.cs" />
   </ItemGroup>
   <ItemGroup />
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/SchemaEqualityComparer.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/SchemaEqualityComparer.cs	(revision 8227)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior/3.3/SchemaEqualityComparer.cs	(revision 8227)
@@ -0,0 +1,45 @@
+﻿#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 HeuristicLab.Data;
+
+namespace HeuristicLab.Analysis.AlgorithmBehavior {
+  public class SchemaEqualityComparer : EqualityComparer<IntArray> {
+    public override bool Equals(IntArray x, IntArray y) {
+      if (object.ReferenceEquals(x, y)) return true;
+      if (x == null || y == null || x.Length != y.Length) return false;
+      bool match = true;
+      for (int i = 0; i < x.Length && match; i++) // check normal tour
+        if (x[i] != y[i]) match = false;
+      if (!match) {
+        match = true;
+        for (int i = x.Length - 1; i >= 0 && match; i--) // check inverse tour
+          if (x[i] != y[i]) match = false;
+      }
+      return match;
+    }
+
+    public override int GetHashCode(IntArray obj) {
+      return 0; // return the same hash code for each object, otherwise Equals will not be called
+    }
+  }
+}
