Exemple #1
0
        private static ISymbolicRegressionSolution CreateSymbolicSolution(List <IRegressionModel> models, double nu, IRegressionProblemData problemData)
        {
            var symbModels   = models.OfType <ISymbolicRegressionModel>();
            var lowerLimit   = symbModels.Min(m => m.LowerEstimationLimit);
            var upperLimit   = symbModels.Max(m => m.UpperEstimationLimit);
            var interpreter  = new SymbolicDataAnalysisExpressionTreeLinearInterpreter();
            var progRootNode = new ProgramRootSymbol().CreateTreeNode();
            var startNode    = new StartSymbol().CreateTreeNode();

            var addNode   = new Addition().CreateTreeNode();
            var mulNode   = new Multiplication().CreateTreeNode();
            var scaleNode = (ConstantTreeNode) new Constant().CreateTreeNode(); // all models are scaled using the same nu

            scaleNode.Value = nu;

            foreach (var m in symbModels)
            {
                var relevantPart = m.SymbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0); // skip root and start
                addNode.AddSubtree((ISymbolicExpressionTreeNode)relevantPart.Clone());
            }

            mulNode.AddSubtree(addNode);
            mulNode.AddSubtree(scaleNode);
            startNode.AddSubtree(mulNode);
            progRootNode.AddSubtree(startNode);
            var t             = new SymbolicExpressionTree(progRootNode);
            var combinedModel = new SymbolicRegressionModel(problemData.TargetVariable, t, interpreter, lowerLimit, upperLimit);
            var sol           = new SymbolicRegressionSolution(combinedModel, problemData);

            return(sol);
        }
Exemple #2
0
        private void playButton_Click(object sender, EventArgs e)
        {
            playButton.Enabled = false;
            int rows    = Content.World.Rows;
            int columns = Content.World.Columns;
            SymbolicExpressionTree expression = Content.SymbolicExpressionTree;
            var nodeStack = new Stack <SymbolicExpressionTreeNode>();

            animationInterpreter = new AntInterpreter();
            animationInterpreter.MaxTimeSteps = Content.MaxTimeSteps.Value;
            animationInterpreter.Expression   = Content.SymbolicExpressionTree;
            animationInterpreter.World        = Content.World;

            DrawWorld();
            using (Graphics graphics = Graphics.FromImage(pictureBox.Image)) {
                float cellHeight = pictureBox.Height / (float)Content.World.Rows;
                float cellWidth  = pictureBox.Width / (float)Content.World.Columns;
                // draw initial ant
                int currentAntLocationColumn;
                int currentAntLocationRow;
                animationInterpreter.AntLocation(out currentAntLocationRow, out currentAntLocationColumn);
                DrawAnt(graphics, currentAntLocationRow, currentAntLocationColumn, animationInterpreter.AntDirection, cellWidth, cellHeight);
                pictureBox.Refresh();
            }

            animationTimer.Start();
        }
        protected static double CalculateReplacementValue(ISymbolicExpressionTreeNode node, ISymbolicExpressionTree sourceTree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
                                                          IDataset dataset, IEnumerable <int> rows)
        {
            //optimization: constant nodes return always the same value
            ConstantTreeNode constantNode = node as ConstantTreeNode;

            if (constantNode != null)
            {
                return(constantNode.Value);
            }

            var rootSymbol  = new ProgramRootSymbol().CreateTreeNode();
            var startSymbol = new StartSymbol().CreateTreeNode();

            rootSymbol.AddSubtree(startSymbol);
            startSymbol.AddSubtree((ISymbolicExpressionTreeNode)node.Clone());

            var tempTree = new SymbolicExpressionTree(rootSymbol);

            // clone ADFs of source tree
            for (int i = 1; i < sourceTree.Root.SubtreeCount; i++)
            {
                tempTree.Root.AddSubtree((ISymbolicExpressionTreeNode)sourceTree.Root.GetSubtree(i).Clone());
            }
            return(interpreter.GetSymbolicExpressionTreeValues(tempTree, dataset, rows).Median());
        }
Exemple #4
0
        public void ProbabilisticTreeCreatorSpecificTreeSizesTest()
        {
            var trees           = new List <ISymbolicExpressionTree>();
            var grammar         = Grammars.CreateSimpleArithmeticGrammar();
            var random          = new MersenneTwister(31415);
            var treeGrammarType = SymbolicExpressionTreeGrammar_Accessor.ShadowedType.ReferencedType;


            for (int targetTreeSize = 1; targetTreeSize <= 100; targetTreeSize++)
            {
                var tree     = new SymbolicExpressionTree();
                var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode();
                rootNode.SetGrammar((ISymbolicExpressionTreeGrammar)Activator.CreateInstance(treeGrammarType, grammar));
                if (rootNode.HasLocalParameters)
                {
                    rootNode.ResetLocalParameters(random);
                }
                var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();
                startNode.SetGrammar((ISymbolicExpressionTreeGrammar)Activator.CreateInstance(treeGrammarType, grammar));
                if (startNode.HasLocalParameters)
                {
                    startNode.ResetLocalParameters(random);
                }
                rootNode.AddSubtree(startNode);

                ProbabilisticTreeCreator_Accessor.TryCreateFullTreeFromSeed(random, startNode, targetTreeSize, ((int)Math.Log(targetTreeSize, 2)) + 1);
                tree.Root = rootNode;
                //mkommend: commented due to performance issues on the builder
                // Assert.AreEqual(targetTreeSize + 2, tree.Length);  //the root and start node must be additionally added
            }
        }
Exemple #5
0
        private void BuildAllowedChildSymbolsTree()
        {
            if (Symbol == null)
            {
                symbolicExpressionTreeChart.Tree = null;
                return;
            }

            var tree = new SymbolicExpressionTree(new SymbolicExpressionTreeNode(Symbol));

            if (Grammar.GetMaximumSubtreeCount(Symbol) > 0)
            {
                for (int i = 0; i < Grammar.GetMaximumSubtreeCount(Symbol); i++)
                {
                    var node         = new DummySymbol("Subtree " + i).CreateTreeNode();
                    var groupSymbols = grammar.GetAllowedChildSymbols(Symbol, i).OfType <GroupSymbol>().ToList();
                    foreach (var childSymbol in Grammar.GetAllowedChildSymbols(Symbol, i))
                    {
                        if (!groupSymbols.Any(g => g != childSymbol && g.Flatten().Contains(childSymbol)))
                        {
                            node.AddSubtree(new SymbolicExpressionTreeNode(childSymbol));
                        }
                    }
                    tree.Root.AddSubtree(node);
                }
            }
            symbolicExpressionTreeChart.Tree           = tree;
            symbolicExpressionTreeChart.SuspendRepaint = true;
            foreach (var subtreeNode in tree.Root.Subtrees)
            {
                foreach (var allowedChildNode in subtreeNode.Subtrees)
                {
                    var visualLine = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(subtreeNode, allowedChildNode);
                    visualLine.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                }
            }

            for (int i = Grammar.GetMinimumSubtreeCount(symbol); i < Grammar.GetMaximumSubtreeCount(symbol); i++)
            {
                var subtreeNode    = tree.Root.GetSubtree(i);
                var visualTreeNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(subtreeNode);
                visualTreeNode.TextColor = Color.Gray;
                visualTreeNode.LineColor = Color.LightGray;

                var visualLine = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(tree.Root, subtreeNode);
                visualLine.LineColor = Color.LightGray;

                foreach (var allowedChildNode in subtreeNode.Subtrees)
                {
                    visualTreeNode           = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(allowedChildNode);
                    visualTreeNode.TextColor = Color.Gray;
                    visualTreeNode.LineColor = Color.LightGray;

                    visualLine           = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(subtreeNode, allowedChildNode);
                    visualLine.LineColor = Color.LightGray;
                }
            }
            symbolicExpressionTreeChart.SuspendRepaint = false;
            UpdateSelectedSymbolicExpressionTreeNodes();
        }
