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); }
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()); }
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 } }
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(); }
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(); }
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); } }
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()); }
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); }
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); }
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()); }
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); }
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 } }
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])))); } }
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); }
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); }
/// <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); } } } } }
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()); }
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()); }