using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using HeuristicLab.Algorithms.Bandits; using HeuristicLab.Algorithms.Bandits.BanditPolicies; using HeuristicLab.Algorithms.Bandits.GrammarPolicies; using HeuristicLab.Algorithms.GrammaticalOptimization; using HeuristicLab.Problems.GrammaticalOptimization; // NOTES: gkronber // TODO: feature extraction for full symbolic expressions and experiment for all benchmark problems // TODO: why does GaussianThompsonSampling work so well with MCTS for the artificial ant problem? // TODO: research thompson sampling for max bandit? // TODO: verify TA implementation using example from the original paper // TODO: implement thompson sampling for gaussian mixture models // TODO: gleichzeitige modellierung von transformierter zielvariable (y, 1/y, log(y), exp(y), sqrt(y), ...) // TODO: vergleich bei complete-randomly möglichst kurze sätze generieren vs. einfach zufällig alternativen wählen // TODO: reward discounting (für veränderliche reward distributions über zeit). speziellen unit-test dafür erstellen // TODO: constant optimization using HeuristicLab.Problems.GrammaticalOptimization.SymbReg; using RandomPolicy = HeuristicLab.Algorithms.Bandits.GrammarPolicies.RandomPolicy; namespace Main { class Program { static void Main(string[] args) { CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; foreach (var banditPolicy in new IBanditPolicy[] { //new HeuristicLab.Algorithms.Bandits.BanditPolicies.RandomPolicy(), //new UCB1TunedPolicy(), //new UCB1Policy(), //new UCB1Policy(0.8), //new UCB1Policy(1), new UCB1Policy(0.5), //new ExtremeHunterPolicy(), //new ThresholdAscentPolicy(), //new BoltzmannExplorationPolicy(1), //new BoltzmannExplorationPolicy(0.5), //new BoltzmannExplorationPolicy(5), //new EpsGreedyPolicy(0.1), //new EpsGreedyPolicy(0.05), }) { var problem = new SymbolicRegressionPoly10Problem(500); var random = new Random(); //var problem = new SymbolicRegressionProblem(random, "Vladislavleva-1", useConstantOpt: true); //var problem = new PrimePolynomialProblem(); //var problem = new SantaFeAntProblem(); var policy = new GenericGrammarPolicy(problem, banditPolicy); // var policy = new GenericGrammarPolicy(problem, new UCB1Policy(0.5)); //var alg = new MonteCarloTreeSearch(problem, 23, random, new UCB1Policy(), new RandomSimulation(problem, random, 30)); RunDemo(problem, random, policy, banditPolicy.ToString()); } } private static void RunDemo(IProblem problem, Random random, GenericGrammarPolicy policy, string banditPolicyName) { for (int i = 0; i < 100; i++) { int iterations = 0; var globalStatistics = new SentenceSetStatistics(); var alg = new SequentialSearch(problem, 23, random, 0, policy); alg.FoundNewBestSolution += (sentence, quality) => { //Console.WriteLine("{0}", globalStatistics); }; alg.SolutionEvaluated += (sentence, quality) => { iterations++; globalStatistics.AddSentence(sentence, quality); //UpdateAlleleStatistics(sentence); // comment this if you don't want to see solver statistics if (iterations % 100 == 0) { if (iterations % 1000 == 0) { Console.Clear(); } Console.SetCursorPosition(0, 0); Console.WriteLine("{0} {1}", iterations, string.Join(" ", policy.OptimalPulls.Take(15).Select(p => string.Format("{0:F3}", p)))); //WriteAlleleStatistics(); Console.WriteLine(globalStatistics.BestSentenceQuality); Console.WriteLine(globalStatistics.BestSentence); Console.WriteLine(globalStatistics); alg.PrintStats(); //policy.PrintStats(); //ResetAlleleStatistics(); } // uncomment this if you want to collect statistics of the generated sentences //if (iterations % 1000 == 0) { // Console.WriteLine("{0} {1} {2}", banditPolicyName, string.Join(" ", policy.OptimalPulls.Take(15).Select(p => string.Format("{0:F3}", p))), globalStatistics); //} }; int maxIterations = 300000; // ResetAlleleStatistics(); //var problem = new SantaFeAntProblem(); //var problem = new RoyalPairProblem(10); //var problem = new FindPhrasesProblem(random, 10, 5, 3, 5, 5, 1.0, 0.9, true); //var problem = new PrimePolynomialProblem(); //var problem = new SymbolicRegressionProblem(random, "Tower"); // @"C:\reps\HeuristicLab\branches\HeuristicLab.Problems.GrammaticalOptimization\HeuristicLab.Problems.GrammaticalOptimization.SymbReg\nht-train.csv", // @"C:\reps\fhooe-new\research\Datasets\Benchmark\kommenda-1.csv", // 1.0, // true); // //var problem = new PrimePolynomialProblem(); // var alg = new SequentialSearch(problem, 25, random, 0, //var policy = new HeuristicLab.Algorithms.Bandits.GrammarPolicies.GenericGrammarPolicy(problem, new UCB1TunedPolicy()); //var policy = new GenericPolicy(problem); //var policy = new GenericGrammarPolicy(problem, new ExtremeHunterPolicy()); //var policy = new GenericGrammarPolicy(problem, new UCB1Policy(0.5)); //var policy = new GenericGrammarPolicy(problem, new ActiveLearningPolicy(3)); //var policy = new GenericGrammarPolicy(problem, new IntervalEstimationPolicy()); //var policy = new GenericGrammarPolicy(problem, new ChernoffIntervalEstimationPolicy()); //var policy = new GenericGrammarPolicy(problem, new EpsGreedyPolicy(0.1)); //var policy = new GenericGrammarPolicy(problem, new ExtremeHunterPolicy(0.001, 0.001, 1, 100000, minPulls: 100)); //var policy = new GenericGrammarPolicy(problem, new ThresholdAscentPolicy(s: 1000, delta: 1)); //var policy = new GenericGrammarPolicy(problem, new HeuristicLab.Algorithms.Bandits.BanditPolicies.UCB1TunedPolicy()); //var policy = new GenericGrammarPolicy(problem, new HeuristicLab.Algorithms.Bandits.BanditPolicies.BoltzmannExplorationPolicy(1)); //var policy = new GenericGrammarPolicy(problem, new HeuristicLab.Algorithms.Bandits.BanditPolicies.ThresholdAscentPolicy(500, 0.01)); // santa fe ant //var policy = new GenericGrammarPolicy(problem, new HeuristicLab.Algorithms.Bandits.BanditPolicies.BoltzmannExplorationWithCoolingPolicy(0.01)); var sw = new Stopwatch(); sw.Start(); alg.Run(maxIterations); sw.Stop(); //Console.WriteLine(globalStatistics); // //Console.WriteLine("{0:F2} sec {1,10:F1} sols/sec {2,10:F1} ns/sol", // sw.Elapsed.TotalSeconds, // maxIterations / (double)sw.Elapsed.TotalSeconds, // (double)sw.ElapsedMilliseconds * 1000 / maxIterations); } } private static void UpdateAlleleStatistics(string sentence) { for (int i = 0; i < sentence.Length; i++) { var allele = sentence.Substring(i, 1); if (alleleStatistics.ContainsKey(allele)) alleleStatistics[allele]++; } for (int i = 0; i < sentence.Length - 2; i += 2) { var allele = sentence.Substring(i, 3); if (alleleStatistics.ContainsKey(allele)) alleleStatistics[allele]++; } for (int i = 0; i < sentence.Length - 4; i += 2) { var allele = sentence.Substring(i, 5); if (alleleStatistics.ContainsKey(allele)) alleleStatistics[allele]++; } } private static Dictionary alleleStatistics; private static void ResetAlleleStatistics() { alleleStatistics = new Dictionary() { {"a", 0}, {"b", 0}, {"c", 0}, {"d", 0}, {"e", 0}, {"f", 0}, {"g", 0}, {"h", 0}, {"i", 0}, {"j", 0}, {"a*b", 0}, {"b*a", 0}, {"c*d", 0}, {"d*c", 0}, {"e*f", 0}, {"f*e", 0}, {"a*g*i", 0}, {"a*i*g", 0}, {"g*a*i", 0}, {"g*i*a", 0}, {"i*g*a", 0}, {"i*a*g", 0}, {"j*c*f", 0}, {"j*f*c", 0}, {"c*j*f", 0}, {"c*f*j", 0}, {"f*c*j", 0}, {"f*j*c", 0} }; } private static void WriteAlleleStatistics() { double count = alleleStatistics.Sum(e => e.Value); foreach (var entry in alleleStatistics.OrderByDescending(e => e.Value)) { Console.WriteLine("{0,-10} {1,-10}", entry.Key, entry.Value); } } } }