Index: trunk/sources/HeuristicLab.StructureIdentification/HeuristicLab.StructureIdentification.csproj
===================================================================
--- trunk/sources/HeuristicLab.StructureIdentification/HeuristicLab.StructureIdentification.csproj	(revision 285)
+++ trunk/sources/HeuristicLab.StructureIdentification/HeuristicLab.StructureIdentification.csproj	(revision 286)
@@ -48,4 +48,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="ProbabilisticTreeCreator.cs" />
     <Compile Include="Evaluation\CoefficientOfDeterminationEvaluator.cs" />
     <Compile Include="Evaluation\MCCEvaluator.cs" />
Index: trunk/sources/HeuristicLab.StructureIdentification/ProbabilisticTreeCreator.cs
===================================================================
--- trunk/sources/HeuristicLab.StructureIdentification/ProbabilisticTreeCreator.cs	(revision 286)
+++ trunk/sources/HeuristicLab.StructureIdentification/ProbabilisticTreeCreator.cs	(revision 286)
@@ -0,0 +1,76 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using System;
+using HeuristicLab.Random;
+using HeuristicLab.Functions;
+
+namespace HeuristicLab.StructureIdentification {
+  public class ProbabilisticTreeCreator : OperatorBase {
+    public override string Description {
+      get { return @"Generates a new random operator tree."; }
+    }
+
+    public ProbabilisticTreeCreator()
+      : base() {
+      AddVariableInfo(new VariableInfo("Random", "Uniform random number generator", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MinTreeSize", "The minimal allowed size of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("FunctionTree", "The created tree", typeof(IFunctionTree), VariableKind.New | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.New | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.New | VariableKind.Out));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      IRandom random = GetVariableValue<IRandom>("Random", scope, true);
+      GPOperatorLibrary opLibrary = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
+      int minTreeSize = GetVariableValue<IntData>("MinTreeSize", scope, true).Data;
+      int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data;
+      int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
+
+      TreeGardener gardener = new TreeGardener(random, opLibrary);
+
+      int treeSize = random.Next(minTreeSize, maxTreeSize + 1);
+      IFunctionTree root = gardener.PTC2(random, treeSize, maxTreeHeight);
+
+      int actualTreeSize = gardener.GetTreeSize(root);
+      int actualTreeHeight = gardener.GetTreeHeight(root);
+
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), root));
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(actualTreeSize)));
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(actualTreeHeight)));
+
+      if(!gardener.IsValidTree(root)) { throw new InvalidProgramException(); }
+
+      if(actualTreeHeight > maxTreeHeight) {
+        throw new InvalidProgramException();
+      }
+
+      return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(root), scope);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.StructureIdentification/RampedTreeCreator.cs
===================================================================
--- trunk/sources/HeuristicLab.StructureIdentification/RampedTreeCreator.cs	(revision 286)
+++ trunk/sources/HeuristicLab.StructureIdentification/RampedTreeCreator.cs	(revision 286)
@@ -0,0 +1,81 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using System;
+using HeuristicLab.Random;
+using HeuristicLab.Functions;
+
+namespace HeuristicLab.StructureIdentification {
+  public class RampedTreeCreator : OperatorBase {
+    public override string Description {
+      get { return @"Generates a new random operator tree."; }
+    }
+
+    public RampedTreeCreator()
+      : base() {
+      AddVariableInfo(new VariableInfo("Random", "Uniform random number generator", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MinTreeHeight", "The minimal allowed height of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("BalancedTreesRate", "Determines how many trees should be balanced", typeof(DoubleData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("FunctionTree", "The created tree", typeof(IFunctionTree), VariableKind.New | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.New | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.New | VariableKind.Out));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      IRandom random = GetVariableValue<IRandom>("Random", scope, true);
+      GPOperatorLibrary opLibrary = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
+      int minTreeHeight = GetVariableValue<IntData>("MinTreeHeight", scope, true).Data;
+      int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
+      double balancedTreesRate = GetVariableValue<DoubleData>("BalancedTreesRate", scope, true).Data;
+
+      TreeGardener gardener = new TreeGardener(random, opLibrary);
+
+      int treeHeight = random.Next(minTreeHeight, maxTreeHeight + 1);
+      IFunctionTree root;
+      if(random.NextDouble() <= balancedTreesRate) {
+        root = gardener.CreateBalancedRandomTree(Int32.MaxValue, treeHeight);
+      } else {
+        root = gardener.CreateUnbalancedRandomTree(Int32.MaxValue, treeHeight);
+      }
+
+      int actualTreeSize = gardener.GetTreeSize(root);
+      int actualTreeHeight = gardener.GetTreeHeight(root);
+
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), root));
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(actualTreeSize)));
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(actualTreeHeight)));
+
+      if(!gardener.IsValidTree(root)) { throw new InvalidProgramException(); }
+
+      if(actualTreeHeight > maxTreeHeight) {
+        throw new InvalidProgramException();
+      }
+
+      return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(root), scope);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.StructureIdentification/RandomTreeCreator.cs
===================================================================
--- trunk/sources/HeuristicLab.StructureIdentification/RandomTreeCreator.cs	(revision 285)
+++ 	(revision )
@@ -1,81 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 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.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using System;
-using HeuristicLab.Random;
-using HeuristicLab.Functions;
-
-namespace HeuristicLab.StructureIdentification {
-  public class RandomTreeCreator : OperatorBase {
-    public override string Description {
-      get { return @"Generates a new random operator tree."; }
-    }
-
-    public RandomTreeCreator()
-      : base() {
-      AddVariableInfo(new VariableInfo("Random", "Uniform random number generator", typeof(MersenneTwister), VariableKind.In));
-      AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));
-      AddVariableInfo(new VariableInfo("MinTreeHeight", "The minimal allowed height of the tree", typeof(IntData), VariableKind.In));
-      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
-      AddVariableInfo(new VariableInfo("BalancedTreesRate", "Determines how many trees should be balanced", typeof(DoubleData), VariableKind.In));
-      AddVariableInfo(new VariableInfo("FunctionTree", "The created tree", typeof(IFunctionTree), VariableKind.New | VariableKind.Out));
-      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.New | VariableKind.Out));
-      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.New | VariableKind.Out));
-    }
-
-    public override IOperation Apply(IScope scope) {
-      IRandom random = GetVariableValue<IRandom>("Random", scope, true);
-      GPOperatorLibrary opLibrary = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
-      int minTreeHeight = GetVariableValue<IntData>("MinTreeHeight", scope, true).Data;
-      int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
-      double balancedTreesRate = GetVariableValue<DoubleData>("BalancedTreesRate", scope, true).Data;
-
-      TreeGardener gardener = new TreeGardener(random, opLibrary);
-
-      int treeHeight = random.Next(minTreeHeight, maxTreeHeight + 1);
-      IFunctionTree root;
-      if(random.NextDouble() <= balancedTreesRate) {
-        root = gardener.CreateBalancedRandomTree(Int32.MaxValue, treeHeight);
-      } else {
-        root = gardener.CreateUnbalancedRandomTree(Int32.MaxValue, treeHeight);
-      }
-
-      int actualTreeSize = gardener.GetTreeSize(root);
-      int actualTreeHeight = gardener.GetTreeHeight(root);
-
-      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), root));
-      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(actualTreeSize)));
-      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(actualTreeHeight)));
-
-      if(!gardener.IsValidTree(root)) { throw new InvalidProgramException(); }
-
-      if(actualTreeHeight > maxTreeHeight) {
-        throw new InvalidProgramException();
-      }
-
-      return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(root), scope);
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.StructureIdentification/TreeGardener.cs
===================================================================
--- trunk/sources/HeuristicLab.StructureIdentification/TreeGardener.cs	(revision 285)
+++ trunk/sources/HeuristicLab.StructureIdentification/TreeGardener.cs	(revision 286)
@@ -97,4 +97,65 @@
       IFunctionTree tree = MakeUnbalancedTree(rootFunction, maxTreeSize - 1, maxTreeHeight - 1);
       return tree;
