Index: /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis.MCTSSymbReg.csproj
===================================================================
--- /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis.MCTSSymbReg.csproj	(revision 15437)
+++ /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis.MCTSSymbReg.csproj	(revision 15438)
@@ -100,5 +100,4 @@
     <Compile Include="Heuristics.cs" />
     <Compile Include="MctsSymbolicRegression\ApproximateDoubleEqualityComparer.cs" />
-    <Compile Include="MctsSymbolicRegression\IConstraintHandler.cs" />
     <Compile Include="MctsSymbolicRegression\Automaton.cs" />
     <Compile Include="MctsSymbolicRegression\CodeGenerator.cs" />
@@ -108,11 +107,5 @@
     <Compile Include="MctsSymbolicRegression\MctsSymbolicRegressionStatic.cs" />
     <Compile Include="MctsSymbolicRegression\OpCodes.cs" />
-    <Compile Include="MctsSymbolicRegression\Policies\EpsGreedy.cs" />
-    <Compile Include="MctsSymbolicRegression\Policies\IActionStatistics.cs" />
-    <Compile Include="MctsSymbolicRegression\Policies\IPolicy.cs" />
-    <Compile Include="MctsSymbolicRegression\Policies\PolicyBase.cs" />
     <Compile Include="MctsSymbolicRegression\ExprHash.cs" />
-    <Compile Include="MctsSymbolicRegression\EmptyConstraintHandler.cs" />
-    <Compile Include="MctsSymbolicRegression\SimpleConstraintHandler.cs" />
     <Compile Include="MctsSymbolicRegression\SymbolicExpressionGenerator.cs" />
     <Compile Include="MctsSymbolicRegression\Tree.cs" />
@@ -122,4 +115,7 @@
   <ItemGroup>
     <None Include="Plugin.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="MctsSymbolicRegression\Policies\" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Index: /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/Heuristics.cs
===================================================================
--- /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/Heuristics.cs	(revision 15437)
+++ /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/Heuristics.cs	(revision 15438)
@@ -22,14 +22,35 @@
   public static class Heuristics {
     public static double CorrelationForInteraction(double[] a, double[] b, double[] c, double[] target) {
-      return 0.0;
-    }
-    public static double CorrelationForInteraction(double[] a, double[] b, double[] z) {
-      // 
       var am = a.Average();
       var bm = b.Average();
+      var cm = c.Average();
       var p1 = Enumerable.Range(0, a.Length).Where(i => a[i] < am);
       var p2 = Enumerable.Range(0, a.Length).Where(i => a[i] > am);
       var p3 = Enumerable.Range(0, a.Length).Where(i => b[i] < bm);
       var p4 = Enumerable.Range(0, a.Length).Where(i => b[i] > bm);
+      var p5 = Enumerable.Range(0, a.Length).Where(i => c[i] < cm);
+      var p6 = Enumerable.Range(0, a.Length).Where(i => c[i] > cm);
+
+      return 1.0 / (p1.Count() + p2.Count() + p3.Count() + p4.Count() + p5.Count() + p6.Count()) * 
+        (
+        p1.Count() * CorrelationForInteraction(b, c, target, p1) +
+        p2.Count() * CorrelationForInteraction(b, c, target, p2) +
+        p3.Count() * CorrelationForInteraction(a, c, target, p3) +
+        p4.Count() * CorrelationForInteraction(a, c, target, p3) +
+        p5.Count() * CorrelationForInteraction(a, b, target, p5) +
+        p6.Count() * CorrelationForInteraction(a, b, target, p6)
+      );
+    }
+    public static double CorrelationForInteraction(double[] a, double[] b, double[] z) {
+      return CorrelationForInteraction(a, b, z, Enumerable.Range(0, a.Length));
+    }
+    public static double CorrelationForInteraction(double[] a, double[] b, double[] z, IEnumerable<int> idx) {
+      // 
+      var am = a.Average();
+      var bm = b.Average();
+      var p1 = idx.Where(i => a[i] < am);
+      var p2 = idx.Where(i => a[i] > am);
+      var p3 = idx.Where(i => b[i] < bm);
+      var p4 = idx.Where(i => b[i] > bm);
 
       return 1.0 / (p1.Count() + p2.Count() + p3.Count() + p4.Count()) *
Index: /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/Automaton.cs
===================================================================
--- /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/Automaton.cs	(revision 15437)
+++ /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/Automaton.cs	(revision 15438)
@@ -118,15 +118,17 @@
     private List<string>[,] actionStrings; // just for printing 
     private readonly CodeGenerator codeGenerator;
-    private IConstraintHandler constraintHandler;
-
-    public Automaton(double[][] vars, IConstraintHandler constraintHandler,
+    private int numVarRefs;
+    private int maximumNumberOfVariables;
+
+    public Automaton(double[][] vars,
        bool allowProdOfVars = true,
        bool allowExp = true,
        bool allowLog = true,
        bool allowInv = true,
-       bool allowMultipleTerms = false) {
+       bool allowMultipleTerms = false,
+       int maxNumberOfVariables = 5) {
       int nVars = vars.Length;
+      this.maximumNumberOfVariables = maxNumberOfVariables;
       codeGenerator = new CodeGenerator();
-      this.constraintHandler = constraintHandler;
       BuildAutomaton(nVars, allowProdOfVars, allowExp, allowLog, allowInv, allowMultipleTerms);
 
@@ -165,5 +167,5 @@
         codeGenerator.Reset();
         codeGenerator.Emit1(OpCodes.LoadConst0);
-        constraintHandler.Reset();
+        numVarRefs = 0;
       }, "0");
       AddTransition(StateTermEnd, StateExprEnd, () => {
@@ -180,5 +182,4 @@
         () => {
           codeGenerator.Emit1(OpCodes.LoadParamN);
-          constraintHandler.StartTerm();
         },
         "c");
@@ -186,5 +187,4 @@
         () => {
           codeGenerator.Emit1(OpCodes.Mul);
-          constraintHandler.EndTerm();
         },
         "*");
@@ -198,22 +198,18 @@
       if (allowProdOfVars)
         AddTransition(StateFactorStart, StateVariableFactorStart, () => {
-          constraintHandler.StartFactor(StateVariableFactorStart);
         }, "");
       if (allowExp)
         AddTransition(StateFactorStart, StateExpFactorStart, () => {
-          constraintHandler.StartFactor(StateExpFactorStart);
         }, "");
       if (allowLog)
         AddTransition(StateFactorStart, StateLogFactorStart, () => {
-          constraintHandler.StartFactor(StateLogFactorStart);
         }, "");
       if (allowInv)
         AddTransition(StateFactorStart, StateInvFactorStart, () => {
-          constraintHandler.StartFactor(StateInvFactorStart);
         }, "");
-      AddTransition(StateVariableFactorEnd, StateFactorEnd, () => { constraintHandler.EndFactor(); }, "");
-      AddTransition(StateExpFactorEnd, StateFactorEnd, () => { constraintHandler.EndFactor(); }, "");
-      AddTransition(StateLogFactorEnd, StateFactorEnd, () => { constraintHandler.EndFactor(); }, "");
-      AddTransition(StateInvFactorEnd, StateFactorEnd, () => { constraintHandler.EndFactor(); }, "");
+      AddTransition(StateVariableFactorEnd, StateFactorEnd);
+      AddTransition(StateExpFactorEnd, StateFactorEnd);
+      AddTransition(StateLogFactorEnd, StateFactorEnd);
+      AddTransition(StateInvFactorEnd, StateFactorEnd);
 
       // VarFact -> var_1 ... var_n
@@ -227,5 +223,5 @@
           () => {
             codeGenerator.Emit2(OpCodes.LoadVar, varIdx);
-            constraintHandler.AddVarToCurrentFactor(varState);
+            numVarRefs++;
           },
           "var_" + varIdx + "");
@@ -259,5 +255,5 @@
           () => {
             codeGenerator.Emit2(OpCodes.LoadVar, varIdx);
-            constraintHandler.AddVarToCurrentFactor(varState);
+            numVarRefs++;
           },
           "var_" + varIdx + "");
