Index: branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisInternalDiversityAnalyzer.cs
===================================================================
--- branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisInternalDiversityAnalyzer.cs	(revision 11221)
+++ branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisInternalDiversityAnalyzer.cs	(revision 11221)
@@ -0,0 +1,111 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Analyzers {
+  [StorableClass]
+  [Item("SymbolicDataAnalysisInternalDiversityAnalyzer", "An analyzer that determines the average diversity of symbolic expression trees.")]
+  public class SymbolicDataAnalysisInternalDiversityAnalyzer : SingleSuccessorOperator, ISymbolicDataAnalysisAnalyzer {
+    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
+    private const string ResultCollectionParameterName = "Results";
+    private readonly BottomUpSimilarityCalculator busCalculator;
+
+    public SymbolicDataAnalysisInternalDiversityAnalyzer() {
+      busCalculator = new BottomUpSimilarityCalculator();
+
+      Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName));
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultCollectionParameterName));
+    }
+
+    protected SymbolicDataAnalysisInternalDiversityAnalyzer(SymbolicDataAnalysisInternalDiversityAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicDataAnalysisInternalDiversityAnalyzer(this, cloner);
+    }
+
+    public IScopeTreeLookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (IScopeTreeLookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
+    }
+    public ILookupParameter<ResultCollection> ResultCollectionParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters[ResultCollectionParameterName]; }
+    }
+
+    public bool EnabledByDefault { get { return true; } }
+
+    public override IOperation Apply() {
+
+      var results = ResultCollectionParameter.ActualValue;
+
+      DataTable table;
+      if (!results.ContainsKey("Avg. Internal Diversity")) {
+        table = new DataTable("Internal Diversity") { VisualProperties = { YAxisTitle = "Internal Diversity" } };
+        table.Rows.Add(new DataRow("Avg. Internal Diversity"));
+        results.Add(new Result("Avg. Internal Diversity", table));
+      } else {
+        table = (DataTable)results["Avg. Internal Diversity"].Value;
+      }
+
+      double diversity = 0;
+      var trees = SymbolicExpressionTreeParameter.ActualValue;
+      foreach (var tree in trees) {
+        diversity += CalculateInternalDiversity(tree);
+      }
+
+      table.Rows["Avg. Internal Diversity"].Values.Add(diversity / trees.Length);
+      return base.Apply();
+    }
+
+    private double CalculateInternalDiversity(ISymbolicExpressionTree tree) {
+      var branchPoint = tree.IterateNodesPrefix().FirstOrDefault(x => x.SubtreeCount == 2);
+      if (branchPoint == null)
+        return 1;
+
+      var s1 = branchPoint.GetSubtree(0);
+      var s2 = branchPoint.GetSubtree(1);
+
+      // set parents to null because otherwise the bottom-up calculator will throw an exception
+      var p1 = s1.Parent;
+      s1.Parent = null;
+      var p2 = s2.Parent;
+      s2.Parent = null;
+
+      var m = busCalculator.ComputeBottomUpMapping(s1, s2);
+      var diversity = 1 - 2.0 * m.Count / (s1.GetLength() + s2.GetLength());
+
+      // restore parents
+      s1.Parent = p1;
+      s2.Parent = p2;
+
+      return diversity;
+    }
+  }
+}
Index: branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 11220)
+++ branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 11221)
@@ -197,4 +197,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Analyzers\SymbolicDataAnalysisInternalDiversityAnalyzer.cs" />
     <Compile Include="Analyzers\SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs" />
     <Compile Include="Analyzers\SymbolicDataAnalysisSingleObjectiveValidationParetoBestSolutionAnalyzer.cs" />
Index: branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SimilarityCalculators/BottomUpSimilarityCalculator.cs
===================================================================
--- branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SimilarityCalculators/BottomUpSimilarityCalculator.cs	(revision 11220)
+++ branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SimilarityCalculators/BottomUpSimilarityCalculator.cs	(revision 11221)
@@ -29,5 +29,5 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic.SimilarityCalculators {
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
   [StorableClass]
   [Item("BottomUpSimilarityCalculator", "A similarity calculator which uses the tree bottom-up distance as a similarity metric.")]
@@ -59,20 +59,19 @@
         return 1;
 
-      var map = ComputeBottomUpMapping(t1, t2);
+      var map = ComputeBottomUpMapping(t1.Root, t2.Root);
       return 2.0 * map.Count / (t1.Length + t2.Length);
     }
 
