Index: branches/LinearLinkage/HeuristicLab.Encodings.LinearLinkageEncoding/3.3/Crossovers/GroupCrossover.cs
===================================================================
--- branches/LinearLinkage/HeuristicLab.Encodings.LinearLinkageEncoding/3.3/Crossovers/GroupCrossover.cs	(revision 12286)
+++ branches/LinearLinkage/HeuristicLab.Encodings.LinearLinkageEncoding/3.3/Crossovers/GroupCrossover.cs	(revision 12288)
@@ -22,4 +22,5 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -53,28 +54,15 @@
       for (var i = 0; i < length; i++) {
         if (endNodes.Contains(i)) continue;
-        if (endNodes.Contains(p1[i]) && endNodes.Contains(p2[i])) {
+        var p1End = endNodes.Contains(p1[i]);
+        var p2End = endNodes.Contains(p2[i]);
+        if ((p1End && p2End) || (!p1End && !p2End)) {
           child[i] = random.NextDouble() < 0.5 ? p1[i] : p2[i];
-        } else if (endNodes.Contains(p1[i])) {
+        } else if (p1End) {
           child[i] = p1[i];
-        } else if (endNodes.Contains(p2[i])) {
+        } else {
           child[i] = p2[i];
-        } else {
-          var a = p1[i];
-          var b = p2[i];
-          while (true) {
-            if (endNodes.Contains(p2[a])) {
-              child[i] = p2[a];
-              break;
-            }
-            if (endNodes.Contains(p1[b])) {
-              child[i] = p1[b];
-              break;
-            }
-            var tmp = b;
-            b = p2[a];
-            a = p1[tmp];
-          }
         }
       }
+      child.LinearizeTreeStructures();
       return child;
     }
Index: branches/LinearLinkage/HeuristicLab.Encodings.LinearLinkageEncoding/3.3/Crossovers/LowestIndexFirstCrossover.cs
===================================================================
--- branches/LinearLinkage/HeuristicLab.Encodings.LinearLinkageEncoding/3.3/Crossovers/LowestIndexFirstCrossover.cs	(revision 12286)
+++ branches/LinearLinkage/HeuristicLab.Encodings.LinearLinkageEncoding/3.3/Crossovers/LowestIndexFirstCrossover.cs	(revision 12288)
@@ -42,18 +42,21 @@
     public static LinearLinkage Apply(IRandom random, ItemArray<LinearLinkage> parents) {
       var len = parents[0].Length;
+      var p = random.Next(parents.Length);
       var child = new LinearLinkage(len);
-      var childGroup = new List<HashSet<int>>();
-      var currentParent = random.Next(parents.Length);
-      var remaining = new HashSet<int>(Enumerable.Range(0, len));
+      var remaining = new SortedSet<int>(Enumerable.Range(0, len));
       do {
-        var i = remaining.Min();
-        var group = new HashSet<int>(parents[currentParent].GetGroupForward(i));
-        group.IntersectWith(remaining);
-        childGroup.Add(group);
-        remaining.ExceptWith(group);
-        currentParent = (currentParent + 1) % parents.Length;
+        var i = remaining.Min;
+        foreach (var g in parents[p].GetGroupForward(i)) {
+          if (!remaining.Contains(g)) continue;
+          child[i] = g;
+          i = g;
+          remaining.Remove(g);
+        }
+        child[i] = i;
+        remaining.Remove(i);
+
+        p = (p + 1) % parents.Length;
       } while (remaining.Count > 0);
 
-      child.SetGroups(childGroup);
       return child;
     }
Index: branches/LinearLinkage/HeuristicLab.Encodings.LinearLinkageEncoding/3.3/Crossovers/LowestIndexMaxCrossover.cs
===================================================================
--- branches/LinearLinkage/HeuristicLab.Encodings.LinearLinkageEncoding/3.3/Crossovers/LowestIndexMaxCrossover.cs	(revision 12286)
+++ branches/LinearLinkage/HeuristicLab.Encodings.LinearLinkageEncoding/3.3/Crossovers/LowestIndexMaxCrossover.cs	(revision 12288)
@@ -45,18 +45,18 @@
       var len = parents[0].Length;
       var child = new LinearLinkage(len);
-      var childGroup = new List<HashSet<int>>();
-      var remaining = new HashSet<int>(Enumerable.Range(0, len));
+      var remaining = new SortedSet<int>(Enumerable.Range(0, len));
       do {
-        var i = remaining.Min();
-        var groups = parents.Select(x => new HashSet<int>(x.GetGroupForward(i))).ToList();
-        for (var k = 0; k < groups.Count; k++)
-          groups[k].IntersectWith(remaining);
-
-        var maxGroup = groups.Select((v, idx) => Tuple.Create(idx, v)).MaxItems(x => x.Item2.Count).SampleRandom(random).Item1;
-        childGroup.Add(groups[maxGroup]);
-        remaining.ExceptWith(groups[maxGroup]);
+        var groups = parents.Select(x => x.GetGroupForward(remaining.Min).Where(y => remaining.Contains(y)).ToList()).ToList();
+        var max = groups.Select((v, idx) => Tuple.Create(idx, v.Count)).MaxItems(x => x.Item2).SampleRandom(random).Item1;
+        var i = groups[max][0];
+        for (var k = 1; k < groups[max].Count; k++) {
+          child[i] = groups[max][k];
+          remaining.Remove(i);
+          i = child[i];
+        }
+        child[i] = i;
+        remaining.Remove(i);
       } while (remaining.Count > 0);
 
-      child.SetGroups(childGroup);
       return child;
     }