Exemple #6
0
 private AntTrail(AntTrail original, Cloner cloner)
     : base(original, cloner)
 {
     expression   = cloner.Clone(original.expression);
     world        = cloner.Clone(original.world);
     maxTimeSteps = cloner.Clone(original.maxTimeSteps);
     Initialize();
 }
Exemple #7
0
 public AntTrail(BoolMatrix world, SymbolicExpressionTree expression, IntValue maxTimeSteps)
     : this()
 {
     this.world        = world;
     this.expression   = expression;
     this.maxTimeSteps = maxTimeSteps;
     Initialize();
 }
        public void AddItemToBuilder(IItem item, string name, SolutionMessage.Builder builder)
        {
            SymbolicExpressionTree tree = (item as SymbolicExpressionTree);

            if (tree != null)
            {
                ConvertSymbolicExpressionTree(tree, name, builder);
            }
        }
Exemple #9
0
        protected override void ConvertSymbolicExpressionTree(SymbolicExpressionTree tree, string name, SolutionMessage.Builder builder)
        {
            string stringRep = formatter.Format(tree);

            stringRep.Replace(Environment.NewLine, "");
            SolutionMessage.Types.StringVariable.Builder stringVariable = SolutionMessage.Types.StringVariable.CreateBuilder();
            stringVariable.SetName(name).SetData(stringRep);
            builder.AddStringVars(stringVariable.Build());
        }
Exemple #10
0
 protected override void ConvertSymbolicExpressionTree(SymbolicExpressionTree tree, string name, SolutionMessage.Builder builder)
 {
     using (MemoryStream memoryStream = new MemoryStream()) {
         Persistence.Default.Xml.XmlGenerator.Serialize(tree, memoryStream);
         byte[] byteRep = memoryStream.ToArray();
         SolutionMessage.Types.RawVariable.Builder rawVariable = SolutionMessage.Types.RawVariable.CreateBuilder();
         rawVariable.SetName(name).SetData(ByteString.CopyFrom(byteRep));
         builder.AddRawVars(rawVariable.Build());
     }
 }
        public static IClassificationSolution CreateLinearDiscriminantAnalysisSolution(IClassificationProblemData problemData)
        {
            var    dataset        = problemData.Dataset;
            string targetVariable = problemData.TargetVariable;
            IEnumerable <string> allowedInputVariables = problemData.AllowedInputVariables;
            IEnumerable <int>    rows = problemData.TrainingIndices;
            int nClasses = problemData.ClassNames.Count();

            double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables.Concat(new string[] { targetVariable }), rows);
            if (inputMatrix.Cast <double>().Any(x => double.IsNaN(x) || double.IsInfinity(x)))
            {
                throw new NotSupportedException("Linear discriminant analysis does not support NaN or infinity values in the input dataset.");
            }

            // change class values into class index
            int           targetVariableColumn = inputMatrix.GetLength(1) - 1;
            List <double> classValues          = problemData.ClassValues.OrderBy(x => x).ToList();

            for (int row = 0; row < inputMatrix.GetLength(0); row++)
            {
                inputMatrix[row, targetVariableColumn] = classValues.IndexOf(inputMatrix[row, targetVariableColumn]);
            }
            int info;

            double[] w;
            alglib.fisherlda(inputMatrix, inputMatrix.GetLength(0), allowedInputVariables.Count(), nClasses, out info, out w);
            if (info < 1)
            {
                throw new ArgumentException("Error in calculation of linear discriminant analysis solution");
            }

            ISymbolicExpressionTree     tree      = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
            ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();

            tree.Root.AddSubtree(startNode);
            ISymbolicExpressionTreeNode addition = new Addition().CreateTreeNode();

            startNode.AddSubtree(addition);

            int col = 0;

            foreach (string column in allowedInputVariables)
            {
                VariableTreeNode vNode = (VariableTreeNode) new HeuristicLab.Problems.DataAnalysis.Symbolic.Variable().CreateTreeNode();
                vNode.VariableName = column;
                vNode.Weight       = w[col];
                addition.AddSubtree(vNode);
                col++;
            }

            var model = LinearDiscriminantAnalysis.CreateDiscriminantFunctionModel(tree, new SymbolicDataAnalysisExpressionTreeInterpreter(), problemData, rows);
            SymbolicDiscriminantFunctionClassificationSolution solution = new SymbolicDiscriminantFunctionClassificationSolution(model, (IClassificationProblemData)problemData.Clone());

            return(solution);
        }
        public override IOperation Apply()
        {
            IEnumerable <int> rows = GenerateRowsToEvaluate();

            if (!rows.Any())
            {
                return(base.Apply());
            }

            double[] trainingQuality = QualityParameter.ActualValue.Select(x => x.Value).ToArray();
            var      problemData     = ProblemDataParameter.ActualValue;
            var      evaluator       = EvaluatorParameter.ActualValue;
            // evaluate on validation partition
            IExecutionContext childContext = (IExecutionContext)ExecutionContext.CreateChildOperation(evaluator);

            double[] validationQuality = SymbolicExpressionTree
                                         .Select(t => evaluator.Evaluate(childContext, t, problemData, rows))
                                         .ToArray();
            double r = 0.0;

            try {
                r = alglib.spearmancorr2(trainingQuality, validationQuality);
            }
            catch (alglib.alglibexception) {
                r = 0.0;
            }

            TrainingValidationQualityCorrelationParameter.ActualValue = new DoubleValue(r);

            if (TrainingValidationQualityCorrelationTableParameter.ActualValue == null)
            {
                var dataTable = new DataTable(TrainingValidationQualityCorrelationTableParameter.Name, TrainingValidationQualityCorrelationTableParameter.Description);
                dataTable.Rows.Add(new DataRow(TrainingValidationQualityCorrelationParameter.Name, TrainingValidationQualityCorrelationParameter.Description));
                dataTable.Rows[TrainingValidationQualityCorrelationParameter.Name].VisualProperties.StartIndexZero = true;
                TrainingValidationQualityCorrelationTableParameter.ActualValue = dataTable;
                ResultCollectionParameter.ActualValue.Add(new Result(TrainingValidationQualityCorrelationTableParameter.Name, dataTable));
            }

            TrainingValidationQualityCorrelationTableParameter.ActualValue.Rows[TrainingValidationQualityCorrelationParameter.Name].Values.Add(r);

            if (OverfittingParameter.ActualValue != null && OverfittingParameter.ActualValue.Value)
            {
                // overfitting == true
                // => r must reach the upper threshold to switch back to non-overfitting state
                OverfittingParameter.ActualValue = new BoolValue(r < UpperCorrelationThresholdParameter.ActualValue.Value);
            }
            else
            {
                // overfitting == false
                // => r must drop below lower threshold to switch to overfitting state
                OverfittingParameter.ActualValue = new BoolValue(r < LowerCorrelationThresholdParameter.ActualValue.Value);
            }

            return(base.Apply());
        }
 protected override void ConvertSymbolicExpressionTree(SymbolicExpressionTree tree, string name, SolutionMessage.Builder builder)
 {
     using (MemoryStream memoryStream = new MemoryStream()) {
         var ser = new ProtoBufSerializer();
         ser.Serialize(tree, memoryStream, disposeStream: false);
         memoryStream.Flush();
         byte[] byteRep = memoryStream.ToArray();
         SolutionMessage.Types.RawVariable.Builder rawVariable = SolutionMessage.Types.RawVariable.CreateBuilder();
         rawVariable.SetName(name).SetData(ByteString.CopyFrom(byteRep));
         builder.AddRawVars(rawVariable.Build());
     }
 }
        public InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView()
            : base()
        {
            InitializeComponent();
            this.Caption = "Interactive Time-Series Prognosis Solution Simplifier";

            constantNode = ((ConstantTreeNode) new Constant().CreateTreeNode());
            ISymbolicExpressionTreeNode root  = new ProgramRootSymbol().CreateTreeNode();
            ISymbolicExpressionTreeNode start = new StartSymbol().CreateTreeNode();

            root.AddSubtree(start);
            tempTree = new SymbolicExpressionTree(root);
        }
