Index: branches/DataAnalysis.PopulationDiversityAnalysis/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/FineGrainedStructuralPopulationDiversityAnalyzer.cs
===================================================================
--- branches/DataAnalysis.PopulationDiversityAnalysis/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/FineGrainedStructuralPopulationDiversityAnalyzer.cs	(revision 4948)
+++ branches/DataAnalysis.PopulationDiversityAnalysis/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/FineGrainedStructuralPopulationDiversityAnalyzer.cs	(revision 4949)
@@ -161,4 +161,5 @@
 
     protected override double[,] CalculateSimilarities(SymbolicExpressionTree[] solutions) {
+      // collect information stored int the problem's parameters
       double variableWeightSigma = 0;
       double constantMinimumValue = 0;
@@ -187,36 +188,47 @@
       }
       variableNames.Add(ProblemData.TargetVariable.Value);
+      // collect genetic information item lists and store them also in dictionaries
       IList<GeneticInformationItem>[] geneticInformationItemsLists = new List<GeneticInformationItem>[n];
+      IDictionary<string, IList<GeneticInformationItem>>[] geneticInformationItemsListsDictionaries = new IDictionary<string, IList<GeneticInformationItem>>[n];
       for (int i = 0; i < n; i++) {
         geneticInformationItemsLists[i] = GeneticInformationItem.getGeneticInformationItems(solutions[i].Root, variableNames, MinimumLevelDelta, MaximumLevelDelta);
-      }
-      double[,] result = new double[n, n];
+        geneticInformationItemsListsDictionaries[i] = GeneticInformationItem.GetDictionary(geneticInformationItemsLists[i]);
+      }
+      // calculate solution similarities
+      double[,] similarities = new double[n, n];
       for (int i = 0; i < n; i++) {
         for (int j = 0; j < n; j++) {
           if (i == j)
-            result[i, j] = 1;
+            similarities[i, j] = 1;
           else {
-            IList<GeneticInformationItem> solution1GeneticItems = GeneticInformationItem.CopyList(geneticInformationItemsLists[i]);
-            IList<GeneticInformationItem> solution2GeneticItems = GeneticInformationItem.CopyList(geneticInformationItemsLists[j]);
+            IList<GeneticInformationItem> solution1GeneticItems = geneticInformationItemsLists[i];
+            IDictionary<string, IList<GeneticInformationItem>> solution2GeneticItemsDictionary = GeneticInformationItem.CopyDictionary(geneticInformationItemsListsDictionaries[j]);
             double similarity = 0;
             for (int k = 0; k < solution1GeneticItems.Count; k++) {
-              double bestPendantSimilarity;
-              GeneticInformationItem bestPendant = GeneticInformationItem.FindBestPendant(solution1GeneticItems[k], solution2GeneticItems,
-                constantMinimumValue, constantMaximumValue, variableWeightSigma,
-                MaximumExpressionDepth, minimumTimeOffset, maximumTimeOffset,
-                LevelDifferenceCoefficient, AncestorIndexCoefficient, ConstantValueCoefficient, VariableWeightCoefficient,
-                TimeOffsetCoefficientCoefficient, VariableIndexCoefficient, AdditiveSimilarityCalculation,
-                out bestPendantSimilarity);
+              double bestPendantSimilarity = 0;
+              GeneticInformationItem item = solution1GeneticItems[k];
+              GeneticInformationItem bestPendant = null;
+              IList<GeneticInformationItem> geneticInformationItemsList = null;
+              string key = GeneticInformationItem.GetKey(item);
+              if (solution2GeneticItemsDictionary.ContainsKey(key)) {
+                geneticInformationItemsList = solution2GeneticItemsDictionary[GeneticInformationItem.GetKey(item)];
+                bestPendant = GeneticInformationItem.FindBestPendant(item, geneticInformationItemsList,
+                  constantMinimumValue, constantMaximumValue, variableWeightSigma,
+                  MaximumExpressionDepth, minimumTimeOffset, maximumTimeOffset,
+                  LevelDifferenceCoefficient, AncestorIndexCoefficient, ConstantValueCoefficient, VariableWeightCoefficient,
+                  TimeOffsetCoefficientCoefficient, VariableIndexCoefficient, AdditiveSimilarityCalculation,
+                  out bestPendantSimilarity);
+              }
               if (bestPendant != null) {
                 similarity += bestPendantSimilarity;
                 if (PreventMultipleComparisonContribution)
-                  solution2GeneticItems.Remove(bestPendant);
+                  geneticInformationItemsList.Remove(bestPendant);
               }
             }
-            result[i, j] = similarity / solution1GeneticItems.Count;
+            similarities[i, j] = similarity / solution1GeneticItems.Count;
           }
         }
       }
-      return result;
+      return similarities;
     }
 
@@ -278,4 +290,27 @@
         list.AddRange(GeneticInformationItemsList);
         return list;
+      }
+
+      public static string GetKey(GeneticInformationItem item) {
+        return item.AncestorDefinition.Name.ToString() + "," + item.DescendantDefinition.Name.ToString();
+      }
+
+      public static IDictionary<string, IList<GeneticInformationItem>> GetDictionary(IList<GeneticInformationItem> GeneticInformationItemsList) {
+        IDictionary<string, IList<GeneticInformationItem>> dictionary = new Dictionary<string, IList<GeneticInformationItem>>();
+        foreach (GeneticInformationItem item in GeneticInformationItemsList) {
+          string key = GetKey(item);
+          if (!dictionary.ContainsKey(key))
+            dictionary.Add(key, new List<GeneticInformationItem>());
+          dictionary[key].Add(item);
+        }
+        return dictionary;
+      }
+
+      public static IDictionary<string, IList<GeneticInformationItem>> CopyDictionary(IDictionary<string, IList<GeneticInformationItem>> Dictionary) {
+        IDictionary<string, IList<GeneticInformationItem>> copy = new Dictionary<string, IList<GeneticInformationItem>>();
+        foreach (KeyValuePair<string, IList<GeneticInformationItem>> pair in Dictionary) {
+          copy.Add(pair.Key, CopyList(pair.Value));
+        }
+        return copy;
       }
 