@@ -274,5 +270,4 @@
         () => {
           codeGenerator.Emit1(OpCodes.LoadConst0);
-          constraintHandler.StartNewTermInPoly();
         },
         "0");
@@ -314,5 +309,5 @@
           () => {
             codeGenerator.Emit2(OpCodes.LoadVar, varIdx);
-            constraintHandler.AddVarToCurrentFactor(varState);
+            numVarRefs++;
           },
           "var_" + varIdx + "");
@@ -325,5 +320,4 @@
         () => {
           codeGenerator.Emit1(OpCodes.LoadConst1);
-          constraintHandler.StartNewTermInPoly();
         },
         "c");
@@ -363,5 +357,5 @@
           () => {
             codeGenerator.Emit2(OpCodes.LoadVar, varIdx);
-            constraintHandler.AddVarToCurrentFactor(varState);
+            numVarRefs++;
           },
           "var_" + varIdx + "");
@@ -401,5 +395,5 @@
       for (int i = 0; i < fs.Count; i++) {
         var s = fs[i];
-        if (constraintHandler.IsAllowedFollowState(state, s)) {
+        if (IsAllowedFollowState(state, s)) {
           buf[j++] = s;
         }
@@ -408,4 +402,10 @@
     }
 
+    private bool IsAllowedFollowState(int state, int nextState) {
+      // any state is allowed if we have not reached the max number of variable references
+      // otherwise we can only go towards the final state (smaller state numbers)
+      if (numVarRefs < maximumNumberOfVariables) return true;
+      else return state > nextState;
+    }
 
     public void Goto(int targetState) {
@@ -417,5 +417,5 @@
 
     public bool IsFinalState(int s) {
-      return s == StateExprEnd && !constraintHandler.IsInvalidExpression;
+      return s == StateExprEnd && numVarRefs <= maximumNumberOfVariables;
     }
 
@@ -434,5 +434,4 @@
     // After that state of the automaton is restored to the current state.
     public void GetCode(out byte[] code, out int nParams) {
-      IConstraintHandler storedConstraintHandler = null;
       int storedState = CurrentState;
       int storedPC = codeGenerator.ProgramCounter;
@@ -440,7 +439,4 @@
       if (!IsFinalState(CurrentState)) {
         // save state and code,
-        // constraints are ignored while completing the expression
-        storedConstraintHandler = constraintHandler;
-        constraintHandler = new EmptyConstraintHandler();
         storedState = CurrentState;
         storedPC = codeGenerator.ProgramCounter;
@@ -457,9 +453,6 @@
 
       // restore 
-      if (storedConstraintHandler != null) {
-        constraintHandler = storedConstraintHandler;
-        CurrentState = storedState;
-        codeGenerator.ProgramCounter = storedPC;
-      }
+      codeGenerator.ProgramCounter = storedPC;
+      CurrentState = storedState;
     }
 
@@ -467,5 +460,5 @@
       CurrentState = StartState;
       codeGenerator.Reset();
-      constraintHandler.Reset();
+      numVarRefs = 0;
     }
 
Index: anches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/ConstraintHandler.cs
===================================================================
--- /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/ConstraintHandler.cs	(revision 15437)
+++ 	(revision )
@@ -1,419 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 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;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using System.Linq;
-
-namespace HeuristicLab.Algorithms.DataAnalysis.MctsSymbolicRegression {
-
-  // This class restricts the set of allowed transitions of the automaton to prevent exploration of duplicate expressions.
-  // It would be possible to implement this class in such a way that the search never visits a duplicate expression. However,
-  // it seems very intricate to detect this robustly while generating an expression because 
-  // some form of lookahead is necessary. 
-  // Instead, the constraint handler only catches the obvious duplicates directly, but does not guarantee that the search always produces a valid expression.
-  // The ratio of the number of unsuccessful searches, that need backtracking should be tracked in the MCTS alg (MctsSymbolicRegressionStatic)
-
-  // All changes to this class should be tested through unit tests. It is important that the ConstraintHandler is not too restrictive.
-
-  // the constraints are derived from a canonical form for expressions.
-  // overall we can enforce a limited number of variable references
-  // 
-  // an expression is a sum of terms t_1 ... t_n where terms are ordered according to a relation t_i (<=)_term t_j for each pair t_i, t_j and i <= j
-  // a term is a product of factors where factors are ordered according to relation f_i (<=)_factor f_j for each pair f_i,f_j and i <= j
-
-  // we want to enforce lower-order terms before higher-order terms in expressions (based on number of variable references)
-  // factors can have different types (variable, exp, log, inverse)
-
-  // (<=)_term  [IsSmallerOrEqualTerm(t_i, t_j)]
-  //   1.  NumberOfVarRefs(t_i) < NumberOfVarRefs(t_j)  --> true           enforce terms with non-decreasing number of var refs
-  //   2.  NumberOfVarRefs(t_i) > NumberOfVarRefs(t_j)  --> false
-  //   3.  NumFactors(t_i) > NumFactors(t_j)            --> true           enforce terms with non-increasing number of factors
-  //   4.  NumFactors(t_i) < NumFactors(t_j)            --> false
-  //   5.  for all k factors: Factor(k, t_i) (<=)_factor  Factor(k, t_j) --> true // factors must be non-decreasing
-  //   6.  all factors are (=)_factor                   --> true
-  //   7.  else false
-
-  // (<=)_factor  [IsSmallerOrEqualFactor(f_i, f_j)]
-  //   1.  FactorType(t_i) < FactorType(t_j)  --> true           enforce terms with non-decreasing factor type (var < exp < log < inv)
-  //   2.  FactorType(t_i) > FactorType(t_j)  --> false
-  //   3.  Compare the two factors specifically
-  //     - variables: varIdx_i <= varIdx_j (only one var reference)
-  //     - exp: number of variable references and then varIdx_i <= varIdx_j for each position
-  //     - log: number of variable references and ...
-  //     - inv: number of variable references and ...
-  //
-
-  // for log and inverse factors we allow all polynomials as argument
-  // a polynomial is a sum of terms t_1 ... t_n where terms are ordered according to a relation t_i (<=)_poly t_j for each pair t_i, t_j and i <= j
-
-  // (<=)_poly  [IsSmallerOrEqualPoly(t_i, t_j)]
-  //  1. NumberOfVarRefs(t_i) < NumberOfVarRefs(t_j)         --> true // enforce non-decreasing number of var refs
-  //  2. NumberOfVarRefs(t_i) > NumberOfVarRefs(t_j)         --> false // enforce non-decreasing number of var refs
-  //  3. for all k variables: VarIdx(k,t_i) > VarIdx(k, t_j) --> false // enforce non-decreasing variable idx
-
-
-  // we store the following to make comparsions:
-  // - prevTerm (complete & containing all factors)
-  // - curTerm  (incomplete & containing all completed factors)
-  // - curFactor (incomplete)
-  internal class ConstraintHandler : IConstraintHandler {
-    private int nVars;
-    private readonly int maxVariables;
-    private bool invalidExpression;
-
-    public bool IsInvalidExpression {
-      get { return invalidExpression; }
-    }
-
-
-    private TermInformation prevTerm;
-    private TermInformation curTerm;
-    private FactorInformation curFactor;
-
-
-    private class TermInformation {
-      public int numVarReferences { get { return factors.Sum(f => f.numVarReferences); } }
-      public List<FactorInformation> factors = new List<FactorInformation>();
-    }
-
-    private class FactorInformation {
-      public int numVarReferences = 0;
-      public int factorType; // use the state number to represent types
-
-      // for variable factors
-      public int variableState = -1;
-
-      // for exp  factors
-      public List<int> expVariableStates = new List<int>();
-
-      // for log and inv factors
-      public List<List<int>> polyVariableStates = new List<List<int>>();
-    }
-
-
-    public ConstraintHandler(int maxVars) {
-      this.maxVariables = maxVars;
-    }
-
-    // the order relations for terms and factors
-
-    private static int CompareTerms(TermInformation a, TermInformation b) {
-      if (a.numVarReferences < b.numVarReferences) return -1;
-      if (a.numVarReferences > b.numVarReferences) return 1;
-
-      if (a.factors.Count > b.factors.Count) return -1;  // terms with more factors should be ordered first
-      if (a.factors.Count < b.factors.Count) return +1;
-
-      var aFactors = a.factors.GetEnumerator();
-      var bFactors = b.factors.GetEnumerator();
-      while (aFactors.MoveNext() & bFactors.MoveNext()) {
-        var c = CompareFactors(aFactors.Current, bFactors.Current);
-        if (c < 0) return -1;
-        if (c > 0) return 1;
-      }
-      // all factors are the same => terms are the same
-      return 0;
-    }
-
-    private static int CompareFactors(FactorInformation a, FactorInformation b) {
-      if (a.factorType < b.factorType) return -1;
-      if (a.factorType > b.factorType) return +1;
-      // same factor types
-      if (a.factorType == Automaton.StateVariableFactorStart) {
-        return a.variableState.CompareTo(b.variableState);
-      } else if (a.factorType == Automaton.StateExpFactorStart) {
-        return CompareStateLists(a.expVariableStates, b.expVariableStates);
-      } else {
-        if (a.numVarReferences < b.numVarReferences) return -1;
-        if (a.numVarReferences > b.numVarReferences) return +1;
-        if (a.polyVariableStates.Count > b.polyVariableStates.Count) return -1; // more terms in the poly should be ordered first
-        if (a.polyVariableStates.Count < b.polyVariableStates.Count) return +1;
-        // log and inv
-        var aTerms = a.polyVariableStates.GetEnumerator();
-        var bTerms = b.polyVariableStates.GetEnumerator();
-        while (aTerms.MoveNext() & bTerms.MoveNext()) {
-          var c = CompareStateLists(aTerms.Current, bTerms.Current);
-          if (c != 0) return c;
-        }
-        return 0; // all terms in the polynomial are the same
-      }
-    }
-
-    private static int CompareStateLists(List<int> a, List<int> b) {
-      if (a.Count < b.Count) return -1;
-      if (a.Count > b.Count) return +1;
-      for (int i = 0; i < a.Count; i++) {
-        if (a[i] < b[i]) return -1;
-        if (a[i] > b[i]) return +1;
-      }
-      return 0; // all states are the same
-    }
-
-
-    private bool IsNewTermAllowed() {
-      // next term must have at least as many variable references as the previous term
-      return prevTerm == null || nVars + prevTerm.numVarReferences <= maxVariables;
-    }
-
-    private bool IsNewFactorAllowed() {
-      // next factor must have a larger or equal type compared to the previous factor.
-      // if the types are the same it must have at least as many variable references.
-      // so if the prevFactor is any other than invFactor (last possible type) then we only need to be able to add one variable
-      // otherwise we need to be able to add at least as many variables as the previous factor
-      return !curTerm.factors.Any() ||
-             (nVars + curTerm.factors.Last().numVarReferences <= maxVariables);
-    }
-
-    private bool IsAllowedAsNextFactorType(int followState) {
-      // IsNewTermAllowed already ensures that we can add a term with enough variable references
-
-      // enforce constraints within terms (compare to prev factor)
-      if (curTerm.factors.Any()) {
-        // enforce non-decreasing factor types
-        if (curTerm.factors.Last().factorType > followState) return false;
-        // when the factor type is the same, starting a new factor is only allowed if we can add at least the number of variables of the prev factor
-        if (curTerm.factors.Last().factorType == followState && nVars + curTerm.factors.Last().numVarReferences > maxVariables) return false;
-      }
-
-      // enforce constraints on terms (compare to prev term)
-      // meaning that we must ensure non-decreasing terms
-      if (prevTerm != null) {
-        // a factor type is only allowed if we can then produce a term that is larger or equal to the prev term
-        // (1) if we the number of variable references still remaining is larger than the number of variable references in the prev term 
-        //     then it is always possible to build a larger term
-        // (2) otherwise we try to build the largest possible term starting from current factors in the term.
-        //     
-
-        var numVarRefsRemaining = maxVariables - nVars;
-        Contract.Assert(!curTerm.factors.Any() || curTerm.factors.Last().numVarReferences <= numVarRefsRemaining);
-
-        if (prevTerm.numVarReferences < numVarRefsRemaining) return true;
-
-        // variable factors must be handled differently because they can only contain one variable reference
-        if (followState == Automaton.StateVariableFactorStart) {
-          // append the variable factor and the maximum possible state from the previous factor to create a larger factor
-          var varF = CreateLargestPossibleFactor(Automaton.StateVariableFactorStart, 1);
-          var maxF = CreateLargestPossibleFactor(prevTerm.factors.Max(f => f.factorType), numVarRefsRemaining - 1);
-          var origFactorCount = curTerm.factors.Count;
-          // add this factor to the current term
-          curTerm.factors.Add(varF);
-          curTerm.factors.Add(maxF);
-          var c = CompareTerms(prevTerm, curTerm);
-          // restore term
-          curTerm.factors.RemoveRange(origFactorCount, 2);
-          // if the prev term is still larger then this followstate is not allowed
-          if (c > 0) {
-            return false;
-          }
-        } else {
-          var newF = CreateLargestPossibleFactor(followState, numVarRefsRemaining);
-
-          var origFactorCount = curTerm.factors.Count;
-          // add this factor to the current term
-          curTerm.factors.Add(newF);
-          var c = CompareTerms(prevTerm, curTerm);
-          // restore term
-          curTerm.factors.RemoveAt(origFactorCount);
-          // if the prev term is still larger then this followstate is not allowed
-          if (c > 0) {
-            return false;
-          }
-        }
-      }
-      return true;
-    }
-
-    // largest possible factor of the given kind
-    private FactorInformation CreateLargestPossibleFactor(int factorType, int numVarRefs) {
-      var newF = new FactorInformation();
-      newF.factorType = factorType;
-      if (factorType == Automaton.StateVariableFactorStart) {
-        newF.variableState = int.MaxValue;
-        newF.numVarReferences = 1;
-      } else if (factorType == Automaton.StateExpFactorStart) {
-        for (int i = 0; i < numVarRefs; i++)
-          newF.expVariableStates.Add(int.MaxValue);
-        newF.numVarReferences = numVarRefs;
-      } else if (factorType == Automaton.StateInvFactorStart || factorType == Automaton.StateLogFactorStart) {
-        for (int i = 0; i < numVarRefs; i++) {
-          newF.polyVariableStates.Add(new List<int>());
-          newF.polyVariableStates[i].Add(int.MaxValue);
-        }
-        newF.numVarReferences = numVarRefs;
-      }
-      return newF;
-    }
-
-    private bool IsAllowedAsNextVariableFactor(int variableState) {
-      Contract.Assert(variableState >= Automaton.FirstDynamicState);
-      return !curTerm.factors.Any() || curTerm.factors.Last().variableState <= variableState;
-    }
-
-    private bool IsAllowedAsNextInExp(int variableState) {
-      Contract.Assert(variableState >= Automaton.FirstDynamicState);
-      if (curFactor.expVariableStates.Any() && curFactor.expVariableStates.Last() > variableState) return false;
-      if (curTerm.factors.Any()) {
-        // try and compare with prev factor      
-        curFactor.numVarReferences++;
-        curFactor.expVariableStates.Add(variableState);
-        var c = CompareFactors(curTerm.factors.Last(), curFactor);
-        curFactor.numVarReferences--;
-        curFactor.expVariableStates.RemoveAt(curFactor.expVariableStates.Count - 1);
-        return c <= 0;
-      }
-      return true;
-    }
-
-    private bool IsNewTermAllowedInPoly() {
-      return nVars + curFactor.polyVariableStates.Last().Count() <= maxVariables;
-    }
-
-    private bool IsAllowedAsNextInPoly(int variableState) {
-      Contract.Assert(variableState >= Automaton.FirstDynamicState);
-      return !curFactor.polyVariableStates.Any() ||
-             !curFactor.polyVariableStates.Last().Any() ||
-              curFactor.polyVariableStates.Last().Last() <= variableState;
-    }
-    private bool IsTermCompleteInPoly() {
-      var nTerms = curFactor.polyVariableStates.Count;
-      return nTerms == 1 ||
-             curFactor.polyVariableStates[nTerms - 2].Count <= curFactor.polyVariableStates[nTerms - 1].Count;
-
-    }
-    private bool IsCompleteExp() {
-      return !curTerm.factors.Any() || CompareFactors(curTerm.factors.Last(), curFactor) <= 0;
-    }
-
-    public bool IsAllowedFollowState(int currentState, int followState) {
-      // an invalid action was taken earlier on => nothing can be done anymore
-      if (invalidExpression) return false;
-      // states that have no alternative are always allowed
-      // some ending states are only allowed if enough variables have been used in the term
-      if (
-        currentState == Automaton.StateTermStart ||           // no alternative
-        currentState == Automaton.StateExpFactorStart ||
-        currentState == Automaton.StateLogFactorStart ||
-        currentState == Automaton.StateInvFactorStart ||
-        followState == Automaton.StateVariableFactorEnd ||    // no alternative
-        followState == Automaton.StateExpFEnd ||              // no alternative
-        followState == Automaton.StateLogTFEnd ||             // no alternative
-        followState == Automaton.StateInvTFEnd ||             // no alternative
-        followState == Automaton.StateFactorEnd ||            // always allowed because no alternative
-        followState == Automaton.StateExprEnd                 // we could also constrain the minimum number of terms here
-      ) return true;
-
-
-      // starting a new term is only allowed if we can add a term with at least the number of variables of the prev term
-      if (followState == Automaton.StateTermStart && !IsNewTermAllowed()) return false;
-      if (followState == Automaton.StateFactorStart && !IsNewFactorAllowed()) return false;
-      if (currentState == Automaton.StateFactorStart && !IsAllowedAsNextFactorType(followState)) return false;
-      if (followState == Automaton.StateTermEnd && prevTerm != null && CompareTerms(prevTerm, curTerm) > 0) return false;
-
-      // all of these states add at least one variable
-      if (
-          followState == Automaton.StateVariableFactorStart ||
-          followState == Automaton.StateExpFactorStart || followState == Automaton.StateExpFStart ||
-          followState == Automaton.StateLogFactorStart || followState == Automaton.StateLogTStart ||
-          followState == Automaton.StateLogTFStart ||
-          followState == Automaton.StateInvFactorStart || followState == Automaton.StateInvTStart ||
-          followState == Automaton.StateInvTFStart) {
-        if (nVars + 1 > maxVariables) return false;
-      }
-
-      if (currentState == Automaton.StateVariableFactorStart && !IsAllowedAsNextVariableFactor(followState)) return false;
-      else if (currentState == Automaton.StateExpFStart && !IsAllowedAsNextInExp(followState)) return false;
-      else if (followState == Automaton.StateLogTStart && !IsNewTermAllowedInPoly()) return false;
-      else if (currentState == Automaton.StateLogTFStart && !IsAllowedAsNextInPoly(followState)) return false;
-      else if (followState == Automaton.StateInvTStart && !IsNewTermAllowedInPoly()) return false;
-      else if (currentState == Automaton.StateInvTFStart && !IsAllowedAsNextInPoly(followState)) return false;
-      // finishing an exponential factor is only allowed when the number of variable references is large enough
-      else if (followState == Automaton.StateExpFactorEnd && !IsCompleteExp()) return false;
-      // finishing a polynomial (in log or inv) is only allowed when the number of variable references is large enough
-      else if (followState == Automaton.StateInvTEnd && !IsTermCompleteInPoly()) return false;
-      else if (followState == Automaton.StateLogTEnd && !IsTermCompleteInPoly()) return false;
-
-      else 
-
-      if (nVars > maxVariables) return false;
-      else return true;
-    }
-
-
-    public void Reset() {
-      nVars = 0;
-      prevTerm = null;
-      curTerm = null;
-      curFactor = null;
-      invalidExpression = false;
-    }
-
-    public void StartTerm() {
-      curTerm = new TermInformation();
-    }
-
-    public void StartFactor(int state) {
-      curFactor = new FactorInformation();
-      curFactor.factorType = state;
-    }
-
-
-    public void AddVarToCurrentFactor(int state) {
-      Contract.Assert(Automaton.FirstDynamicState <= state);
-      Contract.Assert(curTerm != null);
-      Contract.Assert(curFactor != null);
-
-      nVars++;
-      curFactor.numVarReferences++;
-
-      if (curFactor.factorType == Automaton.StateVariableFactorStart) {
-        Contract.Assert(curFactor.variableState < 0); // not set before
-        curFactor.variableState = state;
-      } else if (curFactor.factorType == Automaton.StateExpFactorStart) {
-        curFactor.expVariableStates.Add(state);
-      } else if (curFactor.factorType == Automaton.StateLogFactorStart ||
-                 curFactor.factorType == Automaton.StateInvFactorStart) {
-        curFactor.polyVariableStates.Last().Add(state);
-      } else throw new InvalidProgramException();
-    }
-
-    public void StartNewTermInPoly() {
-      curFactor.polyVariableStates.Add(new List<int>());
-    }
-
-    public void EndFactor() {
-      // enforce non-decreasing factors 
-      if (curTerm.factors.Any() && CompareFactors(curTerm.factors.Last(), curFactor) > 0)
-        invalidExpression = true;
-      curTerm.factors.Add(curFactor);
-      curFactor = null;
-    }
-
-    public void EndTerm() {
-      // enforce non-decreasing terms (TODO: equal terms should not be allowed)
-      if (prevTerm != null && CompareTerms(prevTerm, curTerm) > 0)
-        invalidExpression = true;
-      prevTerm = curTerm;
-      curTerm = null;
-    }
-  }
-}
Index: anches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/EmptyConstraintHandler.cs
===================================================================
--- /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/EmptyConstraintHandler.cs	(revision 15437)
+++ 	(revision )
@@ -1,45 +1,0 @@
-﻿
-
-namespace HeuristicLab.Algorithms.DataAnalysis.MctsSymbolicRegression {
-  // no constraints
-  internal class EmptyConstraintHandler : IConstraintHandler {
-    public bool IsInvalidExpression {
-      get {
-        return false;
-      }
-    }
-
-    public EmptyConstraintHandler() {
-    }
-
-    public void AddVarToCurrentFactor(int state) {
-    }
-
-    public void EndFactor() {
-      // ignore
-    }
-
-    public void EndTerm() {
-      // ignore
-    }
-
-    public bool IsAllowedFollowState(int currentState, int followState) {
-      return true;
-    }
-
-    public void Reset() {
-    }
-
-    public void StartFactor(int state) {
-      // ignore
-    }
-
-    public void StartNewTermInPoly() {
-      // ignore
-    }
-
-    public void StartTerm() {
-      // ignore
-    }
-  }
-}
Index: anches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/IConstraintHandler.cs
===================================================================
--- /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/IConstraintHandler.cs	(revision 15437)
+++ 	(revision )
@@ -1,19 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace HeuristicLab.Algorithms.DataAnalysis.MctsSymbolicRegression {
-  public interface IConstraintHandler {
-    bool IsInvalidExpression { get;    }
-    bool IsAllowedFollowState(int currentState, int followState);
-    void Reset();
-    void StartTerm();
-    void StartFactor(int state);
-    void AddVarToCurrentFactor(int state);
-    void StartNewTermInPoly();
-    void EndFactor();
-    void EndTerm();
-  }
-}
Index: /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/MctsSymbolicRegressionAlgorithm.cs
===================================================================
--- /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/MctsSymbolicRegressionAlgorithm.cs	(revision 15437)
+++ /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/MctsSymbolicRegressionAlgorithm.cs	(revision 15438)
@@ -23,5 +23,4 @@
 using System.Linq;
 using System.Threading;
-using HeuristicLab.Algorithms.DataAnalysis.MctsSymbolicRegression.Policies;
 using HeuristicLab.Analysis;
 using HeuristicLab.Common;
@@ -75,8 +74,5 @@
     public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter {
       get { return (IFixedValueParameter<IntValue>)Parameters[ConstantOptimizationIterationsParameterName]; }
-    }
-    public IValueParameter<IPolicy> PolicyParameter {
-      get { return (IValueParameter<IPolicy>)Parameters[PolicyParameterName]; }
-    }
+    }                  
     public IFixedValueParameter<DoubleValue> PunishmentFactorParameter {
       get { return (IFixedValueParameter<DoubleValue>)Parameters[PunishmentFactorParameterName]; }
@@ -121,8 +117,4 @@
       get { return MaxVariableReferencesParameter.Value.Value; }
       set { MaxVariableReferencesParameter.Value.Value = value; }
-    }
-    public IPolicy Policy {
-      get { return PolicyParameter.Value; }
-      set { PolicyParameter.Value = value; }
     }
     public double PunishmentFactor {
@@ -183,9 +175,4 @@
       Parameters.Add(new FixedValueParameter<IntValue>(MaxVariablesParameterName,
         "Maximal number of variables references in the symbolic regression models (multiple usages of the same variable are counted)", new IntValue(5)));
-      // Parameters.Add(new FixedValueParameter<DoubleValue>(CParameterName,
-      //   "Balancing parameter in UCT formula (0 < c < 1000). Small values: greedy search. Large values: enumeration. Default: 1.0", new DoubleValue(1.0)));
-      Parameters.Add(new ValueParameter<IPolicy>(PolicyParameterName,
-        "The policy to use for selecting nodes in MCTS", new EpsilonGreedy()));
-      PolicyParameter.Hidden = true;
       Parameters.Add(new ValueParameter<ICheckedItemList<StringValue>>(AllowedFactorsParameterName,
         "Choose which expressions are allowed as factors in the model.", defaultFactorsList));
@@ -275,5 +262,5 @@
       var state = MctsSymbolicRegressionStatic.CreateState(problemData, (uint)Seed, MaxVariableReferences, ScaleVariables, 
         ConstantOptimizationIterations, Lambda,
-        Policy, collectPareto,
+        collectPareto,
         lowerLimit, upperLimit,
         allowProdOfVars: AllowedFactors.CheckedItems.Any(s => s.Value.Value == VariableProductFactorName),
Index: /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/MctsSymbolicRegressionStatic.cs
===================================================================
--- /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/MctsSymbolicRegressionStatic.cs	(revision 15437)
+++ /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/MctsSymbolicRegressionStatic.cs	(revision 15438)
@@ -26,5 +26,4 @@
 using System.Linq;
 using System.Text;
-using HeuristicLab.Algorithms.DataAnalysis.MctsSymbolicRegression.Policies;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
@@ -99,5 +98,4 @@
       internal readonly Tree tree;
       internal readonly Func<byte[], int, double> evalFun;
-      internal readonly IPolicy treePolicy;
       // MCTS might get stuck. Track statistics on the number of effective rollouts
       internal int totalRollouts;
@@ -145,5 +143,4 @@
       public State(IRegressionProblemData problemData, uint randSeed, int maxVariables, bool scaleVariables,
         int constOptIterations, double lambda,
-        IPolicy treePolicy = null,
         bool collectParetoOptimalModels = false,
         double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue,
@@ -187,9 +184,7 @@
         this.testEvaluator = new ExpressionEvaluator(testY.Length, lowerEstimationLimit, upperEstimationLimit);
 
-        this.automaton = new Automaton(x, new SimpleConstraintHandler(maxVariables), allowProdOfVars, allowExp, allowLog, allowInv, allowMultipleTerms);
-        this.treePolicy = treePolicy ?? new EpsilonGreedy();
+        this.automaton = new Automaton(x, allowProdOfVars, allowExp, allowLog, allowInv, allowMultipleTerms, maxVariables);
         this.tree = new Tree() {
           state = automaton.CurrentState,
-          actionStatistics = treePolicy.CreateActionStatistics(),
           expr = "",
           level = 0
@@ -469,5 +464,4 @@
     public static IState CreateState(IRegressionProblemData problemData, uint randSeed, int maxVariables = 3,
       bool scaleVariables = true, int constOptIterations = -1, double lambda = 0.0,
-      IPolicy policy = null,
       bool collectParameterOptimalModels = false,
       double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue,
@@ -479,5 +473,5 @@
       ) {
       return new State(problemData, randSeed, maxVariables, scaleVariables, constOptIterations, lambda,
-        policy, collectParameterOptimalModels,
+        collectParameterOptimalModels,
         lowerEstimationLimit, upperEstimationLimit,
         allowProdOfVars, allowExp, allowLog, allowInv, allowMultipleTerms);
@@ -499,5 +493,4 @@
       var eval = mctsState.evalFun;
       var rand = mctsState.random;
-      var treePolicy = mctsState.treePolicy;
       double q = 0;
       bool success = false;
@@ -505,5 +498,5 @@
 
         automaton.Reset();
-        success = TryTreeSearchRec2(rand, tree, automaton, eval, treePolicy, mctsState, out q);
+        success = TryTreeSearchRec2(rand, tree, automaton, eval, mctsState, out q);
         mctsState.totalRollouts++;
       } while (!success && !tree.Done);
@@ -517,5 +510,6 @@
 
     // search forward
-    private static bool TryTreeSearchRec2(IRandom rand, Tree tree, Automaton automaton, Func<byte[], int, double> eval, IPolicy treePolicy,
+    private static bool TryTreeSearchRec2(IRandom rand, Tree tree, Automaton automaton, 
+      Func<byte[], int, double> eval,
       State state,
       out double q) {
@@ -545,5 +539,5 @@
           int selectedIdx = 0;
           if (state.children[tree].Count > 1) {
-            selectedIdx = treePolicy.Select(state.children[tree].Select(ch => ch.actionStatistics), rand);
+            selectedIdx = SelectInternal(state.children[tree], rand);
           }
 
@@ -579,7 +573,5 @@
               if (!state.nodes.TryGetValue(hc, out child)) {
                 child = new Tree() {
-                  children = null,
                   state = possibleFollowStates[i],
-                  actionStatistics = treePolicy.CreateActionStatistics(),
                   expr = actionString + automaton.GetActionString(automaton.CurrentState, possibleFollowStates[i]),
                   level = tree.level + 1
@@ -591,5 +583,5 @@
                 // whenever we join paths we need to propagate back the statistics of the existing node through the newly created link
                 // to all parents 
-                BackpropagateStatistics(child.actionStatistics, tree, state);
+                BackpropagateStatistics(tree, state, child.visits);
               } else {
                 // prevent cycles
@@ -599,7 +591,5 @@
             } else {
               child = new Tree() {
-                children = null,
                 state = possibleFollowStates[i],
-                actionStatistics = treePolicy.CreateActionStatistics(),
                 expr = actionString + automaton.GetActionString(automaton.CurrentState, possibleFollowStates[i]),
                 level = tree.level + 1
@@ -639,10 +629,8 @@
         automaton.GetCode(out code, out nParams);
         q = eval(code, nParams);
-        // Console.WriteLine("{0:N4}\t{1}", q*q, tree.expr);
         success = true;
-        BackpropagateQuality(tree, q, treePolicy, state);
+        BackpropagateQuality(tree, q, state); 
       } else {
         // we got stuck in roll-out (not evaluation necessary!)
-        // Console.WriteLine("\t" + ExprStr(automaton) + " STOP");
         q = 0.0;
         success = false;
@@ -659,10 +647,20 @@
     }
 
+    private static int SelectInternal(List<Tree> list, IRandom rand) {
+      // choose a random node.
+      Debug.Assert(list.Any(t => !t.Done));
+
+      var idx = rand.Next(list.Count);
+      while(list[idx].Done) { idx = rand.Next(list.Count); }
+      return idx;
+    }
+
     // backpropagate existing statistics to all parents
-    private static void BackpropagateStatistics(IActionStatistics stats, Tree tree, State state) {
-      tree.actionStatistics.Add(stats);
+    private static void BackpropagateStatistics(Tree tree, State state, int numVisits) {
+      tree.visits += numVisits;
+
       if (state.parents.ContainsKey(tree)) {
         foreach (var parent in state.parents[tree]) {
-          BackpropagateStatistics(stats, parent, state);
+          BackpropagateStatistics(parent, state, numVisits);
         }
       }
@@ -676,10 +674,11 @@
     }
 
-    private static void BackpropagateQuality(Tree tree, double q, IPolicy policy, State state) {
-      policy.Update(tree.actionStatistics, q);
+    private static void BackpropagateQuality(Tree tree, double q, State state) {
+      tree.visits++;
+      // TODO: q is ignored for now
 
       if (state.parents.ContainsKey(tree)) {
         foreach (var parent in state.parents[tree]) {
-          BackpropagateQuality(parent, q, policy, state);
+          BackpropagateQuality(parent, q, state);
         }
       }
@@ -718,89 +717,5 @@
       }
       return children[selectedChildIdx];
-    }
-
-    // tree search might fail because of constraints for expressions
-    // in this case we get stuck we just restart
-    // see ConstraintHandler.cs for more info
-    private static bool TryTreeSearchRec(IRandom rand, Tree tree, Automaton automaton, Func<byte[], int, double> eval, IPolicy treePolicy,
-      out double q) {
-      Tree selectedChild = null;
-      Contract.Assert(tree.state == automaton.CurrentState);
-      Contract.Assert(!tree.Done);
-      if (tree.children == null) {
-        if (automaton.IsFinalState(tree.state)) {
-          // final state
-          tree.Done = true;
-
-          // EVALUATE
-          byte[] code; int nParams;
-          automaton.GetCode(out code, out nParams);
-          q = eval(code, nParams);
-
-          treePolicy.Update(tree.actionStatistics, q);
-          return true; // we reached a final state
-        } else {
-          // EXPAND 
-          int[] possibleFollowStates = new int[1000];
-          int nFs;
-          automaton.FollowStates(automaton.CurrentState, ref possibleFollowStates, out nFs);
-          if (nFs == 0) {
-            // stuck in a dead end (no final state and no allowed follow states)
-            q = 0;
-            tree.Done = true;
-            tree.children = null;
-            return false;
-          }
-          tree.children = new Tree[nFs];
-          for (int i = 0; i < tree.children.Length; i++)
-            tree.children[i] = new Tree() {
-              children = null,
-              state = possibleFollowStates[i],
-              actionStatistics = treePolicy.CreateActionStatistics()
-            };
-
-          selectedChild = nFs > 1 ? SelectFinalOrRandom(automaton, tree, rand) : tree.children[0];
-        }
-      } else {
-        // tree.children != null
-        // UCT selection within tree
-        int selectedIdx = 0;
-        if (tree.children.Length > 1) {
-          selectedIdx = treePolicy.Select(tree.children.Select(ch => ch.actionStatistics), rand);
-        }
-        selectedChild = tree.children[selectedIdx];
-      }
-      // make selected step and recurse
-      automaton.Goto(selectedChild.state);
-      var success = TryTreeSearchRec(rand, selectedChild, automaton, eval, treePolicy, out q);
-      if (success) {
-        // only update if successful
-        treePolicy.Update(tree.actionStatistics, q);
-      }
-
-      tree.Done = tree.children.All(ch => ch.Done);
-      if (tree.Done) {
-        tree.children = null; // cut off the sub-branch if it has been fully explored
-      }
-      return success;
-    }
-
-    private static Tree SelectFinalOrRandom(Automaton automaton, Tree tree, IRandom rand) {
-      // if one of the new children leads to a final state then go there
-      // otherwise choose a random child
-      int selectedChildIdx = -1;
-      // find first final state if there is one
-      for (int i = 0; i < tree.children.Length; i++) {
-        if (automaton.IsFinalState(tree.children[i].state)) {
-          selectedChildIdx = i;
-          break;
-        }
-      }
-      // no final state -> select a the first child
-      if (selectedChildIdx == -1) {
-        selectedChildIdx = 0;
-      }
-      return tree.children[selectedChildIdx];
-    }
+    }                                            
 
     // scales data and extracts values from dataset into arrays
@@ -869,17 +784,4 @@
       automaton.GetCode(out code, out nParams);
       return Disassembler.CodeToString(code);
-    }
-
-
-    private static string WriteStatistics(Tree tree, State state) {
-      var sb = new System.IO.StringWriter();
-      sb.Write("{0}\t{1:N5}\t", tree.actionStatistics.Tries, tree.actionStatistics.AverageQuality);
-      if (state.children.ContainsKey(tree)) {
-        foreach (var ch in state.children[tree]) {
-          sb.Write("{0}\t{1:N5}\t", ch.actionStatistics.Tries, ch.actionStatistics.AverageQuality);
-        }
-      }
-      sb.WriteLine();
-      return sb.ToString();
     }
 
@@ -899,11 +801,7 @@
 
     private static void TraceTreeRec(Tree tree, int parentId, StringBuilder sb, ref int nextId, State state) {
-      var avgNodeQ = tree.actionStatistics.AverageQuality;
-      var tries = tree.actionStatistics.Tries;
-      if (double.IsNaN(avgNodeQ)) avgNodeQ = 0.0;
-      var hue = (1 - avgNodeQ) / 360.0 * 240.0; // 0 equals red, 240 equals blue
-      hue = 0.0;
-
-      sb.AppendFormat("{0} [label=\"{1:E3} {2}\" color=\"{3:N3} 0.999 0.999\"]; ", parentId, avgNodeQ, tries, hue).AppendLine();
+      var tries = tree.visits;
+
+      sb.AppendFormat("{0} [label=\"{1}\"]; ", parentId, tries).AppendLine();
 
       var list = new List<Tuple<int, int, Tree>>();
@@ -911,11 +809,7 @@
         foreach (var ch in state.children[tree]) {
           nextId++;
-          avgNodeQ = ch.actionStatistics.AverageQuality;
-          tries = ch.actionStatistics.Tries;
-          if (double.IsNaN(avgNodeQ)) avgNodeQ = 0.0;
-          hue = (1 - avgNodeQ) / 360.0 * 240.0; // 0 equals red, 240 equals blue
-          hue = 0.0;
-          sb.AppendFormat("{0} [label=\"{1:E3} {2}\" color=\"{3:N3} 0.999 0.999\"]; ", nextId, avgNodeQ, tries, hue).AppendLine();
-          sb.AppendFormat("{0} -> {1} [label=\"{3}\"]", parentId, nextId, avgNodeQ, ch.expr).AppendLine();
+          tries = ch.visits;
+          sb.AppendFormat("{0} [label=\"{1}\"]; ", nextId, tries).AppendLine();
+          sb.AppendFormat("{0} -> {1} [label=\"{2}\"]", parentId, nextId, ch.expr).AppendLine();
           list.Add(Tuple.Create(tries, nextId, ch));
         }
@@ -927,11 +821,7 @@
             var chch = state.children[ch].First();
             nextId++;
-            avgNodeQ = chch.actionStatistics.AverageQuality;
-            tries = chch.actionStatistics.Tries;
-            if (double.IsNaN(avgNodeQ)) avgNodeQ = 0.0;
-            hue = (1 - avgNodeQ) / 360.0 * 240.0; // 0 equals red, 240 equals blue
-            hue = 0.0;
-            sb.AppendFormat("{0} [label=\"{1:E3} {2}\" color=\"{3:N3} 0.999 0.999\"]; ", nextId, avgNodeQ, tries, hue).AppendLine();
-            sb.AppendFormat("{0} -> {1} [label=\"{3}\"]", chId, nextId, avgNodeQ, chch.expr).AppendLine();
+            tries = chch.visits;
+            sb.AppendFormat("{0} [label=\"{1}\"]; ", nextId, tries).AppendLine();
+            sb.AppendFormat("{0} -> {1} [label=\"{2}\"]", chId, nextId, chch.expr).AppendLine();
           }
         }
@@ -957,11 +847,7 @@
         if (!nodeIds.TryGetValue(parent, out parentId)) {
           parentId = nodeIds.Count + 1;
-          var avgNodeQ = parent.actionStatistics.AverageQuality;
-          var tries = parent.actionStatistics.Tries;
-          if (double.IsNaN(avgNodeQ)) avgNodeQ = 0.0;
-          var hue = (1 - avgNodeQ) / 360.0 * 240.0; // 0 equals red, 240 equals blue
-          hue = 0.0;
-          if (parent.actionStatistics.Tries > threshold)
-            sb.Write("{0} [label=\"{1:E3} {2}\" color=\"{3:N3} 0.999 0.999\"]; ", parentId, avgNodeQ, tries, hue);
+          var tries = parent.visits;
+          if (tries > threshold)
+            sb.Write("{0} [label=\"{1}\"]; ", parentId, tries);
           nodeIds.Add(parent, parentId);
         }
@@ -972,15 +858,11 @@
             nodeIds.Add(child, childId);
           }
-          var avgNodeQ = child.actionStatistics.AverageQuality;
-          var tries = child.actionStatistics.Tries;
+          var tries = child.visits;
           if (tries < 1) continue;
-          if (double.IsNaN(avgNodeQ)) avgNodeQ = 0.0;
-          var hue = (1 - avgNodeQ) / 360.0 * 240.0; // 0 equals red, 240 equals blue
-          hue = 0.0;
           if (tries > threshold) {
-            sb.Write("{0} [label=\"{1:E3} {2}\" color=\"{3:N3} 0.999 0.999\"]; ", childId, avgNodeQ, tries, hue);
+            sb.Write("{0} [label=\"{1}\"]; ", childId, tries);
             var edgeLabel = child.expr;
             // if (parent.expr.Length > 0) edgeLabel = edgeLabel.Replace(parent.expr, "");
-            sb.Write("{0} -> {1} [label=\"{3}\"]", parentId, childId, avgNodeQ, edgeLabel);
+            sb.Write("{0} -> {1} [label=\"{2}\"]", parentId, childId, edgeLabel);
           }
         }
Index: anches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/SimpleConstraintHandler.cs
===================================================================
--- /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/SimpleConstraintHandler.cs	(revision 15437)
+++ 	(revision )
@@ -1,62 +1,0 @@
-﻿
-using HeuristicLab.Algorithms.DataAnalysis.MctsSymbolicRegression;
-
-namespace HeuristicLab.Algorithms.DataAnalysis.MctsSymbolicRegression {
-  // only counts the number of variable references
-  internal class SimpleConstraintHandler : IConstraintHandler {
-    private int maxVariables;
-    private int numVariables;
-
-    public bool IsInvalidExpression {
-      get {
-        return numVariables > maxVariables;
-      }
-    }
-
-    public SimpleConstraintHandler(int maxVars) {
-      this.maxVariables = maxVars;
-    }
-
-    public void AddVarToCurrentFactor(int state) {
-      numVariables++;
-    }
-
-    public void EndFactor() {
-      // ignore
-    }
-
-    public void EndTerm() {
-      // ignore
-    }
-
-    public bool IsAllowedFollowState(int currentState, int followState) {
-      return numVariables < maxVariables ||
-        // going to the final state is always allowed (smaller states are closer to the final state)
-        currentState > followState;
-        // (
-        // followState != Automaton.StateExpFactorStart &&
-        // followState != Automaton.StateFactorStart &&
-        // followState != Automaton.StateTermStart &&
-        // followState != Automaton.StateLogTStart &&
-        // followState != Automaton.StateLogTFStart &&
-        // followState != Automaton.StateInvTStart &&
-        // followState != Automaton.StateInvTFStart);
-    }
-
-    public void Reset() {
-      numVariables = 0;      
-    }
-
-    public void StartFactor(int state) {
-      // ignore
-    }
-
-    public void StartNewTermInPoly() {
-      // ignore
-    }
-
-    public void StartTerm() {
-      // ignore
-    }
-  }
-}
Index: /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/Tree.cs
===================================================================
--- /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/Tree.cs	(revision 15437)
+++ /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/Tree.cs	(revision 15438)
@@ -19,19 +19,18 @@
  */
 #endregion
-
-using HeuristicLab.Algorithms.DataAnalysis.MctsSymbolicRegression.Policies;
-
+                                                      
 namespace HeuristicLab.Algorithms.DataAnalysis.MctsSymbolicRegression {
-  // represents tree nodes for the search tree in MCTS
   internal class Tree {
     public int state;
     public int level;
     public string expr;
-    public bool Done {
-      get { return actionStatistics.Done; }
-      set { actionStatistics.Done = value; }
-    }
-    public IActionStatistics actionStatistics;
-    public Tree[] children;
+    public bool Done { get; set; }
+    public int visits;
+    //   {
+    //   get { return actionStatistics.Done; }
+    //   set { actionStatistics.Done = value; }
+    // }
+    // public IActionStatistics actionStatistics;
+    // public Tree[] children;
   }
 }
Index: /branches/MCTS-SymbReg-2796/Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/MctsSymbolicRegressionTest.cs
===================================================================
--- /branches/MCTS-SymbReg-2796/Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/MctsSymbolicRegressionTest.cs	(revision 15437)
+++ /branches/MCTS-SymbReg-2796/Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/MctsSymbolicRegressionTest.cs	(revision 15438)
@@ -3,5 +3,4 @@
 using System.Linq;
 using System.Threading;
-using HeuristicLab.Algorithms.DataAnalysis.MctsSymbolicRegression.Policies;
 using HeuristicLab.Algorithms.DataAnalysis.MCTSSymbReg;
 using HeuristicLab.Data;
@@ -260,6 +259,6 @@
           }
 
-          Assert.IsTrue(Heuristics.CorrelationForInteraction(a, b, c, z) > 0.05);
-          Assert.IsTrue(Heuristics.CorrelationForInteraction(x, y, z, z) < 0.05);
+          Assert.IsTrue(Heuristics.CorrelationForInteraction(a, b, c, t) > 0.05);
+          Assert.IsTrue(Heuristics.CorrelationForInteraction(x, y, z, t) < 0.05);
 
           /* we might see correlations when only using one of the two relevant factors.
@@ -271,14 +270,99 @@
           Assert.IsTrue(Heuristics.CorrelationForInteraction(b, y, z) < 0.05);
           */
-          Console.WriteLine("a,b: {0:N3}\tx,y: {1:N3}\ta,x: {2:N3}\tb,x: {3:N3}\ta,y: {4:N3}\tb,y: {5:N3}\tcov(a,b): {6:N3}",
-            Heuristics.CorrelationForInteraction(a, b, z),
-            Heuristics.CorrelationForInteraction(x, y, z),
-            Heuristics.CorrelationForInteraction(a, x, z),
-            Heuristics.CorrelationForInteraction(b, x, z),
-            Heuristics.CorrelationForInteraction(a, y, z),
-            Heuristics.CorrelationForInteraction(b, y, z),
-            alglib.cov2(a, b)
+          Console.WriteLine("a,b,c: {0:N3}\tx,y,z: {1:N3}\ta,b,x: {2:N3}\tb,c,x: {3:N3}",
+            Heuristics.CorrelationForInteraction(a, b, c, t),
+            Heuristics.CorrelationForInteraction(x, y, z, t),
+            Heuristics.CorrelationForInteraction(a, b, x, t),
+            Heuristics.CorrelationForInteraction(b, c, x, t)
             );
         }
+      }
+    }
+
+    [TestMethod]
+    [TestCategory("Algorithms.DataAnalysis")]
+    [TestProperty("Time", "short")]
+    public void TestPoly10Interactions() {
+      {
+        alglib.hqrndstate randState;
+        alglib.hqrndseed(1234, 31415, out randState);
+
+        int N = 25000; // large sample size to make sure the test thresholds hold
+        double[] a = new double[N];
+        double[] b = new double[N];
+        double[] c = new double[N];
+        double[] d = new double[N];
+        double[] e = new double[N];
+        double[] f = new double[N];
+        double[] g = new double[N];
+        double[] h = new double[N];
+        double[] i = new double[N];
+        double[] j = new double[N];
+        double[] y = new double[N];
+
+        for(int k=0;k<N;k++) {
+          a[k] = alglib.hqrnduniformr(randState) * 2 - 1;
+          b[k] = alglib.hqrnduniformr(randState) * 2 - 1;
+          c[k] = alglib.hqrnduniformr(randState) * 2 - 1;
+          d[k] = alglib.hqrnduniformr(randState) * 2 - 1;
+          e[k] = alglib.hqrnduniformr(randState) * 2 - 1;
+          f[k] = alglib.hqrnduniformr(randState) * 2 - 1;
+          g[k] = alglib.hqrnduniformr(randState) * 2 - 1;
+          h[k] = alglib.hqrnduniformr(randState) * 2 - 1;
+          i[k] = alglib.hqrnduniformr(randState) * 2 - 1;
+          j[k] = alglib.hqrnduniformr(randState) * 2 - 1;
+          y[k] = a[k] * b[k] + c[k] * d[k] + e[k] * f[k] + a[k] * g[k] * i[k] + c[k] * f[k] * j[k];
+        }
+
+        var x = new[] { a, b, c, d, e, f, g, h, i, j };
+        var all2Combinations = HeuristicLab.Common.EnumerableExtensions.Combinations(new[] {1,2,3,4,5,6,7,8,9,10}, 2);
+
+        var resultList = new List<Tuple<string, double>>();
+        foreach(var entry in all2Combinations) {
+          var aIdx = entry.First();
+          var bIdx = entry.Skip(1).First();
+          resultList.Add(Tuple.Create(aIdx + " " + bIdx, Heuristics.CorrelationForInteraction(x[aIdx - 1], x[bIdx - 1], y)));
+        }
+
+        foreach(var entry in resultList.OrderByDescending(t => t.Item2)) {
+          Console.WriteLine("{0} {1:N3}", entry.Item1, entry.Item2);
+        }
+
+        var all3Combinations = HeuristicLab.Common.EnumerableExtensions.Combinations(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 3);
+
+        resultList = new List<Tuple<string, double>>();
+        foreach (var entry in all3Combinations) {
+          var aIdx = entry.First();
+          var bIdx = entry.Skip(1).First();
+          var cIdx = entry.Skip(2).First();
+          resultList.Add(Tuple.Create(aIdx + " " + bIdx + " " + cIdx, Heuristics.CorrelationForInteraction(x[aIdx - 1], x[bIdx - 1], x[cIdx - 1], y)));
+        }
+
+        //  Y = X1*X2 + X3*X4 + X5*X6 + X1*X7*X9 + X3*X6*X10
+
+        foreach (var entry in resultList.OrderByDescending(t => t.Item2)) {
+          Console.WriteLine("{0} {1:N3}", entry.Item1, entry.Item2);
+        }
+
+
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(a, b, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(b, a, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(c, d, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(d, c, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(e, f, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(f, e, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(a, g, i, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(a, i, g, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(g, a, i, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(g, i, a, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(i, g, a, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(i, a, g, y) > 0.01);
+
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(c, f, j, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(c, j, f, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(f, c, j, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(f, j, c, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(j, c, f, y) > 0.01);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(j, f, c, y) > 0.01);
       }
     }