Exemple #15
0
        public override IOperation Apply()
        {
            #region find best tree
            double bestQuality = Maximization.Value ? double.NegativeInfinity : double.PositiveInfinity;
            ISymbolicExpressionTree   bestTree = null;
            ISymbolicExpressionTree[] tree     = SymbolicExpressionTree.ToArray();
            double[] quality = Quality.Select(x => x.Value).ToArray();
            for (int i = 0; i < tree.Length; i++)
            {
                if (IsBetter(quality[i], bestQuality, Maximization.Value))
                {
                    bestQuality = quality[i];
                    bestTree    = tree[i];
                }
            }
            #endregion

            var results = ResultCollection;
            if (bestTree != null && (UpdateAlways.Value || TrainingBestSolutionQuality == null ||
                                     IsBetter(bestQuality, TrainingBestSolutionQuality.Value, Maximization.Value)))
            {
                TrainingBestSolution        = CreateSolution(bestTree, bestQuality);
                TrainingBestSolutionQuality = new DoubleValue(bestQuality);
                if (IterationsParameter.ActualValue != null)
                {
                    TrainingBestSolutionGenerationParameter.ActualValue = new IntValue(IterationsParameter.ActualValue.Value);
                }

                if (!results.ContainsKey(TrainingBestSolutionParameter.Name))
                {
                    results.Add(new Result(TrainingBestSolutionParameter.Name, TrainingBestSolutionParameter.Description, TrainingBestSolution));
                    results.Add(new Result(TrainingBestSolutionQualityParameter.Name, TrainingBestSolutionQualityParameter.Description, TrainingBestSolutionQuality));
                    if (TrainingBestSolutionGenerationParameter.ActualValue != null)
                    {
                        results.Add(new Result(TrainingBestSolutionGenerationParameter.Name, TrainingBestSolutionGenerationParameter.Description, TrainingBestSolutionGenerationParameter.ActualValue));
                    }
                }
                else
                {
                    results[TrainingBestSolutionParameter.Name].Value        = TrainingBestSolution;
                    results[TrainingBestSolutionQualityParameter.Name].Value = TrainingBestSolutionQuality;
                    if (TrainingBestSolutionGenerationParameter.ActualValue != null)
                    {
                        results[TrainingBestSolutionGenerationParameter.Name].Value = TrainingBestSolutionGenerationParameter.ActualValue;
                    }
                }
            }
            return(base.Apply());
        }
        /// <summary>
        /// Maps a genotype (an integer vector) to a phenotype (a symbolic expression tree).
        /// Random approach.
        /// </summary>
        /// <param name="random">random number generator</param>
        /// <param name="bounds">only used for PIGEMapper (ignore here)</param>
        /// <param name="length">only used for PIGEMapper (ignore here)</param>
        /// <param name="grammar">grammar definition</param>
        /// <param name="genotype">integer vector, which should be mapped to a tree</param>
        /// <returns>phenotype (a symbolic expression tree)</returns>
        public override ISymbolicExpressionTree Map(IRandom random, IntMatrix bounds, int length,
                                                    ISymbolicExpressionGrammar grammar,
                                                    IntegerVector genotype)
        {
            SymbolicExpressionTree tree = new SymbolicExpressionTree();
            var rootNode  = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode();
            var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();

            rootNode.AddSubtree(startNode);
            tree.Root = rootNode;

            MapRandomIteratively(startNode, genotype, grammar,
                                 genotype.Length, random);

            return(tree);
        }
Exemple #17
0
        public sealed override IOperation InstrumentedApply()
        {
            SymbolicExpressionTree expression = SymbolicExpressionTreeParameter.ActualValue;
            BoolMatrix             world      = WorldParameter.ActualValue;
            IntValue maxTimeSteps             = MaxTimeStepsParameter.ActualValue;

            AntInterpreter interpreter = new AntInterpreter();

            interpreter.MaxTimeSteps = maxTimeSteps.Value;
            interpreter.World        = world;
            interpreter.Expression   = expression;
            interpreter.Run();

            QualityParameter.ActualValue = new DoubleValue(interpreter.FoodEaten);
            return(base.InstrumentedApply());
        }
Exemple #18
0
        public static ISymbolicExpressionTree CreateTree(
            IEnumerable <KeyValuePair <string, IEnumerable <string> > > factors, double[] factorCoefficients,
            string[] variableNames, double[] coefficients,
            double @const = 0)
        {
            if (factorCoefficients.Length == 0 && coefficients.Length == 0 && @const == 0)
            {
                throw new ArgumentException();
            }

            // Combine both trees
            ISymbolicExpressionTreeNode add = (new Addition()).CreateTreeNode();

            // Create tree for double variables
            if (coefficients.Length > 0)
            {
                var varTree = CreateTree(variableNames, new int[variableNames.Length], coefficients);
                foreach (var varNode in varTree.IterateNodesPrefix().OfType <VariableTreeNode>())
                {
                    add.AddSubtree(varNode);
                }
            }

            // Create tree for string variables
            if (factorCoefficients.Length > 0)
            {
                var factorTree = CreateTree(factors, factorCoefficients);
                foreach (var binFactorNode in factorTree.IterateNodesPrefix().OfType <BinaryFactorVariableTreeNode>())
                {
                    add.AddSubtree(binFactorNode);
                }
            }

            if (@const != 0.0)
            {
                ConstantTreeNode cNode = (ConstantTreeNode) new Constant().CreateTreeNode();
                cNode.Value = @const;
                add.AddSubtree(cNode);
            }

            ISymbolicExpressionTree     tree      = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
            ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();

            tree.Root.AddSubtree(startNode);
            startNode.AddSubtree(add);
            return(tree);
        }
