Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SimilarityCalculators/BottomUpSimilarityCalculator.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SimilarityCalculators/BottomUpSimilarityCalculator.cs	(revision 11482)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SimilarityCalculators/BottomUpSimilarityCalculator.cs	(revision 11488)
@@ -23,4 +23,5 @@
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.Globalization;
 using System.Linq;
 using HeuristicLab.Common;
@@ -71,4 +72,5 @@
 
     public Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> ComputeBottomUpMapping(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2) {
+      var comparer = new SymbolicExpressionTreeNodeComparer(); // use a node comparer because it's faster than calling node.ToString() (strings are expensive) and comparing strings
       var compactedGraph = Compact(n1, n2);
 
@@ -77,10 +79,12 @@
 
       // visit nodes in order of decreasing height to ensure correct mapping
-      foreach (var v in n1.IterateNodesPrefix().OrderByDescending(x => compactedGraph[x].Depth)) {
+      var nodes1 = n1.IterateNodesPrefix().ToList();
+      var nodes2 = n2.IterateNodesPrefix().ToList();
+      foreach (var v in nodes1) {
         if (forwardMap.ContainsKey(v))
           continue;
         var kv = compactedGraph[v];
         ISymbolicExpressionTreeNode w = null;
-        foreach (var t in n2.IterateNodesPrefix()) {
+        foreach (var t in nodes2) {
           if (reverseMap.ContainsKey(t) || compactedGraph[t] != kv)
             continue;
@@ -92,6 +96,6 @@
         // at this point we know that v and w are isomorphic, however, the mapping cannot be done directly (as in the paper) because the trees are unordered (subtree order might differ)
         // the solution is to sort subtrees by label using IterateBreadthOrdered (this will work because the subtrees are isomorphic!) and simultaneously iterate over the two subtrees
-        var eV = IterateBreadthOrdered(v).GetEnumerator();
-        var eW = IterateBreadthOrdered(w).GetEnumerator();
+        var eV = IterateBreadthOrdered(v, comparer).GetEnumerator();
+        var eW = IterateBreadthOrdered(w, comparer).GetEnumerator();
 
         while (eV.MoveNext() && eW.MoveNext()) {
@@ -148,5 +152,5 @@
           bool sort = commutativeSymbols.Contains(label);
           var nNodes = n.Subtrees.Select(x => nodeMap[x]).ToList();
-          if (sort) nNodes.Sort((a, b) => String.Compare(a.Label, b.Label, StringComparison.Ordinal));
+          if (sort) nNodes.Sort((a, b) => string.CompareOrdinal(a.Label, b.Label));
 
           for (int i = list.Count - 1; i >= 0; --i) {
@@ -159,5 +163,5 @@
             var m = w.SymbolicExpressionTreeNode;
             var mNodes = m.Subtrees.Select(x => nodeMap[x]).ToList();
-            if (sort) mNodes.Sort((a, b) => String.Compare(a.Label, b.Label, StringComparison.Ordinal));
+            if (sort) mNodes.Sort((a, b) => string.CompareOrdinal(a.Label, b.Label));
 
             if (nNodes.SequenceEqual(mNodes)) {
@@ -169,5 +173,5 @@
 
           if (!found) {
-            var w = new GraphNode { SymbolicExpressionTreeNode = n, Label = label, Depth = depth, ChildrenCount = n.SubtreeCount };
+            var w = new GraphNode { SymbolicExpressionTreeNode = n, Label = label, Depth = depth };
             list.Add(w);
             nodeMap[n] = w;
@@ -191,5 +195,5 @@
     }
 
-    private IEnumerable<ISymbolicExpressionTreeNode> IterateBreadthOrdered(ISymbolicExpressionTreeNode node) {
+    private IEnumerable<ISymbolicExpressionTreeNode> IterateBreadthOrdered(ISymbolicExpressionTreeNode node, ISymbolicExpressionTreeNodeComparer comparer) {
       var list = new List<ISymbolicExpressionTreeNode> { node };
       int i = 0;
@@ -197,5 +201,5 @@
         var n = list[i];
         if (n.SubtreeCount > 0) {
-          var subtrees = commutativeSymbols.Contains(node.Symbol.Name) ? n.Subtrees.OrderBy(x => x.ToString(), StringComparer.Ordinal) : n.Subtrees;
+          var subtrees = commutativeSymbols.Contains(node.Symbol.Name) ? n.Subtrees.OrderBy(x => x, comparer) : n.Subtrees;
           list.AddRange(subtrees);
         }
@@ -206,11 +210,15 @@
 
     private string Label(ISymbolicExpressionTreeNode node) {
+      if (node.SubtreeCount > 0)
+        return node.Symbol.Name;
+
       var constant = node as ConstantTreeNode;
-      if (constant != null && !MatchConstantValues)
-        return constant.Symbol.Name;
+      if (constant != null)
+        return MatchConstantValues ? constant.Value.ToString(CultureInfo.InvariantCulture) : constant.Symbol.Name;
       var variable = node as VariableTreeNode;
-      if (variable != null && !MatchVariableWeights) {
-        return variable.VariableName;
-      }
+      if (variable != null) {
+        return MatchVariableWeights ? variable.Weight + variable.VariableName : variable.VariableName;
+      }
+
       return node.ToString();
     }
@@ -220,5 +228,5 @@
       public string Label;
       public int Depth;
-      public int ChildrenCount;
+      public int ChildrenCount { get { return SymbolicExpressionTreeNode.SubtreeCount; } }
     }
   }
