using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; using HeuristicLab.Problems.DataAnalysis; using HeuristicLab.Problems.DataAnalysis.Symbolic; using HeuristicLab.Problems.DataAnalysis.Symbolic.ConstantsOptimization; using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression; using HeuristicLab.Problems.Instances.DataAnalysis; using HeuristicLab.Random; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace UnitTests { [TestClass] public class PerformanceTest { private static readonly int seed = 1234; private static readonly int totalRows = 1000; private static readonly int maxIterations = 10; private static readonly int repetitions = 5; private static readonly int maxTreeSize = 50; [TestMethod] [TestCategory("Problems.DataAnalysis.Symbolic.Regression")] [TestProperty("Time", "long")] public static void New_ConstantsOptimization_Tower_Algorithm() { var twister = new MersenneTwister((uint)seed); var problemData = new RegressionRealWorldInstanceProvider().LoadData(new Tower()); var rows = Enumerable.Range(0, totalRows); var grammar = new TypeCoherentExpressionGrammar(); grammar.ConfigureAsDefaultRegressionGrammar(); var trees = CreateRandomTrees(twister, problemData.Dataset, grammar, 1000, 1, maxTreeSize, 0, 0); foreach (SymbolicExpressionTree tree in trees) { InitTree(tree, twister, problemData.AllowedInputVariables.ToList()); } Console.WriteLine("Random tree constants optimization performance of new method:"); //warm up for (int i = 0; i < trees.Length; i++) { if (!trees[i].IterateNodesPrefix().OfType().Any()) Debugger.Break(); double quality = LMConstantsOptimizer.OptimizeConstants(trees[i], problemData.Dataset,problemData.TargetVariable, rows, true, maxIterations); } Stopwatch watch = new Stopwatch(); for (int rep = 0; rep < repetitions; rep++) { watch.Start(); for (int i = 0; i < trees.Length; i++) { double quality = LMConstantsOptimizer.OptimizeConstants(trees[i], problemData.Dataset, problemData.TargetVariable, rows, true, maxIterations); } watch.Stop(); Console.WriteLine("Iteration " + rep + "\t\t" + " Elapsed time: \t" + watch.ElapsedMilliseconds + " ms \t\t" + "Time per tree: " + watch.ElapsedMilliseconds / 1000.0 / trees.Length); watch.Reset(); } } [TestMethod] [TestCategory("Problems.DataAnalysis.Symbolic.Regression")] [TestProperty("Time", "long")] public void Old_ConstantsOptimization_Tower_Algorithm() { var twister = new MersenneTwister((uint)seed); var problemData = new RegressionRealWorldInstanceProvider().LoadData(new Tower()); var rows = Enumerable.Range(0, totalRows); var grammar = new TypeCoherentExpressionGrammar(); grammar.ConfigureAsDefaultRegressionGrammar(); var trees = CreateRandomTrees(twister, problemData.Dataset, grammar, 1000, 1, maxTreeSize, 0, 0); foreach (SymbolicExpressionTree tree in trees) { InitTree(tree, twister, problemData.AllowedInputVariables.ToList()); } Console.WriteLine("Random tree constants optimization performance of existing method:"); var interpreter = new SymbolicDataAnalysisExpressionTreeLinearInterpreter(); //warm up for (int i = 0; i < trees.Length; i++) { if (!trees[i].IterateNodesPrefix().OfType().Any()) Debugger.Break(); double quality = SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants( interpreter, trees[i], problemData, rows, true, maxIterations); } Stopwatch watch = new Stopwatch(); for (int rep = 0; rep < repetitions; rep++) { watch.Start(); for (int i = 0; i < trees.Length; i++) { double quality = SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants( interpreter, trees[i], problemData, rows, true, maxIterations); } watch.Stop(); Console.WriteLine("Iteration " + rep + "\t\t" + " Elapsed time: \t" + watch.ElapsedMilliseconds + " ms \t\t" + "Time per tree: " + watch.ElapsedMilliseconds / 1000.0 / trees.Length); watch.Reset(); } } public static ISymbolicExpressionTree[] CreateRandomTrees(MersenneTwister twister, IDataset dataset, ISymbolicExpressionGrammar grammar, int popSize) { return CreateRandomTrees(twister, dataset, grammar, popSize, 1, 200, 3, 3); } public static ISymbolicExpressionTree[] CreateRandomTrees(MersenneTwister twister, IDataset dataset, ISymbolicExpressionGrammar grammar, int popSize, int minSize, int maxSize, int maxFunctionDefinitions, int maxFunctionArguments) { foreach (Variable variableSymbol in grammar.Symbols.OfType()) { variableSymbol.VariableNames = dataset.VariableNames; } ISymbolicExpressionTree[] randomTrees = new ISymbolicExpressionTree[popSize]; for (int i = 0; i < randomTrees.Length; i++) { randomTrees[i] = ProbabilisticTreeCreator.Create(twister, grammar, maxSize, 10); } return randomTrees; } public static void InitTree(ISymbolicExpressionTree tree, MersenneTwister twister, List varNames) { foreach (var node in tree.IterateNodesPostfix()) { if (node is VariableTreeNode) { var varNode = node as VariableTreeNode; varNode.Weight = twister.NextDouble() * 20.0 - 10.0; varNode.VariableName = varNames[twister.Next(varNames.Count)]; } else if (node is ConstantTreeNode) { var constantNode = node as ConstantTreeNode; constantNode.Value = twister.NextDouble() * 20.0 - 10.0; } } } } }