Exemple #19
0
        public static ISymbolicExpressionTree CreateTree(string[] variableNames, int[] lags, double[] coefficients,
                                                         double @const = 0)
        {
            if (variableNames.Length == 0 ||
                variableNames.Length != coefficients.Length ||
                variableNames.Length != lags.Length)
            {
                throw new ArgumentException("The length of the variable names, lags, and coefficients vectors must match");
            }

            ISymbolicExpressionTree     tree      = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
            ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();

            tree.Root.AddSubtree(startNode);
            ISymbolicExpressionTreeNode addition = new Addition().CreateTreeNode();

            startNode.AddSubtree(addition);

            for (int i = 0; i < variableNames.Length; i++)
            {
                if (lags[i] == 0)
                {
                    VariableTreeNode vNode = (VariableTreeNode) new Variable().CreateTreeNode();
                    vNode.VariableName = variableNames[i];
                    vNode.Weight       = coefficients[i];
                    addition.AddSubtree(vNode);
                }
                else
                {
                    LaggedVariableTreeNode vNode = (LaggedVariableTreeNode) new LaggedVariable().CreateTreeNode();
                    vNode.VariableName = variableNames[i];
                    vNode.Weight       = coefficients[i];
                    vNode.Lag          = lags[i];
                    addition.AddSubtree(vNode);
                }
            }

            if ([email protected](0.0))
            {
                ConstantTreeNode cNode = (ConstantTreeNode) new Constant().CreateTreeNode();
                cNode.Value = @const;
                addition.AddSubtree(cNode);
            }
            return(tree);
        }
        protected IEnumerable <double> CalculateReplacementValues(ISymbolicExpressionTreeNode node, ISymbolicExpressionTree sourceTree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
                                                                  IDataset dataset, IEnumerable <int> rows)
        {
            //optimization: constant nodes return always the same value
            ConstantTreeNode             constantNode     = node as ConstantTreeNode;
            BinaryFactorVariableTreeNode binaryFactorNode = node as BinaryFactorVariableTreeNode;
            FactorVariableTreeNode       factorNode       = node as FactorVariableTreeNode;

            if (constantNode != null)
            {
                yield return(constantNode.Value);
            }
            else if (binaryFactorNode != null)
            {
                // valid replacements are either all off or all on
                yield return(0);

                yield return(1);
            }
            else if (factorNode != null)
            {
                foreach (var w in factorNode.Weights)
                {
                    yield return(w);
                }
                yield return(0.0);
            }
            else
            {
                var rootSymbol  = new ProgramRootSymbol().CreateTreeNode();
                var startSymbol = new StartSymbol().CreateTreeNode();
                rootSymbol.AddSubtree(startSymbol);
                startSymbol.AddSubtree((ISymbolicExpressionTreeNode)node.Clone());

                var tempTree = new SymbolicExpressionTree(rootSymbol);
                // clone ADFs of source tree
                for (int i = 1; i < sourceTree.Root.SubtreeCount; i++)
                {
                    tempTree.Root.AddSubtree((ISymbolicExpressionTreeNode)sourceTree.Root.GetSubtree(i).Clone());
                }
                yield return(interpreter.GetSymbolicExpressionTreeValues(tempTree, dataset, rows).Median());

                yield return(interpreter.GetSymbolicExpressionTreeValues(tempTree, dataset, rows).Average()); // TODO perf
            }
        }
Exemple #21
0
        public static void AnalyzeNodes(RegressionNodeTreeModel tree, ResultCollection results, IRegressionProblemData pd)
        {
            var dict             = new Dictionary <int, RegressionNodeModel>();
            var trainingLeafRows = new Dictionary <int, IReadOnlyList <int> >();
            var testLeafRows     = new Dictionary <int, IReadOnlyList <int> >();
            var modelNumber      = new IntValue(1);
            var symtree          = new SymbolicExpressionTree(MirrorTree(tree.Root, dict, trainingLeafRows, testLeafRows, modelNumber, pd.Dataset, pd.TrainingIndices.ToList(), pd.TestIndices.ToList()));

            results.AddOrUpdateResult("DecisionTree", symtree);

            if (dict.Count > 200)
            {
                return;
            }
            var models = new Scope("NodeModels");

            results.AddOrUpdateResult("NodeModels", models);
            foreach (var m in dict.Keys.OrderBy(x => x))
            {
                models.Variables.Add(new Variable("Model " + m, dict[m].CreateRegressionSolution(Subselect(pd, trainingLeafRows[m], testLeafRows[m]))));
            }
        }
Exemple #22
0
        private void GenerateImage()
        {
            animationTimer.Stop();
            pictureBox.Image = null;
            if ((pictureBox.Width > 0) && (pictureBox.Height > 0))
            {
                if (Content != null)
                {
                    var nodeStack = new Stack <SymbolicExpressionTreeNode>();
                    int rows      = Content.World.Rows;
                    int columns   = Content.World.Columns;
                    SymbolicExpressionTree expression = Content.SymbolicExpressionTree;

                    DrawWorld();
                    using (Graphics graphics = Graphics.FromImage(pictureBox.Image)) {
                        float cellHeight = pictureBox.Height / (float)rows;
                        float cellWidth  = pictureBox.Width / (float)columns;

                        AntInterpreter interpreter = new AntInterpreter();
                        interpreter.MaxTimeSteps = Content.MaxTimeSteps.Value;
                        interpreter.Expression   = Content.SymbolicExpressionTree;
                        interpreter.World        = Content.World;
                        int currentAntLocationColumn;
                        int currentAntLocationRow;
                        // draw initial ant
                        interpreter.AntLocation(out currentAntLocationRow, out currentAntLocationColumn);
                        DrawAnt(graphics, currentAntLocationRow, currentAntLocationColumn, interpreter.AntDirection, cellWidth, cellHeight);
                        // interpret ant code and draw trail
                        while (interpreter.ElapsedTime < interpreter.MaxTimeSteps)
                        {
                            interpreter.Step();
                            interpreter.AntLocation(out currentAntLocationRow, out currentAntLocationColumn);
                            DrawAnt(graphics, currentAntLocationRow, currentAntLocationColumn, interpreter.AntDirection, cellWidth, cellHeight);
                        }
                    }
                    pictureBox.Refresh();
                }
            }
        }
        public sealed override IOperation Apply()
        {
            SymbolicExpressionTree tree = GenotypeToPhenotypeMapperParameter.ActualValue.Map(
                RandomParameter.ActualValue,
                BoundsParameter.ActualValue,
                MaxExpressionLengthParameter.ActualValue.Value,
                SymbolicExpressionTreeGrammarParameter.ActualValue,
                IntegerVectorParameter.ActualValue
                );

            SymbolicExpressionTreeParameter.ActualValue = tree;
            BoolMatrix world        = WorldParameter.ActualValue;
            IntValue   maxTimeSteps = MaxTimeStepsParameter.ActualValue;

            AntInterpreter interpreter = new AntInterpreter();

            interpreter.MaxTimeSteps = maxTimeSteps.Value;
            interpreter.World        = world;
            interpreter.Expression   = tree;
            interpreter.Run();

            QualityParameter.ActualValue = new DoubleValue(interpreter.FoodEaten);
            return(null);
        }
