Index: branches/HeuristicLab.Problems.GrammaticalOptimization/Main/Main.csproj
===================================================================
--- branches/HeuristicLab.Problems.GrammaticalOptimization/Main/Main.csproj	(revision 11690)
+++ branches/HeuristicLab.Problems.GrammaticalOptimization/Main/Main.csproj	(revision 11727)
@@ -49,4 +49,8 @@
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Algorithms.Bandits\HeuristicLab.Algorithms.Bandits.csproj">
+      <Project>{24408F7D-EE0F-4886-A08B-EC324D662E47}</Project>
+      <Name>HeuristicLab.Algorithms.Bandits</Name>
+    </ProjectReference>
     <ProjectReference Include="..\HeuristicLab.Algorithms.GrammaticalOptimization\HeuristicLab.Algorithms.GrammaticalOptimization.csproj">
       <Project>{eea07488-1a51-412a-a52c-53b754a628b3}</Project>
Index: branches/HeuristicLab.Problems.GrammaticalOptimization/Main/Program.cs
===================================================================
--- branches/HeuristicLab.Problems.GrammaticalOptimization/Main/Program.cs	(revision 11690)
+++ branches/HeuristicLab.Problems.GrammaticalOptimization/Main/Program.cs	(revision 11727)
@@ -1,7 +1,10 @@
 ﻿using System;
 using System.Collections.Generic;
+using System.Data;
 using System.Diagnostics;
 using System.Linq;
 using System.Text;
+using System.Threading.Tasks;
+using HeuristicLab.Algorithms.Bandits;
 using HeuristicLab.Algorithms.GrammaticalOptimization;
 using HeuristicLab.Problems.GrammaticalOptimization;
@@ -10,4 +13,69 @@
   class Program {
     static void Main(string[] args) {
+      // RunDemo();
+      RunGridTest();
+    }
+
+    private static void RunGridTest() {
+      int maxIterations = 150000;
+      var globalRandom = new Random(31415);
+      var reps = 10;
+      Parallel.ForEach(new int[] { 1, 5, 10, 100, 500, 1000 }, (randomTries) => {
+        Random localRand;
+        lock (globalRandom) {
+          localRand = new Random(globalRandom.Next());
+        }
+        var policyFactories = new Func<int, IPolicy>[]
+        {
+          (numActions) => new RandomPolicy(localRand, numActions), 
+          (numActions) => new UCB1Policy(numActions), 
+          (numActions) => new UCB1TunedPolicy(numActions), 
+          (numActions) => new UCBNormalPolicy(numActions), 
+          (numActions) => new EpsGreedyPolicy(localRand, numActions, 0.01), 
+          (numActions) => new EpsGreedyPolicy(localRand, numActions, 0.05), 
+          (numActions) => new EpsGreedyPolicy(localRand, numActions, 0.1), 
+          (numActions) => new EpsGreedyPolicy(localRand, numActions, 0.2), 
+          (numActions) => new EpsGreedyPolicy(localRand, numActions, 0.5), 
+          (numActions) => new GaussianThompsonSamplingPolicy(localRand, numActions), 
+          (numActions) => new BernoulliThompsonSamplingPolicy(localRand, numActions)
+        };
+
+        foreach (var policyFactory in policyFactories)
+          for (int i = 0; i < reps; i++) {
+            int iterations = 0;
+            var sw = new Stopwatch();
+            var globalStatistics = new SentenceSetStatistics();
+
+            // var problem = new SymbolicRegressionPoly10Problem();
+            var problem = new SantaFeAntProblem();
+            //var problem = new PalindromeProblem();
+            //var problem = new HardPalindromeProblem();
+            //var problem = new RoyalPairProblem();
+            //var problem = new EvenParityProblem();
+            var alg = new MctsSampler(problem, 17, localRand, randomTries, policyFactory);
+            //var alg = new ExhaustiveBreadthFirstSearch(problem, 25);
+            //var alg = new AlternativesContextSampler(problem, 25);
+
+            alg.SolutionEvaluated += (sentence, quality) => {
+              iterations++;
+              globalStatistics.AddSentence(sentence, quality);
+              if (iterations % 10000 == 0) {
+                Console.WriteLine("{0} {1} {2}", randomTries, policyFactory(1), globalStatistics);
+              }
+            };
+
+            sw.Start();
+
+            alg.Run(maxIterations);
+
+            sw.Stop();
+          }
+      });
+    }
+
+    private static void RunDemo() {
+      // TODO: implement threshold ascent
+      // TODO: implement inspection for MCTS
+
       int maxIterations = 10000000;
       int iterations = 0;
@@ -15,16 +83,28 @@
       double bestQuality = 0;
       string bestSentence = "";
+      var globalStatistics = new SentenceSetStatistics();
+      var random = new Random(31415);
 
-      var rs = new ExhaustiveDepthFirstSearch(17);
+      // var problem = new SymbolicRegressionPoly10Problem();
+      var problem = new SantaFeAntProblem();
+      //var problem = new PalindromeProblem();
+      //var problem = new HardPalindromeProblem();
+      //var problem = new RoyalPairProblem();
+      //var problem = new EvenParityProblem();
+      var alg = new MctsSampler(problem, 17, random);
+      //var alg = new ExhaustiveBreadthFirstSearch(problem, 25);
+      //var alg = new AlternativesContextSampler(problem, 25);
 
-      rs.FoundNewBestSolution += (sentence, quality) => {
+      alg.FoundNewBestSolution += (sentence, quality) => {
         bestQuality = quality;
         bestSentence = sentence;
         Console.WriteLine("{0,10} {1,10:F5} {2,10:F5} {3}", iterations, bestQuality, quality, sentence);
       };
-      rs.SolutionEvaluated += (sentence, quality) => {
+      alg.SolutionEvaluated += (sentence, quality) => {
         iterations++;
+        globalStatistics.AddSentence(sentence, quality);
         if (iterations % 10000 == 0) {
-          Console.WriteLine("{0,10} {1,10:F5} {2,10:F5} {3}", iterations, bestQuality, quality, sentence);
+          //Console.WriteLine("{0,10} {1,10:F5} {2,10:F5} {3}", iterations, bestQuality, quality, sentence);
+          Console.WriteLine(globalStatistics.ToString());
         }
       };
@@ -33,5 +113,5 @@
       sw.Start();
 
-      rs.Run(new SymbolicRegressionPoly10Problem(), maxIterations);
+      alg.Run(maxIterations);
 
       sw.Stop();
