Index: /trunk/sources/HeuristicLab.StructureIdentification/TreeGardener.cs
===================================================================
--- /trunk/sources/HeuristicLab.StructureIdentification/TreeGardener.cs	(revision 181)
+++ /trunk/sources/HeuristicLab.StructureIdentification/TreeGardener.cs	(revision 182)
@@ -138,5 +138,5 @@
       IFunction[] possibleFunctions = allowedFunctions.Where(f => ((IntData)f.GetVariable(GPOperatorLibrary.MIN_TREE_HEIGHT).Value).Data <= treeHeight &&
         ((IntData)f.GetVariable(GPOperatorLibrary.MIN_TREE_SIZE).Value).Data <= treeSize).ToArray();
-      IFunction selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)];
+      IFunction selectedFunction = RandomSelect(possibleFunctions);
 
       // build the tree 
@@ -375,10 +375,10 @@
     private IFunctionTree CreateRandomRoot(int maxTreeSize, int maxTreeHeight) {
       if(maxTreeHeight == 1 || maxTreeSize == 1) {
-        IFunction selectedTerminal = terminals[random.Next(terminals.Count())];
+        IFunction selectedTerminal = RandomSelect(terminals);
         return new FunctionTree(selectedTerminal);
       } else {
         IFunction[] possibleFunctions = allFunctions.Where(f => GetMinimalTreeHeight(f) <= maxTreeHeight &&
           GetMinimalTreeSize(f) <= maxTreeSize).ToArray();
-        IFunction selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)];
+        IFunction selectedFunction = RandomSelect(possibleFunctions);
         return new FunctionTree(selectedFunction);
       }
@@ -399,5 +399,5 @@
           IFunction[] possibleFunctions = GetAllowedSubFunctions(parent.Function, i).Where(f => GetMinimalTreeHeight(f) <= maxTreeHeight &&
             GetMinimalTreeSize(f) <= maxSubTreeSize).ToArray();
-          IFunction selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)];
+          IFunction selectedFunction = RandomSelect(possibleFunctions);
           FunctionTree newSubTree = new FunctionTree(selectedFunction);
           MakeUnbalancedTree(newSubTree, maxSubTreeSize - 1, maxTreeHeight - 1);
@@ -422,6 +422,6 @@
         for(int i = 0; i < actualArity; i++) {
           if(maxTreeHeight == 1 || maxSubTreeSize == 1) {
-            IFunction[] possibleTerminals = GetAllowedSubFunctions(parent.Function, i).Where(IsTerminal(f)).ToArray();
-            IFunction selectedTerminal = possibleTerminals[random.Next(possibleTerminals.Length)];
+            IFunction[] possibleTerminals = GetAllowedSubFunctions(parent.Function, i).Where(f => IsTerminal(f)).ToArray();
+            IFunction selectedTerminal = RandomSelect(possibleTerminals);
             IFunctionTree newTree = new FunctionTree(selectedTerminal);
             parent.InsertSubTree(i, newTree);
@@ -431,5 +431,5 @@
               GetMinimalTreeSize(f) <= maxSubTreeSize &&
               !IsTerminal(f)).ToArray();
-            IFunction selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)];
+            IFunction selectedFunction = RandomSelect(possibleFunctions);
             FunctionTree newTree = new FunctionTree(selectedFunction);
             parent.InsertSubTree(i, newTree);
@@ -465,4 +465,23 @@
     }
 
+    private IFunction RandomSelect(IList<IFunction> functionSet) {
+      double[] accumulatedTickets = new double[functionSet.Count];
+      double ticketAccumulator = 0;
+      int i = 0;
+      // precalculate the slot-sizes
+      foreach(IFunction function in functionSet) {
+        ticketAccumulator += ((DoubleData)function.GetVariable(GPOperatorLibrary.TICKETS).Value).Data;
+        accumulatedTickets[i] = ticketAccumulator;
+        i++;
+      }
+      // throw ball
+      double r = random.NextDouble() * ticketAccumulator;
+      // find the slot that has been hit
+      for(i = 0; i < accumulatedTickets.Length; i++) {
+        if(r < accumulatedTickets[i]) return functionSet[i];
+      }
+      // sanity check
+      throw new InvalidProgramException(); // should never happen
+    }
 
     #endregion