Exemple #24
0
        public static ISymbolicExpressionTree CreateTree(IEnumerable <KeyValuePair <string, IEnumerable <string> > > factors,
                                                         double[] factorCoefficients,
                                                         double @const = 0)
        {
            ISymbolicExpressionTree     tree      = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
            ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();

            tree.Root.AddSubtree(startNode);
            ISymbolicExpressionTreeNode addition = new Addition().CreateTreeNode();

            startNode.AddSubtree(addition);

            int i = 0;

            foreach (var factor in factors)
            {
                var varName = factor.Key;
                foreach (var factorValue in factor.Value)
                {
                    var node = (BinaryFactorVariableTreeNode) new BinaryFactorVariable().CreateTreeNode();
                    node.VariableValue = factorValue;
                    node.VariableName  = varName;
                    node.Weight        = factorCoefficients[i];
                    addition.AddSubtree(node);
                    i++;
                }
            }

            if ([email protected](0.0))
            {
                ConstantTreeNode cNode = (ConstantTreeNode) new Constant().CreateTreeNode();
                cNode.Value = @const;
                addition.AddSubtree(cNode);
            }
            return(tree);
        }
Exemple #25
0
        /// <summary>
        /// Maps a genotype (an integer vector) to a phenotype (a symbolic expression tree).
        /// PIGE approach.
        /// </summary>
        /// <param name="random">random number generator</param>
        /// <param name="bounds">integer number range for genomes (codons) of the nont vector</param>
        /// <param name="length">length of the nont vector to create</param>
        /// <param name="grammar">grammar definition</param>
        /// <param name="genotype">integer vector, which should be mapped to a tree</param>
        /// <returns>phenotype (a symbolic expression tree)</returns>
        public override ISymbolicExpressionTree Map(IRandom random, IntMatrix bounds, int length,
                                                    ISymbolicExpressionGrammar grammar,
                                                    IntegerVector genotype)
        {
            SymbolicExpressionTree tree = new SymbolicExpressionTree();
            var rootNode  = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode();
            var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();

            rootNode.AddSubtree(startNode);
            tree.Root = rootNode;

            // Map can be called simultaniously on multiple threads
            lock (nontVectorLocker) {
                if (NontVector == null)
                {
                    NontVector = GetNontVector(random, bounds, length);
                }
            }

            MapPIGEIteratively(startNode, genotype, grammar,
                               genotype.Length, random);

            return(tree);
        }
        /// <summary>
        /// Maps a genotype (an integer vector) to a phenotype (a symbolic expression tree).
        /// Depth-first approach.
        /// </summary>
        /// <param name="random">random number generator</param>
        /// <param name="bounds">only used for PIGEMapper (ignore here)</param>
        /// <param name="length">only used for PIGEMapper (ignore here)</param>
        /// <param name="grammar">grammar definition</param>
        /// <param name="genotype">integer vector, which should be mapped to a tree</param>
        /// <returns>phenotype (a symbolic expression tree)</returns>
        public override SymbolicExpressionTree Map(IRandom random, IntMatrix bounds, int length,
                                                   ISymbolicExpressionGrammar grammar,
                                                   IntegerVector genotype)
        {
            SymbolicExpressionTree tree = new SymbolicExpressionTree();
            var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode();

            if (rootNode.HasLocalParameters)
            {
                rootNode.ResetLocalParameters(random);
            }
            var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();

            if (startNode.HasLocalParameters)
            {
                startNode.ResetLocalParameters(random);
            }
            rootNode.AddSubtree(startNode);
            tree.Root = rootNode;

            MapDepthFirstIteratively(startNode, genotype, grammar,
                                     genotype.Length, random);
            return(tree);
        }
        public void TestCompiledInterpreterEstimatedValuesConsistency()
        {
            const double delta = 1e-12;

            var twister = new MersenneTwister();
            int seed    = twister.Next(0, int.MaxValue);

            twister.Seed((uint)seed);

            Console.WriteLine(seed);

            const int numRows = 100;
            var       dataset = Util.CreateRandomDataset(twister, numRows, Columns);

            var grammar = new TypeCoherentExpressionGrammar();

            grammar.ConfigureAsDefaultRegressionGrammar();
            grammar.Symbols.First(x => x.Name == "Power Functions").Enabled = true;

            var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 10, 0, 0);

            foreach (ISymbolicExpressionTree tree in randomTrees)
            {
                Util.InitTree(tree, twister, new List <string>(dataset.VariableNames));
            }

            var interpreters = new ISymbolicDataAnalysisExpressionTreeInterpreter[] {
                new SymbolicDataAnalysisExpressionCompiledTreeInterpreter(),
                new SymbolicDataAnalysisExpressionTreeInterpreter(),
                new SymbolicDataAnalysisExpressionTreeLinearInterpreter(),
            };
            var rows      = Enumerable.Range(0, numRows).ToList();
            var formatter = new SymbolicExpressionTreeHierarchicalFormatter();

            for (int i = 0; i < randomTrees.Length; ++i)
            {
                var tree         = randomTrees[i];
                var valuesMatrix = interpreters.Select(x => x.GetSymbolicExpressionTreeValues(tree, dataset, rows).ToList()).ToList();
                for (int m = 0; m < interpreters.Length - 1; ++m)
                {
                    for (int n = m + 1; n < interpreters.Length; ++n)
                    {
                        for (int row = 0; row < numRows; ++row)
                        {
                            var v1 = valuesMatrix[m][row];
                            var v2 = valuesMatrix[n][row];
                            if (double.IsNaN(v1) && double.IsNaN(v2))
                            {
                                continue;
                            }
                            if (Math.Abs(v1 - v2) > delta)
                            {
                                Console.WriteLine(formatter.Format(tree));
                                foreach (var node in tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList())
                                {
                                    var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode();
                                    if (rootNode.HasLocalParameters)
                                    {
                                        rootNode.ResetLocalParameters(twister);
                                    }
                                    rootNode.SetGrammar(grammar.CreateExpressionTreeGrammar());

                                    var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();
                                    if (startNode.HasLocalParameters)
                                    {
                                        startNode.ResetLocalParameters(twister);
                                    }
                                    startNode.SetGrammar(grammar.CreateExpressionTreeGrammar());

                                    rootNode.AddSubtree(startNode);
                                    var t     = new SymbolicExpressionTree(rootNode);
                                    var start = t.Root.GetSubtree(0);
                                    var p     = node.Parent;
                                    start.AddSubtree(node);
                                    Console.WriteLine(node);

                                    var y1 = interpreters[m].GetSymbolicExpressionTreeValues(t, dataset, new[] { row }).First();
                                    var y2 = interpreters[n].GetSymbolicExpressionTreeValues(t, dataset, new[] { row }).First();

                                    if (double.IsNaN(y1) && double.IsNaN(y2))
                                    {
                                        continue;
                                    }
                                    string prefix = Math.Abs(y1 - y2) > delta ? "++" : "==";
                                    Console.WriteLine("\t{0} Row {1}: {2} {3}, Deviation = {4}", prefix, row, y1, y2, Math.Abs(y1 - y2));
                                    node.Parent = p;
                                }
                            }
                            string errorMessage = string.Format("Interpreters {0} and {1} do not agree on tree {2} and row {3} (seed = {4}).", interpreters[m].Name, interpreters[n].Name, i, row, seed);
                            Assert.AreEqual(v1, v2, delta, errorMessage);
                        }
                    }
                }
            }
        }