-
-    public Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> ComputeBottomUpMapping(ISymbolicExpressionTree t1, ISymbolicExpressionTree t2) {
-      var compactedGraph = Compact(t1, t2);
+    public Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> ComputeBottomUpMapping(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2) {
+      var compactedGraph = Compact(n1, n2);
 
       var forwardMap = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); // nodes of t1 => nodes of t2
       var reverseMap = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); // nodes of t2 => nodes of t1
 
-      foreach (var v in t1.IterateNodesBreadth()) {
+      foreach (var v in n1.IterateNodesBreadth()) {
         if (forwardMap.ContainsKey(v)) continue;
         var kv = compactedGraph[v];
         ISymbolicExpressionTreeNode w = null;
-        foreach (var t in t2.IterateNodesBreadth()) {
+        foreach (var t in n2.IterateNodesBreadth()) {
           if (reverseMap.ContainsKey(t) || compactedGraph[t] != kv) continue;
           w = t;
@@ -103,5 +102,5 @@
     /// <param name="t2">The second tree</param>
     /// <returns>The compacted DAG representing the two trees</returns>
-    private Dictionary<ISymbolicExpressionTreeNode, IVertex> Compact(ISymbolicExpressionTree t1, ISymbolicExpressionTree t2) {
+    private Dictionary<ISymbolicExpressionTreeNode, IVertex> Compact(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2) {
       var nodesToVertices = new Dictionary<ISymbolicExpressionTreeNode, IVertex>(); // K
       var labelsToVertices = new Dictionary<string, IVertex>(); // L
@@ -109,5 +108,5 @@
       var vertices = new List<IVertex>(); // G
 
-      var nodes = t1.IterateNodesPostfix().Concat(t2.IterateNodesPostfix()); // the disjoint union F
+      var nodes = n1.IterateNodesPostfix().Concat(n2.IterateNodesPostfix()); // the disjoint union F
       var queue = new Queue<ISymbolicExpressionTreeNode>();
 
Index: branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SimilarityCalculators/MaxCommonSubtreeSimilarityCalculator.cs
===================================================================
--- branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SimilarityCalculators/MaxCommonSubtreeSimilarityCalculator.cs	(revision 11220)
+++ branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SimilarityCalculators/MaxCommonSubtreeSimilarityCalculator.cs	(revision 11221)
@@ -27,5 +27,5 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic.SimilarityCalculators {
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
   [StorableClass]
   [Item("MaxCommonSubtreeSimilarityCalculator", "A similarity calculator based on the size of the maximum common subtree between two trees")]
Index: branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs
===================================================================
--- branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs	(revision 11220)
+++ branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs	(revision 11221)
@@ -34,5 +34,4 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.PluginInfrastructure;
-using HeuristicLab.Problems.DataAnalysis.Symbolic.SimilarityCalculators;
 using HeuristicLab.Problems.Instances;
 
Index: branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Tests/BottomUpSimilarityCalculatorTest.cs
===================================================================
--- branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Tests/BottomUpSimilarityCalculatorTest.cs	(revision 11220)
+++ branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Tests/BottomUpSimilarityCalculatorTest.cs	(revision 11221)
@@ -8,5 +8,4 @@
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
-using HeuristicLab.Problems.DataAnalysis.Symbolic.SimilarityCalculators;
 using HeuristicLab.Random;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -33,4 +32,5 @@
       TestMatchedNodes("(+ 1 2)", "(+ 2 1)", 5);
       TestMatchedNodes("(- 2 1)", "(- 1 2)", 2);
+      TestMatchedNodes("(* (variable 1 X1) (variable 1 X2))", "(* (+ (variable 1 X1) 1) (+ (variable 1 X2) 1))", 2);
 
       TestMatchedNodes("(* (variable 1 X1) (variable 1 X2))", "(* (+ (variable 1 X1) 1) (variable 1 X2))", 2);
@@ -52,5 +52,5 @@
       var t2 = importer.Import(expr2);
 
-      var mapping = busCalculator.ComputeBottomUpMapping(t1, t2);
+      var mapping = busCalculator.ComputeBottomUpMapping(t1.Root, t2.Root);
       var c = mapping.Count;
 
