Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction-3.3.csproj
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction-3.3.csproj	(revision 12923)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction-3.3.csproj	(revision 12924)
@@ -99,4 +99,8 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="HeuristicLab.Algorithms.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.DataAnalysis-3.4.dll</HintPath>
+    </Reference>
     <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -142,4 +146,8 @@
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
       <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
@@ -169,4 +177,5 @@
     </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="QualityFunctions\GbtApproximateStateValueFunction.cs" />
     <Compile Include="QualityFunctions\TabularStateValueFunctionBase.cs" />
     <Compile Include="QualityFunctions\TabularAvgStateValueFunction.cs" />
@@ -198,5 +207,7 @@
     </BootstrapperPackage>
   </ItemGroup>
-  <ItemGroup />
+  <ItemGroup>
+    <Folder Include="FeatureFunctions\" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/IStateValueFunction.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/IStateValueFunction.cs	(revision 12923)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/IStateValueFunction.cs	(revision 12924)
@@ -8,5 +8,5 @@
 namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
   // represents the state value function (V(s))
-  public interface IStateValueFunction : IStatefulItem {
+  public interface IStateValueFunction : IItem {
     double Value(object state);
     void Update(object state, double observedQuality);
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/BoltzmannExplorationSymbolicExpressionConstructionPolicy.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/BoltzmannExplorationSymbolicExpressionConstructionPolicy.cs	(revision 12923)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/BoltzmannExplorationSymbolicExpressionConstructionPolicy.cs	(revision 12924)
@@ -45,5 +45,4 @@
       var idxs = Enumerable.Range(0, followStates.Count);
       // find best action
-      var bestQuality = double.NegativeInfinity;
       if (followStates.Any(s => StateValueFunction.Tries(s) == 0)) {
         return idxs.Where(idx => StateValueFunction.Tries(followStates[idx]) == 0).SampleRandom(random);
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/RandomSymbolicExpressionConstructionPolicy.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/RandomSymbolicExpressionConstructionPolicy.cs	(revision 12923)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/RandomSymbolicExpressionConstructionPolicy.cs	(revision 12924)
@@ -23,5 +23,4 @@
 
     public sealed override void Update(IEnumerable<object> stateSequence, double quality) {
-
       // ignore
     }
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/GbtApproximateStateValueFunction.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/GbtApproximateStateValueFunction.cs	(revision 12924)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/GbtApproximateStateValueFunction.cs	(revision 12924)
@@ -0,0 +1,175 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Runtime.InteropServices.WindowsRuntime;
+using HeuristicLab.Algorithms.DataAnalysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  [StorableClass]
+  public class GbtApproximateStateValueFunction : ParameterizedNamedItem, IStateValueFunction {
+    // encapuslates a feature list as a state (that is equatable)
+    [StorableClass]
+    private class FeatureState : IEquatable<FeatureState> {
+      private SortedList<string, double> features; // readonly
+
+      public FeatureState(IEnumerable<Tuple<string, double>> features) {
+        this.features = new SortedList<string, double>(features.ToDictionary(t => t.Item1, t => t.Item2));
+      }
+
+      public IEnumerable<string> GetFeatures() {
+        return features.Keys;
+      }
+      public double GetValue(string featureName) {
+        double d;
+        if (!features.TryGetValue(featureName, out d)) return 0.0;
+        else return d;
+      }
+
+      public bool Equals(FeatureState other) {
+        if (other == null) return false;
+        if (other.features.Count != this.features.Count) return false;
+        var f0 = this.features.GetEnumerator();
+        var f1 = other.features.GetEnumerator();
+        while (f0.MoveNext() & f1.MoveNext()) {
+          if (f0.Current.Key != f1.Current.Key ||
+             Math.Abs(f0.Current.Value - f1.Current.Value) > 1E-6) return false;
+        }
+        return true;
+      }
+
+      public override bool Equals(object obj) {
+        return this.Equals(obj as FeatureState);
+      }
+
+      public override int GetHashCode() {
+        // TODO perf
+        return string.Join("", features.Keys).GetHashCode();
+      }
+    }
+
+    // calculates a sparse list of features 
+    [StorableClass]
+    [Item("FeaturesFunction", "")]
+    private class FeaturesFunction : Item, IStateFunction {
+      public FeaturesFunction() {
+      }
+
+      private FeaturesFunction(FeaturesFunction original, Cloner cloner)
+        : base(original, cloner) {
+      }
+      [StorableConstructor]
+      protected FeaturesFunction(bool deserializing) : base(deserializing) { }
+      public object CreateState(ISymbolicExpressionTreeNode root, List<ISymbol> actions, ISymbolicExpressionTreeNode parentNode, int childIdx) {
+        return new FeatureState(actions.GroupBy(a => a.Name).Select(g => Tuple.Create(g.Key, g.Count() / (double)actions.Count))); // terminal frequencies
+      }
+
+      public override IDeepCloneable Clone(Cloner cloner) {
+        return new FeaturesFunction(this, cloner);
+      }
+    }
+
+    [Storable]
+    private readonly ITabularStateValueFunction observedValues = new TabularMaxStateValueFunction(); // we only store the max observed value for each feature state
+    [Storable]
+    private readonly HashSet<FeatureState> observedStates = new HashSet<FeatureState>();
+    [Storable]
+    private readonly Dictionary<string, int> observedFeatures = new Dictionary<string, int>();
+
+    public IStateFunction StateFunction {
+      get {
+        return ((IValueParameter<IStateFunction>)Parameters["Feature function"]).Value;
+      }
+      private set { ((IValueParameter<IStateFunction>)Parameters["Feature function"]).Value = value; }
+    }
+
+    public GbtApproximateStateValueFunction()
+      : base() {
+      Parameters.Add(new ValueParameter<IStateFunction>("Feature function", "The function that generates features for value approximation", new FeaturesFunction()));
+    }
+
+    private IRegressionModel model;
+    private ModifiableDataset applicationDs;
+    public double Value(object state) {
+      if (model == null) return double.PositiveInfinity; // no function approximation yet
+
+      // init the row
+      var featureState = state as FeatureState;
+      foreach (var variableName in applicationDs.VariableNames)
+        applicationDs.SetVariableValue(featureState.GetValue(variableName), variableName, 0);
+
+      // only one row
+      return model.GetEstimatedValues(applicationDs, new int[] { 0 }).First();
+    }
+
+
+    private int newStatesUntilModelUpdate = 1000;
+    public virtual void Update(object state, double observedQuality) {
+      // update dataset of observed values
+      var featureState = state as FeatureState;
+      if (!observedStates.Contains(featureState)) {
+        newStatesUntilModelUpdate--;
+        observedStates.Add(featureState);
+      }
+      observedValues.Update(state, observedQuality);
+      foreach (var f in featureState.GetFeatures()) {
+        if (observedFeatures.ContainsKey(f)) observedFeatures[f]++;
+        else observedFeatures.Add(f, 1);
+      }
+      if (newStatesUntilModelUpdate == 0) {
+        newStatesUntilModelUpdate = 100;
+        // update model after 100 new states have been observed
+        var variableNames = new string[] { "target" }.Concat(observedFeatures.OrderByDescending(e => e.Value).Select(e => e.Key).Take(50)).ToArray();
+        var rows = observedStates.Count;
+        var cols = variableNames.Count();
+        var variableValues = new double[rows, cols];
+        int r = 0;
+        foreach (var obsState in observedStates) {
+          variableValues[r, 0] = observedValues.Value(obsState);
+          for (int c = 1; c < cols; c++) {
+            variableValues[r, c] = obsState.GetValue(variableNames[c]);
+          }
+          r++;
+        }
+        var trainingDs = new Dataset(variableNames, variableValues);
+        applicationDs = new ModifiableDataset(variableNames, variableNames.Select(i => new List<double>(new[] { 0.0 }))); // init one row with zero values
+        var problemData = new RegressionProblemData(trainingDs, variableNames.Skip(1), variableNames.First());
+        var solution = GradientBoostedTreesAlgorithmStatic.TrainGbm(problemData, new SquaredErrorLoss(), 30, 0.01, 0.5, 0.5, 200);
+        //var rmsError = 0.0;
+        //var cvRmsError = 0.0;
+        //var solution = (SymbolicRegressionSolution)LinearRegression.CreateLinearRegressionSolution(problemData, out rmsError, out cvRmsError);
+        model = solution.Model;
+      }
+    }
+
+
+    #region item
+    [StorableConstructor]
+    protected GbtApproximateStateValueFunction(bool deserializing) : base(deserializing) { }
+    protected GbtApproximateStateValueFunction(GbtApproximateStateValueFunction original, Cloner cloner)
+      : base(original, cloner) {
+      // TODO
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GbtApproximateStateValueFunction(this, cloner);
+    }
+    #endregion
+
+    public void InitializeState() {
+      ClearState();
+    }
+
+    public void ClearState() {
+
+    }
+
+  }
+
+
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularAvgStateValueFunction.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularAvgStateValueFunction.cs	(revision 12923)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularAvgStateValueFunction.cs	(revision 12924)
@@ -9,5 +9,5 @@
   [StorableClass]
   [Item("TabularAvgQualityFunction", "")]
-  internal class TabularAvgStateValueFunction : TabularStateValueFunctionBase {
+  public class TabularAvgStateValueFunction : TabularStateValueFunctionBase {
 
     public TabularAvgStateValueFunction()
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularMaxStateValueFunction.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularMaxStateValueFunction.cs	(revision 12923)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularMaxStateValueFunction.cs	(revision 12924)
@@ -9,5 +9,5 @@
   [StorableClass]
   [Item("TabularMaxStateValueFunction", "")]
-  internal class TabularMaxStateValueFunction : TabularStateValueFunctionBase {
+  public class TabularMaxStateValueFunction : TabularStateValueFunctionBase {
 
     public TabularMaxStateValueFunction()
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularStateValueFunctionBase.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularStateValueFunctionBase.cs	(revision 12923)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularStateValueFunctionBase.cs	(revision 12924)
@@ -8,5 +8,5 @@
 namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
   [StorableClass]
-  internal abstract class TabularStateValueFunctionBase : ParameterizedNamedItem, ITabularStateValueFunction {
+  public abstract class TabularStateValueFunctionBase : ParameterizedNamedItem, ITabularStateValueFunction {
     [Storable]
     private readonly Dictionary<object, double> q = new Dictionary<object, double>();
@@ -78,13 +78,13 @@
     #endregion
 
-    public void InitializeState() {
-      ClearState();
-    }
-
-    public void ClearState() {
-      q.Clear();
-      tries.Clear();
-      qVariance.Clear();
-    }
+    //public void InitializeState() {
+    //  ClearState();
+    //}
+    //
+    //public void ClearState() {
+    //  q.Clear();
+    //  tries.Clear();
+    //  qVariance.Clear();
+    //}
   }
 }
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/SearchTree.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/SearchTree.cs	(revision 12923)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/SearchTree.cs	(revision 12924)
@@ -8,8 +8,8 @@
 namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
   internal class SearchTree<TValue> {
-    private class Node<TValue> {
+    private class Node {
       internal TValue value;
-      internal Node<TValue> parent;
-      internal Node<TValue>[] children;
+      internal Node parent;
+      internal Node[] children;
       // children == null -> never visited
       // children[i] != null -> visited at least once, still allowed
@@ -17,11 +17,11 @@
     }
 
-    private Node<TValue> root;
+    private Node root;
 
     // for iteration
-    private Node<TValue> currentNode;
+    private Node currentNode;
 
     public SearchTree() {
-      root = new Node<TValue>();
+      root = new Node();
       currentNode = root;
     }
@@ -38,5 +38,5 @@
       Contract.Assert(values.Any());
       Contract.Assert(currentNode.children == null);
-      currentNode.children = values.Select(val => new Node<TValue>() { value = val, parent = currentNode }).ToArray();
+      currentNode.children = values.Select(val => new Node() { value = val, parent = currentNode }).ToArray();
     }
 
@@ -71,5 +71,5 @@
     }
 
-    private void RemoveRecursively(Node<TValue> node) {
+    private void RemoveRecursively(Node node) {
       // when the last child has been removed we must remove the current node from it's parent
       while (node.parent != null && node.children.All(ch => ch == null)) {
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/StateFunctions/DefaultStateFunction.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/StateFunctions/DefaultStateFunction.cs	(revision 12923)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/StateFunctions/DefaultStateFunction.cs	(revision 12924)
@@ -13,5 +13,5 @@
   [StorableClass]
   [Item("DefaultStateFunction", "")]
-  internal class DefaultStateFunction : Item, IStateFunction {
+  public class DefaultStateFunction : Item, IStateFunction {
     public DefaultStateFunction()
       : base() {
@@ -19,5 +19,5 @@
 
     public object CreateState(ISymbolicExpressionTreeNode root, List<ISymbol> actions, ISymbolicExpressionTreeNode parentNode, int childIdx) {
-      return string.Join(",", actions.Select(a => a.Name));
+      return string.Join(",", actions.Select(a => a.Name)); // TODO: perf
     }
 
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/StateFunctions/ParentChildStateFunction.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/StateFunctions/ParentChildStateFunction.cs	(revision 12923)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/StateFunctions/ParentChildStateFunction.cs	(revision 12924)
@@ -14,5 +14,5 @@
   [StorableClass]
   [Item("ParentChildStateFunction", "")]
-  internal class ParentChildStateFunction : Item, IStateFunction {
+  public class ParentChildStateFunction : Item, IStateFunction {
     public ParentChildStateFunction()
       : base() {
@@ -20,5 +20,6 @@
 
     public object CreateState(ISymbolicExpressionTreeNode root, List<ISymbol> actions, ISymbolicExpressionTreeNode parentNode, int childIdx) {
-      return (parentNode == null ? "" : parentNode.Symbol.Name) + childIdx;
+      if (parentNode == null) return string.Empty;
+      else return parentNode.Symbol.Name + "." + string.Join(".", parentNode.Subtrees.Select(t => t.Symbol.Name));
     }
 
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/Tests/IteratedSymbolicExpressionConstructionTest.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/Tests/IteratedSymbolicExpressionConstructionTest.cs	(revision 12923)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/Tests/IteratedSymbolicExpressionConstructionTest.cs	(revision 12924)
@@ -12,10 +12,10 @@
 
       // see Langdon and Poli, "Why Ants are Hard", Table 2 (http://marvin.cs.uidaho.edu/Teaching/CS472/santaFeTrailSpace.pdf)
-      TestAlg(problem: new Problem(), maxLen: 3, expectedEvals: 3, expectedBestQuality: 3);
-      TestAlg(problem: new Problem(), maxLen: 4, expectedEvals: 3, expectedBestQuality: 3);
-      TestAlg(problem: new Problem(), maxLen: 5, expectedEvals: 21, expectedBestQuality: 11);
-      TestAlg(problem: new Problem(), maxLen: 6, expectedEvals: 48, expectedBestQuality: 11);
-      TestAlg(problem: new Problem(), maxLen: 10, expectedEvals: 25455, expectedBestQuality: 47);
-      TestAlg(problem: new Problem(), maxLen: 13, expectedEvals: 3191259, expectedBestQuality: 89);
+      TestAlg(problem: new Problem(), policy: new RandomSymbolicExpressionConstructionPolicy(), maxLen: 3, expectedEvals: 3, expectedBestQuality: 3);
+      TestAlg(problem: new Problem(), policy: new RandomSymbolicExpressionConstructionPolicy(), maxLen: 4, expectedEvals: 3, expectedBestQuality: 3);
+      TestAlg(problem: new Problem(), policy: new RandomSymbolicExpressionConstructionPolicy(), maxLen: 5, expectedEvals: 21, expectedBestQuality: 11);
+      TestAlg(problem: new Problem(), policy: new RandomSymbolicExpressionConstructionPolicy(), maxLen: 6, expectedEvals: 48, expectedBestQuality: 11);
+      TestAlg(problem: new Problem(), policy: new RandomSymbolicExpressionConstructionPolicy(), maxLen: 10, expectedEvals: 25455, expectedBestQuality: 47);
+      TestAlg(problem: new Problem(), policy: new RandomSymbolicExpressionConstructionPolicy(), maxLen: 13, expectedEvals: 3191259, expectedBestQuality: 89);
 
       // log of runtimes (28.08.2015), single core, Intel Core i5 @3.2 GHz
@@ -29,9 +29,26 @@
     }
 
-    private void TestAlg(Problem problem, int maxLen, int expectedEvals, double expectedBestQuality) {
+    [TestMethod]
+    public void TestStateAggregation() {
+      var stateValueFunction = new TabularMaxStateValueFunction();
+      stateValueFunction.StateFunction = new ParentChildStateFunction();
+      var pol = new UcbSymbolicExpressionConstructionPolicy();
+      pol.StateValueFunction = stateValueFunction;
+      TestAlg(new Problem(), pol, maxLen: 13, expectedEvals: 3191259, expectedBestQuality: 89);
+    }
+
+    [TestMethod]
+    public void TestStateValueApproximation() {
+      var stateValueFunction = new GbtApproximateStateValueFunction();
+      var pol = new EpsGreedySymbolicExpressionConstructionPolicy();
+      pol.StateValueFunction = stateValueFunction;      
+      TestAlg(new Problem(), pol, maxLen: 13, expectedEvals: 3191259, expectedBestQuality: 89);
+    }
+
+    private void TestAlg(Problem problem, ISymbolicExpressionConstructionPolicy policy, int maxLen, int expectedEvals, double expectedBestQuality) {
       var alg = new IteratedSymbolicExpressionConstruction();
       problem.Encoding.TreeLength = maxLen;
       alg.Problem = problem;
-      alg.PolicyParameter.Value = new RandomSymbolicExpressionConstructionPolicy();
+      alg.PolicyParameter.Value = policy;
       alg.MaximumEvaluations = 5000000;
 