Exemple #28
0
        public override IOperation Apply()
        {
            var results = ResultCollection;

            // create empty parameter and result values
            if (TrainingBestSolutions == null)
            {
                TrainingBestSolutions         = new ItemList <T>();
                TrainingBestSolutionQualities = new ItemList <DoubleArray>();
                results.Add(new Result(TrainingBestSolutionQualitiesParameter.Name, TrainingBestSolutionQualitiesParameter.Description, TrainingBestSolutionQualities));
                results.Add(new Result(TrainingBestSolutionsParameter.Name, TrainingBestSolutionsParameter.Description, TrainingBestSolutions));
            }

            IList <Tuple <double, double> > trainingBestQualities = TrainingBestSolutionQualities
                                                                    .Select(x => Tuple.Create(x[0], x[1]))
                                                                    .ToList();

            #region find best trees
            IList <int> nonDominatedIndexes     = new List <int>();
            ISymbolicExpressionTree[] tree      = SymbolicExpressionTree.ToArray();
            List <double>             qualities = Quality.Select(x => x.Value).ToList();

            List <double> complexities;
            if (ComplexityParameter.ActualValue != null && ComplexityParameter.ActualValue.Length == qualities.Count)
            {
                complexities = ComplexityParameter.ActualValue.Select(x => x.Value).ToList();
            }
            else
            {
                complexities = tree.Select(t => (double)t.Length).ToList();
            }
            List <Tuple <double, double> > fitness = new List <Tuple <double, double> >();
            for (int i = 0; i < qualities.Count; i++)
            {
                fitness.Add(Tuple.Create(qualities[i], complexities[i]));
            }
            var maximization = Tuple.Create(Maximization.Value, false);// complexity must be minimized
            List <Tuple <double, double> > newNonDominatedQualities = new List <Tuple <double, double> >();
            for (int i = 0; i < tree.Length; i++)
            {
                if (IsNonDominated(fitness[i], trainingBestQualities, maximization) &&
                    IsNonDominated(fitness[i], newNonDominatedQualities, maximization) &&
                    IsNonDominated(fitness[i], fitness.Skip(i + 1), maximization))
                {
                    if (!newNonDominatedQualities.Contains(fitness[i]))
                    {
                        newNonDominatedQualities.Add(fitness[i]);
                        nonDominatedIndexes.Add(i);
                    }
                }
            }
            #endregion

            #region update Pareto-optimal solution archive
            if (nonDominatedIndexes.Count > 0)
            {
                ItemList <DoubleArray> nonDominatedQualities = new ItemList <DoubleArray>();
                ItemList <T>           nonDominatedSolutions = new ItemList <T>();
                // add all new non-dominated solutions to the archive
                foreach (var index in nonDominatedIndexes)
                {
                    T solution = CreateSolution(tree[index]);
                    nonDominatedSolutions.Add(solution);
                    nonDominatedQualities.Add(new DoubleArray(new double[] { fitness[index].Item1, fitness[index].Item2 }));
                }
                // add old non-dominated solutions only if they are not dominated by one of the new solutions
                for (int i = 0; i < trainingBestQualities.Count; i++)
                {
                    if (IsNonDominated(trainingBestQualities[i], newNonDominatedQualities, maximization))
                    {
                        if (!newNonDominatedQualities.Contains(trainingBestQualities[i]))
                        {
                            nonDominatedSolutions.Add(TrainingBestSolutions[i]);
                            nonDominatedQualities.Add(TrainingBestSolutionQualities[i]);
                        }
                    }
                }

                // make sure solutions and qualities are ordered in the results
                var orderedIndexes =
                    nonDominatedSolutions.Select((s, i) => i).OrderBy(i => nonDominatedQualities[i][0]).ToArray();

                var orderedNonDominatedSolutions = new ItemList <T>();
                var orderedNonDominatedQualities = new ItemList <DoubleArray>();
                foreach (var i in orderedIndexes)
                {
                    orderedNonDominatedQualities.Add(nonDominatedQualities[i]);
                    orderedNonDominatedSolutions.Add(nonDominatedSolutions[i]);
                }

                TrainingBestSolutions         = orderedNonDominatedSolutions;
                TrainingBestSolutionQualities = orderedNonDominatedQualities;

                results[TrainingBestSolutionsParameter.Name].Value         = orderedNonDominatedSolutions;
                results[TrainingBestSolutionQualitiesParameter.Name].Value = orderedNonDominatedQualities;
            }
            #endregion
            return(base.Apply());
        }