+    }
+
+    internal IFunctionTree PTC2(IRandom random, int size, int maxDepth) {
+      if(size == 1) return RandomSelect(terminals).GetTreeNode();
+      List<object[]> list = new List<object[]>();
+      IFunctionTree root = GetRandomRoot(size, maxDepth).GetTreeNode();
+      int currentSize = 1;
+      int minArity;
+      int maxArity;
+      GetMinMaxArity(root.Function, out minArity, out maxArity);
+      if(maxArity >= size) {
+        maxArity = size;
+      }
+      int actualArity = random.Next(minArity, maxArity + 1);
+      for(int i=0;i<actualArity;i++) {
+        // insert a dummy sub-tree and add the pending extension to the list
+        root.AddSubTree(null);
+        list.Add(new object[] {root, i, 2});
+      }
+
+      while(list.Count > 0 && list.Count + currentSize < size) {
+        int randomIndex = random.Next(list.Count);
+        object[] nextExtension = list[randomIndex];
+        list.RemoveAt(randomIndex);
+        IFunctionTree parent = (IFunctionTree)nextExtension[0];
+        int a = (int)nextExtension[1];
+        int d = (int)nextExtension[2];
+        if(d == maxDepth) {
+          parent.RemoveSubTree(a);
+          parent.InsertSubTree(a, RandomSelect(terminals).GetTreeNode());
+        } else {
+          IFunction selectedFunction = RandomSelect(functions);
+          IFunctionTree newTree = selectedFunction.GetTreeNode();
+          parent.RemoveSubTree(a);
+          parent.InsertSubTree(a, newTree);
+
+          GetMinMaxArity(selectedFunction, out minArity, out maxArity);
+          if(maxArity >= size) {
+            maxArity = size;
+          }
+          actualArity = random.Next(minArity, maxArity + 1);
+          for(int i = 0; i < actualArity; i++) {
+            // insert a dummy sub-tree and add the pending extension to the list
+            newTree.AddSubTree(null);
+            list.Add(new object[] { newTree, i, d + 1 });
+          }
+        }
+        currentSize++;
+      }
+      while(list.Count > 0) {
+        int randomIndex = random.Next(list.Count);
+        object[] nextExtension = list[randomIndex];
+        list.RemoveAt(randomIndex);
+        IFunctionTree parent = (IFunctionTree)nextExtension[0];
+        int a = (int)nextExtension[1];
+        int d = (int)nextExtension[2];
+        IFunction selectedTerminal = RandomSelect(terminals);
+        parent.RemoveSubTree(a);
+        parent.InsertSubTree(a, selectedTerminal.GetTreeNode());
+      }
+      return root;
     }
 
