Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/MultiSymbolicDataAnalysisExpressionCrossover.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/MultiSymbolicDataAnalysisExpressionCrossover.cs	(revision 9421)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/MultiSymbolicDataAnalysisExpressionCrossover.cs	(revision 9423)
@@ -86,6 +86,6 @@
       get { return (IValueLookupParameter<T>)Parameters[ProblemDataParameterName]; }
     }
-    public ValueParameter<ISymbolicExpressionTreeNodeComparer> SymbolicExpressionTreeNodeComparerParameter {
-      get { return (ValueParameter<ISymbolicExpressionTreeNodeComparer>)Parameters[SymbolicExpressionTreeNodeComparerParameterName]; }
+    public ValueParameter<ISymbolicExpressionTreeNodeSimilarityComparer> SymbolicExpressionTreeNodeComparerParameter {
+      get { return (ValueParameter<ISymbolicExpressionTreeNodeSimilarityComparer>)Parameters[SymbolicExpressionTreeNodeComparerParameterName]; }
     }
     #endregion
@@ -112,5 +112,5 @@
       Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(ParentsParameterName, "The parent symbolic expression trees which should be crossed."));
       Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(ChildParameterName, "The child symbolic expression tree resulting from the crossover."));
-      Parameters.Add(new ValueParameter<ISymbolicExpressionTreeNodeComparer>(SymbolicExpressionTreeNodeComparerParameterName, SymbolicExpressionTreeNodeComparerParameterDescription));
+      Parameters.Add(new ValueParameter<ISymbolicExpressionTreeNodeSimilarityComparer>(SymbolicExpressionTreeNodeComparerParameterName, SymbolicExpressionTreeNodeComparerParameterDescription));
 
       EvaluatorParameter.Hidden = true;
@@ -185,5 +185,5 @@
         op.EvaluatorParameter.ActualName = EvaluatorParameter.Name;
       }
-      var comparers = ApplicationManager.Manager.GetInstances<ISymbolicExpressionTreeNodeComparer>();
+      var comparers = ApplicationManager.Manager.GetInstances<ISymbolicExpressionTreeNodeSimilarityComparer>();
       foreach (var op in Operators.OfType<ITracingSymbolicExpressionTreeOperator>()) {
         op.SymbolicExpressionTreeNodeComparerParameter.ActualValue = comparers.First();
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 9421)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 9423)
@@ -41,5 +41,5 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
-    <OutputPath>..\..\..\..\Trunk\sources\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -58,5 +58,5 @@
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
     <DebugSymbols>true</DebugSymbols>
-    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <DebugType>full</DebugType>
@@ -76,5 +76,5 @@
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
     <DebugSymbols>true</DebugSymbols>
-    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <DebugType>full</DebugType>
@@ -93,6 +93,7 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\bin\ALGLIB-3.6.0.dll</HintPath>
+    <Reference Include="ALGLIB-3.7.0, Version=3.7.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\Trunk\sources\bin\ALGLIB-3.7.0.dll</HintPath>
       <Private>False</Private>
     </Reference>
@@ -100,56 +101,70 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <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">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <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">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Parameters-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <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">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="System" />
@@ -304,4 +319,5 @@
       <Project>{06d4a186-9319-48a0-bade-a2058d462eea}</Project>
       <Name>HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4</Name>