Exemple #29
0
        public void DeriveExpressions()
        {
            var formatter = new InfixExpressionFormatter();
            var parser    = new InfixExpressionParser();

            Assert.AreEqual("0", Derive("3", "x"));
            Assert.AreEqual("1", Derive("x", "x"));
            Assert.AreEqual("10", Derive("10*x", "x"));
            Assert.AreEqual("10", Derive("x*10", "x"));
            Assert.AreEqual("(2*'x')", Derive("x*x", "x"));
            Assert.AreEqual("((('x' * 'x') * 2) + ('x' * 'x'))", Derive("x*x*x", "x")); // simplifier does not merge (x*x)*2 + x*x  to 3*x*x
            Assert.AreEqual("0", Derive("10*x", "y"));
            Assert.AreEqual("20", Derive("10*x+20*y", "y"));
            Assert.AreEqual("6", Derive("2*3*x", "x"));
            Assert.AreEqual("(10*'y')", Derive("10*x*y+20*y", "x"));
            Assert.AreEqual("(1 / (SQR('x') * (-1)))", Derive("1/x", "x"));
            Assert.AreEqual("('y' / (SQR('x') * (-1)))", Derive("y/x", "x"));
            Assert.AreEqual("((((-2*'x') + (-1)) * ('a' + 'b')) / SQR(('x' + ('x' * 'x'))))",
                            Derive("(a+b)/(x+x*x)", "x"));
            Assert.AreEqual("((((-2*'x') + (-1)) * ('a' + 'b')) / SQR(('x' + SQR('x'))))", Derive("(a+b)/(x+SQR(x))", "x"));
            Assert.AreEqual("EXP('x')", Derive("exp(x)", "x"));
            Assert.AreEqual("(EXP((3*'x')) * 3)", Derive("exp(3*x)", "x"));
            Assert.AreEqual("(1 / 'x')", Derive("log(x)", "x"));
            Assert.AreEqual("(1 / 'x')", Derive("log(3*x)", "x"));                                            // 3 * 1/(3*x)
            Assert.AreEqual("(1 / ('x' + (0.333333333333333*'y')))", Derive("log(3*x+y)", "x"));              // simplifier does not try to keep fractions
            Assert.AreEqual("(1 / (SQRT(((3*'x') + 'y')) * 0.666666666666667))", Derive("sqrt(3*x+y)", "x")); // 3 / (2 * sqrt(3*x+y)) = 1 / ((2/3) * sqrt(3*x+y))
            Assert.AreEqual("(COS((3*'x')) * 3)", Derive("sin(3*x)", "x"));
            Assert.AreEqual("(SIN((3*'x')) * (-3))", Derive("cos(3*x)", "x"));
            Assert.AreEqual("(1 / (SQR(COS((3*'x'))) * 0.333333333333333))", Derive("tan(3*x)", "x")); // diff(tan(f(x)), x) = 1.0 / cos²(f(x)), simplifier puts constant factor into the denominator

            Assert.AreEqual("((9*'x') / ABS((3*'x')))", Derive("abs(3*x)", "x"));
            Assert.AreEqual("(SQR('x') * 3)", Derive("cube(x)", "x"));
            Assert.AreEqual("(1 / (SQR(CUBEROOT('x')) * 3))", Derive("cuberoot(x)", "x"));

            Assert.AreEqual("0", Derive("(a+b)/(x+SQR(x))", "y")); // df(a,b,x) / dy = 0


            Assert.AreEqual("('a' * 'b' * 'c')", Derive("a*b*c*d", "d"));
            Assert.AreEqual("('a' / ('b' * 'c' * SQR('d') * (-1)))", Derive("a/b/c/d", "d"));

            Assert.AreEqual("('x' * ((SQR(TANH(SQR('x'))) * (-1)) + 1) * 2)", Derive("tanh(sqr(x))", "x")); // (2*'x'*(1 - SQR(TANH(SQR('x'))))

            {
                // special case: Inv(x) using only one argument to the division symbol
                // f(x) = 1/x
                var root    = new ProgramRootSymbol().CreateTreeNode();
                var start   = new StartSymbol().CreateTreeNode();
                var div     = new Division().CreateTreeNode();
                var varNode = (VariableTreeNode)(new Variable().CreateTreeNode());
                varNode.Weight       = 1.0;
                varNode.VariableName = "x";
                div.AddSubtree(varNode);
                start.AddSubtree(div);
                root.AddSubtree(start);
                var t = new SymbolicExpressionTree(root);
                Assert.AreEqual("(1 / (SQR('x') * (-1)))",
                                formatter.Format(DerivativeCalculator.Derive(t, "x")));
            }

            {
                // special case: multiplication with only one argument
                var root    = new ProgramRootSymbol().CreateTreeNode();
                var start   = new StartSymbol().CreateTreeNode();
                var mul     = new Multiplication().CreateTreeNode();
                var varNode = (VariableTreeNode)(new Variable().CreateTreeNode());
                varNode.Weight       = 3.0;
                varNode.VariableName = "x";
                mul.AddSubtree(varNode);
                start.AddSubtree(mul);
                root.AddSubtree(start);
                var t = new SymbolicExpressionTree(root);
                Assert.AreEqual("3",
                                formatter.Format(DerivativeCalculator.Derive(t, "x")));
            }

            {
                // division with multiple arguments
                // div(x, y, z) is interpreted as (x / y) / z
                var root     = new ProgramRootSymbol().CreateTreeNode();
                var start    = new StartSymbol().CreateTreeNode();
                var div      = new Division().CreateTreeNode();
                var varNode1 = (VariableTreeNode)(new Variable().CreateTreeNode());
                varNode1.Weight       = 3.0;
                varNode1.VariableName = "x";
                var varNode2 = (VariableTreeNode)(new Variable().CreateTreeNode());
                varNode2.Weight       = 4.0;
                varNode2.VariableName = "y";
                var varNode3 = (VariableTreeNode)(new Variable().CreateTreeNode());
                varNode3.Weight       = 5.0;
                varNode3.VariableName = "z";
                div.AddSubtree(varNode1); div.AddSubtree(varNode2); div.AddSubtree(varNode3);
                start.AddSubtree(div);
                root.AddSubtree(start);
                var t = new SymbolicExpressionTree(root);

                Assert.AreEqual("(('y' * 'z' * 60) / (SQR('y') * SQR('z') * 400))",    // actually 3 / (4y  5z) but simplifier is not smart enough to cancel numerator and denominator
                                                                                       // 60 y z / y² z² 20² == 6 / y z 40 == 3 / y z 20
                                formatter.Format(DerivativeCalculator.Derive(t, "x")));
                Assert.AreEqual("(('x' * 'z' * (-60)) / (SQR('y') * SQR('z') * 400))", // actually 3x * -(4 5 z) / (4y 5z)² = -3x / (20 y² z)
                                                                                       // -3 4 5 x z / 4² y² 5² z² = -60 x z / 20² z² y² ==    -60 x z / y² z² 20²
                                formatter.Format(DerivativeCalculator.Derive(t, "y")));
                Assert.AreEqual("(('x' * 'y' * (-60)) / (SQR('y') * SQR('z') * 400))",
                                formatter.Format(DerivativeCalculator.Derive(t, "z")));
            }
        }
    private void BuildAllowedChildSymbolsTree() {
      if (Symbol == null) {
        symbolicExpressionTreeChart.Tree = null;
        return;
      }

      var tree = new SymbolicExpressionTree(new SymbolicExpressionTreeNode(Symbol));
      if (Grammar.GetMaximumSubtreeCount(Symbol) > 0) {
        for (int i = 0; i < Grammar.GetMaximumSubtreeCount(Symbol); i++) {
          var node = new DummySymbol("Subtree " + i).CreateTreeNode();
          var groupSymbols = grammar.GetAllowedChildSymbols(Symbol, i).OfType<GroupSymbol>().ToList();
          foreach (var childSymbol in Grammar.GetAllowedChildSymbols(Symbol, i)) {
            if (!groupSymbols.Any(g => g != childSymbol && g.Flatten().Contains(childSymbol)))
              node.AddSubtree(new SymbolicExpressionTreeNode(childSymbol));
          }
          tree.Root.AddSubtree(node);
        }
      }
      symbolicExpressionTreeChart.Tree = tree;
      symbolicExpressionTreeChart.SuspendRepaint = true;
      foreach (var subtreeNode in tree.Root.Subtrees) {
        foreach (var allowedChildNode in subtreeNode.Subtrees) {
          var visualLine = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(subtreeNode, allowedChildNode);
          visualLine.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
        }
      }

      for (int i = Grammar.GetMinimumSubtreeCount(symbol); i < Grammar.GetMaximumSubtreeCount(symbol); i++) {
        var subtreeNode = tree.Root.GetSubtree(i);
        var visualTreeNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(subtreeNode);
        visualTreeNode.TextColor = Color.Gray;
        visualTreeNode.LineColor = Color.LightGray;

        var visualLine = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(tree.Root, subtreeNode);
        visualLine.LineColor = Color.LightGray;

        foreach (var allowedChildNode in subtreeNode.Subtrees) {
          visualTreeNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(allowedChildNode);
          visualTreeNode.TextColor = Color.Gray;
          visualTreeNode.LineColor = Color.LightGray;

          visualLine = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(subtreeNode, allowedChildNode);
          visualLine.LineColor = Color.LightGray;
        }
      }
      symbolicExpressionTreeChart.SuspendRepaint = false;
      UpdateSelectedSymbolicExpressionTreeNodes();
    }
        public override IOperation Apply()
        {
            IEnumerable <int> rows = GenerateRowsToEvaluate();

            if (!rows.Any())
            {
                return(base.Apply());
            }

            #region find best tree
            var evaluator   = EvaluatorParameter.ActualValue;
            var problemData = ProblemDataParameter.ActualValue;
            ISymbolicExpressionTree[] tree = SymbolicExpressionTree.ToArray();

            // sort is ascending and we take the first n% => order so that best solutions are smallest
            // sort order is determined by maximization parameter
            double[] trainingQuality;
            if (Maximization.Value)
            {
                // largest values must be sorted first
                trainingQuality = Quality.Select(x => - x.Value).ToArray();
            }
            else
            {
                // smallest values must be sorted first
                trainingQuality = Quality.Select(x => x.Value).ToArray();
            }

            int[] treeIndexes = Enumerable.Range(0, tree.Length).ToArray();

            // sort trees by training qualities
            Array.Sort(trainingQuality, treeIndexes);

            // number of best training solutions to validate (at least 1)
            int topN = (int)Math.Max(tree.Length * PercentageOfBestSolutionsParameter.ActualValue.Value, 1);

            IExecutionContext childContext = (IExecutionContext)ExecutionContext.CreateChildOperation(evaluator);
            // evaluate best n training trees on validiation set
            var qualities = treeIndexes
                            .Select(i => tree[i])
                            .Take(topN)
                            .Select(t => evaluator.Evaluate(childContext, t, problemData, rows))
                            .ToArray();
            #endregion

            var results = ResultCollection;
            // create empty parameter and result values
            if (ValidationBestSolutions == null)
            {
                ValidationBestSolutions         = new ItemList <S>();
                ValidationBestSolutionQualities = new ItemList <DoubleArray>();
                results.Add(new Result(ValidationBestSolutionQualitiesParameter.Name, ValidationBestSolutionQualitiesParameter.Description, ValidationBestSolutionQualities));
                results.Add(new Result(ValidationBestSolutionsParameter.Name, ValidationBestSolutionsParameter.Description, ValidationBestSolutions));
            }

            IList <Tuple <double, double> > validationBestQualities = ValidationBestSolutionQualities
                                                                      .Select(x => Tuple.Create(x[0], x[1]))
                                                                      .ToList();

            #region find best trees
            IList <int> nonDominatedIndexes = new List <int>();

            List <double> complexities;
            if (ComplexityParameter.ActualValue != null && ComplexityParameter.ActualValue.Length == trainingQuality.Length)
            {
                complexities = ComplexityParameter.ActualValue.Select(x => x.Value).ToList();
            }
            else
            {
                complexities = tree.Select(t => (double)t.Length).ToList();
            }
            List <Tuple <double, double> > fitness = new List <Tuple <double, double> >();
            for (int i = 0; i < qualities.Length; i++)
            {
                fitness.Add(Tuple.Create(qualities[i], complexities[treeIndexes[i]]));
            }

            var maximization = Tuple.Create(Maximization.Value, false); // complexity must be minimized
            List <Tuple <double, double> > newNonDominatedQualities = new List <Tuple <double, double> >();
            for (int i = 0; i < fitness.Count; i++)
            {
                if (IsNonDominated(fitness[i], validationBestQualities, maximization) &&
                    IsNonDominated(fitness[i], newNonDominatedQualities, maximization) &&
                    IsNonDominated(fitness[i], fitness.Skip(i + 1), maximization))
                {
                    if (!newNonDominatedQualities.Contains(fitness[i]))
                    {
                        newNonDominatedQualities.Add(fitness[i]);
                        nonDominatedIndexes.Add(i);
                    }
                }
            }
            #endregion

            #region update Pareto-optimal solution archive
            if (nonDominatedIndexes.Count > 0)
            {
                ItemList <DoubleArray> nonDominatedQualities = new ItemList <DoubleArray>();
                ItemList <S>           nonDominatedSolutions = new ItemList <S>();
                // add all new non-dominated solutions to the archive
                foreach (var index in nonDominatedIndexes)
                {
                    S solution = CreateSolution(tree[treeIndexes[index]]);
                    nonDominatedSolutions.Add(solution);
                    nonDominatedQualities.Add(new DoubleArray(new double[] { fitness[index].Item1, fitness[index].Item2 }));
                }
                // add old non-dominated solutions only if they are not dominated by one of the new solutions
                for (int i = 0; i < validationBestQualities.Count; i++)
                {
                    if (IsNonDominated(validationBestQualities[i], newNonDominatedQualities, maximization))
                    {
                        if (!newNonDominatedQualities.Contains(validationBestQualities[i]))
                        {
                            nonDominatedSolutions.Add(ValidationBestSolutions[i]);
                            nonDominatedQualities.Add(ValidationBestSolutionQualities[i]);
                        }
                    }
                }

                // make sure solutions and qualities are ordered in the results
                var orderedIndexes =
                    nonDominatedSolutions.Select((s, i) => i).OrderBy(i => nonDominatedQualities[i][0]).ToArray();

                var orderedNonDominatedSolutions = new ItemList <S>();
                var orderedNonDominatedQualities = new ItemList <DoubleArray>();
                foreach (var i in orderedIndexes)
                {
                    orderedNonDominatedQualities.Add(nonDominatedQualities[i]);
                    orderedNonDominatedSolutions.Add(nonDominatedSolutions[i]);
                }

                ValidationBestSolutions         = orderedNonDominatedSolutions;
                ValidationBestSolutionQualities = orderedNonDominatedQualities;

                results[ValidationBestSolutionsParameter.Name].Value         = orderedNonDominatedSolutions;
                results[ValidationBestSolutionQualitiesParameter.Name].Value = orderedNonDominatedQualities;
            }
            #endregion
            return(base.Apply());
        }