+      <Private>False</Private>
     </ProjectReference>
   </ItemGroup>
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame	(revision 9421)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame	(revision 9423)
@@ -28,5 +28,5 @@
   [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic","Provides base classes for symbolic data analysis tasks.", "3.4.3.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.dll", PluginFileType.Assembly)]
-  [PluginDependency("HeuristicLab.ALGLIB", "3.6.0")]
+  [PluginDependency("HeuristicLab.ALGLIB", "3.7.0")]
   [PluginDependency("HeuristicLab.Analysis", "3.3")]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeMatching.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeMatching.cs	(revision 9421)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeMatching.cs	(revision 9423)
@@ -12,5 +12,5 @@
   [Item("SymbolicExpressionTreeNodeSimilarityComparer", "A comparison operator that checks node equality based on different similarity measures.")]
   [StorableClass]
-  public class SymbolicExpressionTreeNodeSimilarityComparer : Item, ISymbolicExpressionTreeNodeComparer {
+  public class SymbolicExpressionTreeNodeSimilarityComparer : Item, ISymbolicExpressionTreeNodeSimilarityComparer {
     [StorableConstructor]
     private SymbolicExpressionTreeNodeSimilarityComparer(bool deserializing) : base(deserializing) { }
@@ -98,5 +98,5 @@
   // - A function node is "greater" than a terminal node
   // - A variable terminal is "greater" than a constant terminal
-  public class SymbolicExpressionTreeNodeComparer : IComparer<ISymbolicExpressionTreeNode> {
+  public class SymbolicExpressionTreeNodeComparer : ISymbolicExpressionTreeNodeComparer {
     public int Compare(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
       if (!(a is SymbolicExpressionTreeTerminalNode)) {
@@ -208,8 +208,8 @@
   private double[,] matrix;
 
-  public SymbolicExpressionTreeNodeSimilarityComparer comparer;
+  public SymbolicExpressionTreeNodeSimilarityComparer SimilarityComparer { get; set; }
 
   public List<ISymbolicExpressionTreeNode> Calculate(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2) {
-    if (comparer == null) throw new Exception("Comparer cannot be null.");
+    if (SimilarityComparer == null) throw new Exception("Comparer cannot be null.");
 
     x = n1.IterateNodesPrefix().ToArray();
@@ -228,5 +228,5 @@
         if (i == 0 || j == 0) {
           matrix[i, j] = 0;
-        } else if (comparer.Equals(x[i - 1], y[j - 1])) {
+        } else if (SimilarityComparer.Equals(x[i - 1], y[j - 1])) {
           matrix[i, j] = matrix[i - 1, j - 1] + 1;
         } else {
@@ -241,5 +241,5 @@
   private void recon(int i, int j) {
     if (i == 0 || j == 0) return;
-    if (comparer.Equals(x[i - 1], y[j - 1])) {
+    if (SimilarityComparer.Equals(x[i - 1], y[j - 1])) {
       recon(i - 1, j - 1);
       maxCommonSubseq.Add(x[i - 1]);
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimilarity.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimilarity.cs	(revision 9421)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimilarity.cs	(revision 9423)
@@ -20,6 +20,6 @@
 #endregion
 
-
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Common;
@@ -69,4 +69,8 @@
     public SymbolicExpressionTreeNodeSimilarityComparer SimilarityComparer { get; set; }
 
+    public Dictionary<ISymbolicExpressionTree, SymbolicDataAnalysisExpressionTreeSimilarity.GeneticItem[]> GeneticItems;
+
+    public int MaximumTreeDepth { get; set; }
+
     protected SymbolicDataAnalysisExpressionTreeSimilarityCalculator(SymbolicDataAnalysisExpressionTreeSimilarityCalculator original, Cloner cloner) : base(original, cloner) { }
     public override IDeepCloneable Clone(Cloner cloner) { return new SymbolicDataAnalysisExpressionTreeSimilarityCalculator(this, cloner); }
@@ -87,14 +91,20 @@
       var trees = SymbolicExpressionTreeParameter.ActualValue;
 
-      bool found = false;
       double similarity = 0.0;
       var current = CurrentSymbolicExpressionTree;
 
+      bool found = false;
       foreach (var tree in trees) {
-        if (tree == current) { found = true; }
-        if (!found) continue;
-
-        similarity += SymbolicDataAnalysisExpressionTreeSimilarity.MaxCommonSubtreeSimilarity(current, tree, SimilarityComparer);
-      }
+        if (tree == current) {
+          found = true;
+          continue;
+        }
+
+        if (found) {
+          similarity += SymbolicDataAnalysisExpressionTreeSimilarity.MaxCommonSubtreeSimilarity(current, tree, SimilarityComparer);
+          //          similarity += SymbolicDataAnalysisExpressionTreeSimilarity.GeneticItemSimilarity(GeneticItems[current], GeneticItems[tree], MaximumTreeDepth);
+        }
+      }
+
       lock (SimilarityParameter.ActualValue) {
         SimilarityParameter.ActualValue.Value += similarity;
@@ -104,20 +114,17 @@
   }
 
-
-
   public static class SymbolicDataAnalysisExpressionTreeSimilarity {
-    /// <summary>
-    /// Returns a similarity value based on the size of the maximum common subtree according to the given equality comparison.
-    /// </summary>
-    /// <param name="a"></param>
-    /// <param name="b"></param>
-    /// <param name="comparer"></param>
-    /// <returns>Similarity degree between the two trees, scaled between [0,1], where 1 = similar, 0 = non-similar</returns>
+    private static double CalculateSimilarity(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b, SymbolicExpressionTreeNodeSimilarityComparer comp) {
+      return 2.0 * SymbolicExpressionTreeMatching.Match(a, b, comp) / (a.GetLength() + b.GetLength());
+    }
+
     public static double MaxCommonSubtreeSimilarity(ISymbolicExpressionTree a, ISymbolicExpressionTree b, SymbolicExpressionTreeNodeSimilarityComparer comparer) {
       double max = 0;
-      foreach (var aa in a.Root.GetSubtree(0).GetSubtree(0).IterateNodesBreadth()) {
+      var rootA = a.Root.GetSubtree(0).GetSubtree(0);
+      var rootB = b.Root.GetSubtree(0).GetSubtree(0);
+      foreach (var aa in rootA.IterateNodesBreadth()) {
         int lenA = aa.GetLength();
         if (lenA <= max) continue;
-        foreach (var bb in b.Root.GetSubtree(0).GetSubtree(0).IterateNodesBreadth()) {
+        foreach (var bb in rootB.IterateNodesBreadth()) {
           int lenB = bb.GetLength();
           if (lenB <= max) continue;
@@ -126,33 +133,171 @@
         }
       }
-      return max / Math.Max(a.Length, b.Length);
-    }
-
-    private static double CalculateSimilarity(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b, SymbolicExpressionTreeNodeSimilarityComparer comp) {
-      return (double)SymbolicExpressionTreeMatching.Match(a, b, comp) / Math.Max(a.GetLength(), b.GetLength());
-    }
-
-    public static double CalculateCompoundSimilarity(ISymbolicExpressionTree a, ISymbolicExpressionTree b, SymbolicExpressionTreeNodeSimilarityComparer comparer) {
+      return 2.0 * max / (rootA.GetLength() + rootB.GetLength());
+    }
+
+    public static double GeneticItemSimilarity(ISymbolicExpressionTree a, ISymbolicExpressionTree b, int maximumTreeHeight, bool preventMultipleContribution = true) {
+      const int minLevelDelta = 1;
+      const int maxLevelDelta = 4;
+
+      var itemsA = a.GetGeneticItems(minLevelDelta, maxLevelDelta).ToArray();
+      var itemsB = b.GetGeneticItems(minLevelDelta, maxLevelDelta).ToArray();
+
+      return GeneticItemSimilarity(itemsA, itemsB, maximumTreeHeight);
+    }
+
+    public static double GeneticItemSimilarity(GeneticItem[] itemsA, GeneticItem[] itemsB, int maximumTreeHeight, bool preventMultipleContribution = true) {
+      double similarity = 0.0;
+      if (itemsA.Length == 0 || itemsB.Length == 0) return similarity;
+
+      var flagsB = new bool[itemsB.Length];
+
+      for (int i = 0; i != itemsA.Length; ++i) {
+        double simMax = 0.0;
+        int index = -1;
+        for (int j = 0; j != itemsB.Length; ++j) {
+          if (flagsB[j]) continue;
+          double sim = StructuralSimilarity(itemsA[i], itemsB[j], maximumTreeHeight);
+          if (sim > simMax) {
+            simMax = sim;
+            index = j;
+          }
+          if (preventMultipleContribution && index > -1) {
+            flagsB[index] = true;
+          }
+        }
+        similarity += simMax;
+      }
+      return similarity / itemsA.Length;
+    }
+
+    public static double AdditiveSimilarity(ISymbolicExpressionTree a, ISymbolicExpressionTree b, SymbolicExpressionTreeNodeSimilarityComparer comparer) {
       var nA = a.Root.GetSubtree(0).GetSubtree(0);
       var nB = b.Root.GetSubtree(0).GetSubtree(0);
 
-      var itemsA = nA.IterateNodesBreadth().Where(n => n.SubtreeCount > 0).Select(n => new MatchItem { Node = n, Matched = false }).ToArray();
-      var itemsB = nB.IterateNodesBreadth().Where(n => n.SubtreeCount > 0).Select(n => new MatchItem { Node = n, Matched = false }).ToArray();
-
-
-      double similaritySum = 0;
-
-      foreach (var ia in itemsA) {
-        foreach (var ib in itemsB) {
-          similaritySum += CalculateSimilarity(ia.Node, ib.Node, comparer);
-        }
-      }
-      return similaritySum / (itemsA.Length * itemsB.Length);
-    }
-  }
-
-  class MatchItem {
-    public ISymbolicExpressionTreeNode Node;
-    public bool Matched;
+      var nodesA = nA.IterateNodesBreadth().ToArray();
+      var nodesB = nB.IterateNodesBreadth().ToArray();
+
+      var similarities = nodesA.SelectMany(ia => nodesB, (ia, ib) => CalculateSimilarity(ia, ib, comparer)).Where(s => !s.IsAlmost(0.0)).ToList();
+
+      double average = similarities.Count > 0 ? similarities.Average() : 0;
+      if (average > 1.0) throw new Exception("Similarity average should be less than 1.0");
+      if (average < 0.0) throw new Exception("Similarity average should be greater than 0.0");
+      return average;
+    }
+
+    private static double StructuralSimilarity(GeneticItem g1, GeneticItem g2, int heightMax) {
+      if (!(SameType(g1.Ascendant, g2.Ascendant) && SameType(g1.Descendant, g2.Descendant))) return 0.0;
+
+      double s1 = 1.0 - Math.Abs(g1.LevelDelta - g2.LevelDelta) / heightMax;
+      double s2 = g1.Index == g2.Index ? 1.0 : 0.0;
+      double s3 = g1.ParamA.Variant.Name.Equals(g2.ParamA.Variant.Name) ? 1.0 : 0.0;
+      double s4 = g1.ParamB.Variant.Name.Equals(g2.ParamB.Variant.Name) ? 1.0 : 0.0;
+
+      double deltaCa = Math.Abs(g1.ParamA.Coeff - g2.ParamA.Coeff);
+      double deltaCb = Math.Abs(g1.ParamB.Coeff - g2.ParamB.Coeff);
+      double s5 = 0.0;
+      double s6 = 0.0;
+      // no time offsets so we hardcode s7 = s8 = 0.0
+      double s7 = 0.0;
+      double s8 = 0.0;
+      // variable indexes
+      double s9 = 0.0;
+      double s10 = 0.0;
+
+      // same type with g2.Ascendant so we only do one check
+      if (g1.Ascendant is VariableTreeNode) {
+        s5 = deltaCa / (((Variable)g1.Ascendant.Symbol).WeightManipulatorSigma * 4);
+        s9 = g1.ParamA.VariableIndex.Equals(g2.ParamA.VariableIndex) ? 1.0 : 0.0;
+      }
+      if (g1.Descendant is VariableTreeNode) {
+        s6 = deltaCb / (((Variable)g1.Descendant.Symbol).WeightManipulatorSigma * 4);
+        s10 = g1.ParamB.VariableIndex.Equals(g2.ParamB.VariableIndex) ? 1.0 : 0.0;
+      }
+
+      double similarity = 1.0;
+
+      double[] constributors = new double[10] { s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 }; // s1...s10
+      double[] coefficients = new double[10] { 0.8, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2 }; // c1...c10
+
+      for (int i = 0; i != 10; ++i) {
+        similarity *= (1 - (1 - constributors[i]) * coefficients[i]);
+      }
+      return double.IsNaN(similarity) ? 0 : similarity;
+    }
+
+    // genetic items for computing tree similarity (S. Winkler)
+    public class GeneticItem {
+      public ISymbolicExpressionTreeNode Ascendant;
+      public ISymbolicExpressionTreeNode Descendant;
+      public int LevelDelta;
+      public int Index;
+      public double[] Coefficients; // c_i = 0.2, i=1,...,10, d_1 = 0.8
+      // parameters for the Ascendant and Descendant
+      public GeneticItemParameters ParamA;
+      public GeneticItemParameters ParamB;
+    }
+
+    public class GeneticItemParameters {
+      public Symbol Variant; // the variant of functions
+      public double Coeff; // the coefficient of terminals
+      public int TimeOffset; // the time offset of terminals
+      public int VariableIndex; // the variable index (of terminals)
+    }
+    // get genetic items
+    public static List<GeneticItem> GetGeneticItems(this ISymbolicExpressionTree tree, int minLevelDelta, int maxLevelDelta) {
+      return GetGeneticItems(tree.Root.GetSubtree(0).GetSubtree(0), minLevelDelta, maxLevelDelta).ToList();
+    }
+
+    private static double Coefficient(this ISymbolicExpressionTreeNode node) {
+      var variable = node as VariableTreeNode;
+      if (variable != null)
+        return variable.Weight;
+      var constant = node as ConstantTreeNode;
+      if (constant != null)
+        return constant.Value;
+      //      return double.NaN;
+      return 0.0;
+    }
+
+    private static int VariableIndex(this ISymbolicExpressionTreeNode node) {
+      var variable = node as VariableTreeNode;
+      if (variable != null)
+        return variable.Symbol.AllVariableNames.ToList().IndexOf(variable.VariableName);
+      return -1;
+    }
+
+    private static IEnumerable<GeneticItem> GetGeneticItems(ISymbolicExpressionTreeNode node, int minimumLevelDelta, int maximumLevelDelta) {
+      var descendants = node.IterateNodesBreadth().Skip(1).ToArray();
+      for (int i = 0; i != descendants.Length; ++i) {
+        var descendant = descendants[i];
+        var levelDelta = node.GetBranchLevel(descendant);
+        if (!(minimumLevelDelta <= levelDelta && levelDelta <= maximumLevelDelta)) continue;
+        var p = descendant;
+        while (p.Parent != node && p.Parent != null)
+          p = p.Parent;
+        if (p.Parent == null) throw new Exception("The child is not a descendant of node");
+        var geneticItem = new GeneticItem {
+          Ascendant = node, Descendant = descendant, LevelDelta = levelDelta, Index = node.IndexOfSubtree(p),
+          ParamA = new GeneticItemParameters {
+            Coeff = node.Coefficient(), TimeOffset = 0, VariableIndex = node.VariableIndex(), Variant = (Symbol)node.Symbol
+          },
+          ParamB = new GeneticItemParameters {
+            Coeff = descendant.Coefficient(), TimeOffset = 0, VariableIndex = descendant.VariableIndex(), Variant = (Symbol)descendant.Symbol
+          }
+        };
+        yield return geneticItem;
+      }
+    }
+
+    // returns true if both nodes are variables, or both are constants, or both are functions
+    private static bool SameType(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
+      if (a is VariableTreeNode) {
+        return b is VariableTreeNode;
+      }
+      if (a is ConstantTreeNode) {
+        return b is ConstantTreeNode;
+      }
+      return true;
+    }
   }
 }
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs	(revision 9421)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs	(revision 9423)
@@ -350,5 +350,5 @@
         op.EvaluatorParameter.ActualName = EvaluatorParameter.Name;
       }
-      var comparers = ApplicationManager.Manager.GetInstances<ISymbolicExpressionTreeNodeComparer>().ToList();
+      var comparers = ApplicationManager.Manager.GetInstances<ISymbolicExpressionTreeNodeSimilarityComparer>().ToList();
       if (comparers.Count > 0)
         foreach (var op in operators.OfType<ITracingSymbolicExpressionTreeOperator>()) {
