예제 #1
0
        public void ReplaceBranchManipulationDistributionsTest()
        {
            SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter();
            var trees   = new List <ISymbolicExpressionTree>();
            var grammar = Grammars.CreateArithmeticAndAdfGrammar();
            var random  = new MersenneTwister(31415);

            for (int i = 0; i < POPULATION_SIZE; i++)
            {
                var tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
                SubroutineCreater.CreateSubroutine(random, tree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
                string originalTree = formatter.Format(tree);
                ReplaceBranchManipulation.ReplaceRandomBranch(random, tree, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
                string manipulatedTree = formatter.Format(tree);
                Assert.IsFalse(originalTree == manipulatedTree);
                Util.IsValid(tree);
                trees.Add(tree);
            }
            Console.WriteLine("ReplaceBranchManipulation: " + Environment.NewLine +
                              Util.GetSizeDistributionString(trees, 105, 5) + Environment.NewLine +
                              Util.GetFunctionDistributionString(trees) + Environment.NewLine +
                              Util.GetNumberOfSubtreesDistributionString(trees) + Environment.NewLine +
                              Util.GetTerminalDistributionString(trees) + Environment.NewLine
                              );
        }
예제 #2
0
        public void ChangeNodeTypeManipulationDistributionsTest()
        {
            SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter();
            var trees        = new List <ISymbolicExpressionTree>();
            var grammar      = Grammars.CreateArithmeticAndAdfGrammar();
            var random       = new MersenneTwister(31415);
            int failedEvents = 0;

            for (int i = 0; i < POPULATION_SIZE; i++)
            {
                var    tree         = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
                string originalTree = formatter.Format(tree);
                ChangeNodeTypeManipulation.ChangeNodeType(random, tree);
                string manipulatedTree = formatter.Format(tree);
                if (originalTree == manipulatedTree)
                {
                    failedEvents++;
                }
                Util.IsValid(tree);
                trees.Add(tree);
            }
            Console.WriteLine("ChangeNodeTypeManipulation: " + Environment.NewLine +
                              "Failed events: " + failedEvents * 100.0 / POPULATION_SIZE + " %" + Environment.NewLine +
                              Util.GetSizeDistributionString(trees, 105, 5) + Environment.NewLine +
                              Util.GetFunctionDistributionString(trees) + Environment.NewLine +
                              Util.GetNumberOfSubtreesDistributionString(trees) + Environment.NewLine +
                              Util.GetTerminalDistributionString(trees) + Environment.NewLine
                              );
            Assert.IsTrue(failedEvents * 100.0 / POPULATION_SIZE < 5.0); // only max 5% failed mutations are allowed
        }
예제 #3
0
        private void AssertEqualAfterSimplification(string original, string expected)
        {
            var formatter    = new SymbolicExpressionTreeStringFormatter();
            var importer     = new SymbolicExpressionImporter();
            var actualTree   = TreeSimplifier.Simplify(importer.Import(original));
            var expectedTree = importer.Import(expected);

            Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
        }
        public void SimplifierAxiomsTest()
        {
            SymbolicExpressionImporter importer = new SymbolicExpressionImporter();
            SymbolicDataAnalysisExpressionTreeSimplifier simplifier = new SymbolicDataAnalysisExpressionTreeSimplifier();
            SymbolicExpressionTreeStringFormatter        formatter  = new SymbolicExpressionTreeStringFormatter();

            #region single argument arithmetics
            {
                var actualTree   = simplifier.Simplify(importer.Import("(+ 1.0)"));
                var expectedTree = importer.Import("1.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                var actualTree   = simplifier.Simplify(importer.Import("(+ (variable 2.0 a))"));
                var expectedTree = importer.Import("(variable 2.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                var actualTree   = simplifier.Simplify(importer.Import("(- 1.0)"));
                var expectedTree = importer.Import("-1.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                var actualTree   = simplifier.Simplify(importer.Import("(- (variable 2.0 a))"));
                var expectedTree = importer.Import("(variable -2.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                var actualTree   = simplifier.Simplify(importer.Import("(* 2.0)"));
                var expectedTree = importer.Import("2.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                var actualTree   = simplifier.Simplify(importer.Import("(* (variable 2.0 a))"));
                var expectedTree = importer.Import("(variable 2.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                var actualTree   = simplifier.Simplify(importer.Import("(/ 2.0)"));
                var expectedTree = importer.Import("0.5");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                var actualTree   = simplifier.Simplify(importer.Import("(/ (variable 2.0 a))"));
                var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            #endregion
            #region aggregation of constants into factors
            {
                var actualTree   = simplifier.Simplify(importer.Import("(* 2.0 (variable 2.0 a))"));
                var expectedTree = importer.Import("(variable 4.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                var actualTree   = simplifier.Simplify(importer.Import("(/ (variable 2.0 a) 2.0)"));
                var expectedTree = importer.Import("(variable 1.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                var actualTree   = simplifier.Simplify(importer.Import("(/ (variable 2.0 a) (* 2.0 2.0))"));
                var expectedTree = importer.Import("(variable 0.5 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            #endregion
            #region constant and variable folding
            {
                var actualTree   = simplifier.Simplify(importer.Import("(+ 1.0 2.0)"));
                var expectedTree = importer.Import("3.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                var actualTree   = simplifier.Simplify(importer.Import("(+ (variable 2.0 a) (variable 2.0 a))"));
                var expectedTree = importer.Import("(variable 4.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                var actualTree   = simplifier.Simplify(importer.Import("(- (variable 2.0 a) (variable 1.0 a))"));
                var expectedTree = importer.Import("(variable 1.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                var actualTree   = simplifier.Simplify(importer.Import("(* (variable 2.0 a) (variable 2.0 a))"));
                var expectedTree = importer.Import("(* (* (variable 1.0 a) (variable 1.0 a)) 4.0)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                var actualTree   = simplifier.Simplify(importer.Import("(/ (variable 1.0 a) (variable 2.0 a))"));
                var expectedTree = importer.Import("0.5");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            #endregion
            #region logarithm rules
            {
                // cancellation
                var actualTree   = simplifier.Simplify(importer.Import("(log (exp (variable 2.0 a)))"));
                var expectedTree = importer.Import("(variable 2.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // must not transform logs in this way as we do not know wether both variables are positive
                var actualTree   = simplifier.Simplify(importer.Import("(log (* (variable 1.0 a) (variable 1.0 b)))"));
                var expectedTree = importer.Import("(log (* (variable 1.0 a) (variable 1.0 b)))");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // must not transform logs in this way as we do not know wether both variables are positive
                var actualTree   = simplifier.Simplify(importer.Import("(log (/ (variable 1.0 a) (variable 1.0 b)))"));
                var expectedTree = importer.Import("(log (/ (variable 1.0 a) (variable 1.0 b)))");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            #endregion
            #region exponentiation rules
            {
                // cancellation
                var actualTree   = simplifier.Simplify(importer.Import("(exp (log (variable 2.0 a)))"));
                var expectedTree = importer.Import("(variable 2.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // exp transformation
                var actualTree   = simplifier.Simplify(importer.Import("(exp (+ (variable 2.0 a) (variable 3.0 b)))"));
                var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (variable 3.0 b)))");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // exp transformation
                var actualTree   = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (variable 3.0 b)))"));
                var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (variable -3.0 b)))");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // exp transformation
                var actualTree   = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (* (variable 3.0 b) (variable 4.0 c))))"));
                var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (variable 1.0 c) -12.0)))");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // exp transformation
                var actualTree   = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (* (variable 3.0 b) (cos (variable 4.0 c)))))"));
                var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (cos (variable 4.0 c)) -3.0)))");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            #endregion
            #region power rules
            {
                // cancellation
                var actualTree   = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) 0.0)"));
                var expectedTree = importer.Import("1.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // fixed point
                var actualTree   = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) 1.0)"));
                var expectedTree = importer.Import("(variable 2.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // inversion fixed point
                var actualTree   = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) -1.0)"));
                var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // inversion
                var actualTree   = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) -2.0)"));
                var expectedTree = importer.Import("(/ 1.0 (pow (variable 2.0 a) 2.0))");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // constant folding
                var actualTree   = simplifier.Simplify(importer.Import("(pow 3.0 2.0)"));
                var expectedTree = importer.Import("9.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            #endregion
            #region root rules
            {
                // cancellation
                var actualTree   = simplifier.Simplify(importer.Import("(root (variable 2.0 a) 0.0)"));
                var expectedTree = importer.Import("1.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // fixed point
                var actualTree   = simplifier.Simplify(importer.Import("(root (variable 2.0 a) 1.0)"));
                var expectedTree = importer.Import("(variable 2.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // inversion fixed point
                var actualTree   = simplifier.Simplify(importer.Import("(root (variable 2.0 a) -1.0)"));
                var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // inversion
                var actualTree   = simplifier.Simplify(importer.Import("(root (variable 2.0 a) -2.0)"));
                var expectedTree = importer.Import("(/ 1.0 (root (variable 2.0 a) 2.0))");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // constant folding
                var actualTree   = simplifier.Simplify(importer.Import("(root 9.0 2.0)"));
                var expectedTree = importer.Import("3.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            #endregion
            #region boolean operations
            {
                // always true and
                var actualTree   = simplifier.Simplify(importer.Import("(and 1.0 2.0)"));
                var expectedTree = importer.Import("1.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // always false and
                var actualTree   = simplifier.Simplify(importer.Import("(and 1.0 -2.0)"));
                var expectedTree = importer.Import("-1.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // always true or
                var actualTree   = simplifier.Simplify(importer.Import("(or -1.0 2.0)"));
                var expectedTree = importer.Import("1.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // always false or
                var actualTree   = simplifier.Simplify(importer.Import("(or -1.0 -2.0)"));
                var expectedTree = importer.Import("-1.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // constant not
                var actualTree   = simplifier.Simplify(importer.Import("(not -2.0)"));
                var expectedTree = importer.Import("1.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // constant not
                var actualTree   = simplifier.Simplify(importer.Import("(not 2.0)"));
                var expectedTree = importer.Import("-1.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // constant not
                var actualTree   = simplifier.Simplify(importer.Import("(not 0.0)"));
                var expectedTree = importer.Import("1.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // nested nots
                var actualTree   = simplifier.Simplify(importer.Import("(not (not 1.0))"));
                var expectedTree = importer.Import("1.0");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // not of non-Boolean argument
                var actualTree   = simplifier.Simplify(importer.Import("(not (variable 1.0 a))"));
                var expectedTree = importer.Import("(not (> (variable 1.0 a) 0.0))");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // not Boolean argument
                var actualTree   = simplifier.Simplify(importer.Import("(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))"));
                var expectedTree = importer.Import("(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            #endregion
            #region conditionals
            {
                // always false
                var actualTree   = simplifier.Simplify(importer.Import("(if -1.0 (variable 2.0 a) (variable 3.0 a))"));
                var expectedTree = importer.Import("(variable 3.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // always true
                var actualTree   = simplifier.Simplify(importer.Import("(if 1.0 (variable 2.0 a) (variable 3.0 a))"));
                var expectedTree = importer.Import("(variable 2.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // always false (0.0)
                var actualTree   = simplifier.Simplify(importer.Import("(if 0.0 (variable 2.0 a) (variable 3.0 a))"));
                var expectedTree = importer.Import("(variable 3.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // complex constant condition (always false)
                var actualTree   = simplifier.Simplify(importer.Import("(if (* 1.0 -2.0) (variable 2.0 a) (variable 3.0 a))"));
                var expectedTree = importer.Import("(variable 3.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // complex constant condition (always false)
                var actualTree   = simplifier.Simplify(importer.Import("(if (/ (variable 1.0 a) (variable -2.0 a)) (variable 2.0 a) (variable 3.0 a))"));
                var expectedTree = importer.Import("(variable 3.0 a)");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            {
                // insertion of relational operator
                var actualTree   = simplifier.Simplify(importer.Import("(if (variable 1.0 a) (variable 2.0 a) (variable 3.0 a))"));
                var expectedTree = importer.Import("(if (> (variable 1.0 a) 0.0) (variable 2.0 a) (variable 3.0 a))");
                Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
            }
            #endregion
        }
    public void AllArchitectureAlteringOperatorsDistributionTest() {
      var trees = new List<ISymbolicExpressionTree>();
      var newTrees = new List<ISymbolicExpressionTree>();
      var grammar = Grammars.CreateArithmeticAndAdfGrammar();
      var random = new MersenneTwister(31415);
      SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter();
      IntValue maxTreeSize = new IntValue(MAX_TREE_LENGTH);
      IntValue maxTreeHeigth = new IntValue(MAX_TREE_DEPTH);
      IntValue maxDefuns = new IntValue(3);
      IntValue maxArgs = new IntValue(3);
      for (int i = 0; i < POPULATION_SIZE; i++) {
        var tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
        Util.IsValid(tree);
        trees.Add(tree);
      }
      Stopwatch stopwatch = new Stopwatch();
      int failedEvents = 0;
      for (int g = 0; g < N_ITERATIONS; g++) {
        for (int i = 0; i < POPULATION_SIZE; i++) {
          if (random.NextDouble() < 0.5) {
            // manipulate
            stopwatch.Start();
            var selectedTree = (ISymbolicExpressionTree)trees.SampleRandom(random).Clone();
            var oldTree = (ISymbolicExpressionTree)selectedTree.Clone();
            bool success = false;
            int sw = random.Next(6);
            switch (sw) {
              case 0: success = ArgumentCreater.CreateNewArgument(random, selectedTree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3); break;
              case 1: success = ArgumentDeleter.DeleteArgument(random, selectedTree, 3, 3); break;
              case 2: success = ArgumentDuplicater.DuplicateArgument(random, selectedTree, 3, 3); break;
              case 3: success = SubroutineCreater.CreateSubroutine(random, selectedTree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3); break;
              case 4: success = SubroutineDuplicater.DuplicateSubroutine(random, selectedTree, 3, 3); break;
              case 5: success = SubroutineDeleter.DeleteSubroutine(random, selectedTree, 3, 3); break;
            }
            stopwatch.Stop();
            if (!success) failedEvents++;
            Util.IsValid(selectedTree);
            newTrees.Add(selectedTree);
          } else {
            stopwatch.Start();
            // crossover
            SymbolicExpressionTree par0 = null;
            SymbolicExpressionTree par1 = null;
            do {
              par0 = (SymbolicExpressionTree)trees.SampleRandom(random).Clone();
              par1 = (SymbolicExpressionTree)trees.SampleRandom(random).Clone();
            } while (par0.Length > MAX_TREE_LENGTH || par1.Length > MAX_TREE_LENGTH);
            var newTree = SubtreeCrossover.Cross(random, par0, par1, 0.9, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
            stopwatch.Stop();
            Util.IsValid(newTree);
            newTrees.Add(newTree);
          }
        }
        trees = new List<ISymbolicExpressionTree>(newTrees);
        newTrees.Clear();
      }
      var msPerOperation = stopwatch.ElapsedMilliseconds / ((double)POPULATION_SIZE * (double)N_ITERATIONS);
      Console.WriteLine("AllArchitectureAlteringOperators: " + Environment.NewLine +
        "Operations / s: ~" + Math.Round(1000.0 / (msPerOperation)) + "operations / s)" + Environment.NewLine +
        "Failed events: " + failedEvents * 100.0 / (double)(POPULATION_SIZE * N_ITERATIONS / 2.0) + "%" + Environment.NewLine +
        Util.GetSizeDistributionString(trees, 200, 5) + Environment.NewLine +
        Util.GetFunctionDistributionString(trees) + Environment.NewLine +
        Util.GetNumberOfSubtreesDistributionString(trees) + Environment.NewLine +
        Util.GetTerminalDistributionString(trees) + Environment.NewLine
        );

      Assert.IsTrue(failedEvents * 100.0 / (POPULATION_SIZE * N_ITERATIONS / 2.0) < 75.0); // 25% of architecture operations must succeed
      //mkommend: commented due to performance issues on the builder
      // Assert.IsTrue(Math.Round(1000.0 / (msPerOperation)) > 800); // must achieve more than 800 ops per second
    }
예제 #6
0
        public void AllArchitectureAlteringOperatorsDistributionTest()
        {
            var trees    = new List <ISymbolicExpressionTree>();
            var newTrees = new List <ISymbolicExpressionTree>();
            var grammar  = Grammars.CreateArithmeticAndAdfGrammar();
            var random   = new MersenneTwister(31415);
            SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter();
            IntValue maxTreeSize   = new IntValue(MAX_TREE_LENGTH);
            IntValue maxTreeHeigth = new IntValue(MAX_TREE_DEPTH);
            IntValue maxDefuns     = new IntValue(3);
            IntValue maxArgs       = new IntValue(3);

            for (int i = 0; i < POPULATION_SIZE; i++)
            {
                var tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
                Util.IsValid(tree);
                trees.Add(tree);
            }
            Stopwatch stopwatch    = new Stopwatch();
            int       failedEvents = 0;

            for (int g = 0; g < N_ITERATIONS; g++)
            {
                for (int i = 0; i < POPULATION_SIZE; i++)
                {
                    if (random.NextDouble() < 0.5)
                    {
                        // manipulate
                        stopwatch.Start();
                        var  selectedTree = (ISymbolicExpressionTree)trees.SampleRandom(random).Clone();
                        var  oldTree      = (ISymbolicExpressionTree)selectedTree.Clone();
                        bool success      = false;
                        int  sw           = random.Next(6);
                        switch (sw)
                        {
                        case 0: success = ArgumentCreater.CreateNewArgument(random, selectedTree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3); break;

                        case 1: success = ArgumentDeleter.DeleteArgument(random, selectedTree, 3, 3); break;

                        case 2: success = ArgumentDuplicater.DuplicateArgument(random, selectedTree, 3, 3); break;

                        case 3: success = SubroutineCreater.CreateSubroutine(random, selectedTree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3); break;

                        case 4: success = SubroutineDuplicater.DuplicateSubroutine(random, selectedTree, 3, 3); break;

                        case 5: success = SubroutineDeleter.DeleteSubroutine(random, selectedTree, 3, 3); break;
                        }
                        stopwatch.Stop();
                        if (!success)
                        {
                            failedEvents++;
                        }
                        Util.IsValid(selectedTree);
                        newTrees.Add(selectedTree);
                    }
                    else
                    {
                        stopwatch.Start();
                        // crossover
                        SymbolicExpressionTree par0 = null;
                        SymbolicExpressionTree par1 = null;
                        do
                        {
                            par0 = (SymbolicExpressionTree)trees.SampleRandom(random).Clone();
                            par1 = (SymbolicExpressionTree)trees.SampleRandom(random).Clone();
                        } while (par0.Length > MAX_TREE_LENGTH || par1.Length > MAX_TREE_LENGTH);
                        var newTree = SubtreeCrossover.Cross(random, par0, par1, 0.9, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
                        stopwatch.Stop();
                        Util.IsValid(newTree);
                        newTrees.Add(newTree);
                    }
                }
                trees = new List <ISymbolicExpressionTree>(newTrees);
                newTrees.Clear();
            }
            var msPerOperation = stopwatch.ElapsedMilliseconds / ((double)POPULATION_SIZE * (double)N_ITERATIONS);

            Console.WriteLine("AllArchitectureAlteringOperators: " + Environment.NewLine +
                              "Operations / s: ~" + Math.Round(1000.0 / (msPerOperation)) + "operations / s)" + Environment.NewLine +
                              "Failed events: " + failedEvents * 100.0 / (double)(POPULATION_SIZE * N_ITERATIONS / 2.0) + "%" + Environment.NewLine +
                              Util.GetSizeDistributionString(trees, 200, 5) + Environment.NewLine +
                              Util.GetFunctionDistributionString(trees) + Environment.NewLine +
                              Util.GetNumberOfSubtreesDistributionString(trees) + Environment.NewLine +
                              Util.GetTerminalDistributionString(trees) + Environment.NewLine
                              );

            Assert.IsTrue(failedEvents * 100.0 / (POPULATION_SIZE * N_ITERATIONS / 2.0) < 75.0); // 25% of architecture operations must succeed
            //mkommend: commented due to performance issues on the builder
            // Assert.IsTrue(Math.Round(1000.0 / (msPerOperation)) > 800); // must achieve more than 800 ops per second
        }
예제 #7
0
        public void SimplifierAxiomsTest()
        {
            SymbolicExpressionImporter            importer  = new SymbolicExpressionImporter();
            SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter();

            #region single argument arithmetics

            AssertEqualAfterSimplification("(+ 1.0)", "1.0");
            AssertEqualAfterSimplification("(- 1.0)", "-1.0");
            AssertEqualAfterSimplification("(- (variable 2.0 a))", "(variable -2.0 a)");
            AssertEqualAfterSimplification("(* 2.0)", "2.0");
            AssertEqualAfterSimplification("(* (variable 2.0 a))", "(variable 2.0 a)");
            AssertEqualAfterSimplification("(/ 2.0)", "0.5");
            AssertEqualAfterSimplification("(/ (variable 2.0 a))", "(/ 1.0 (variable 2.0 a))");
            #endregion

            #region aggregation of constants into factors
            AssertEqualAfterSimplification("(* 2.0 (variable 2.0 a))", "(variable 4.0 a)");
            AssertEqualAfterSimplification("(/ (variable 2.0 a) 2.0)", "(variable 1.0 a)");
            AssertEqualAfterSimplification("(/ (variable 2.0 a) (* 2.0 2.0))", "(variable 0.5 a)");
            #endregion

            #region constant and variable folding
            AssertEqualAfterSimplification("(+ 1.0 2.0)", "3.0");
            AssertEqualAfterSimplification("(+ (variable 2.0 a) (variable 2.0 a))", "(variable 4.0 a)");
            AssertEqualAfterSimplification("(- (variable 2.0 a) (variable 1.0 a))", "(variable 1.0 a)");
            AssertEqualAfterSimplification("(* (variable 2.0 a) (variable 2.0 a))", "(* (* (variable 1.0 a) (variable 1.0 a)) 4.0)");
            AssertEqualAfterSimplification("(/ (variable 1.0 a) (variable 2.0 a))", "0.5");
            #endregion

            #region logarithm rules

            // cancellation
            AssertEqualAfterSimplification("(log (exp (variable 2.0 a)))", "(variable 2.0 a)");
            // must not transform logs in this way as we do not know wether both variables are positive
            AssertEqualAfterSimplification("(log (* (variable 1.0 a) (variable 1.0 b)))", "(log (* (variable 1.0 a) (variable 1.0 b)))");
            // must not transform logs in this way as we do not know wether both variables are positive
            AssertEqualAfterSimplification("(log (/ (variable 1.0 a) (variable 1.0 b)))", "(log (/ (variable 1.0 a) (variable 1.0 b)))");
            #endregion

            #region exponentiation rules
            // cancellation
            AssertEqualAfterSimplification("(exp (log (variable 2.0 a)))", "(variable 2.0 a)");
            // exp transformation
            AssertEqualAfterSimplification("(exp (+ (variable 2.0 a) (variable 3.0 b)))", "(* (exp (variable 2.0 a)) (exp (variable 3.0 b)))");
            // exp transformation
            AssertEqualAfterSimplification("(exp (- (variable 2.0 a) (variable 3.0 b)))", "(* (exp (variable 2.0 a)) (exp (variable -3.0 b)))");
            // exp transformation
            AssertEqualAfterSimplification("(exp (- (variable 2.0 a) (* (variable 3.0 b) (variable 4.0 c))))", "(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (variable 1.0 c) -12.0)))");
            // exp transformation
            AssertEqualAfterSimplification("(exp (- (variable 2.0 a) (* (variable 3.0 b) (cos (variable 4.0 c)))))", "(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (cos (variable 4.0 c)) -3.0)))");
            #endregion

            #region power rules

            // cancellation
            AssertEqualAfterSimplification("(pow (variable 2.0 a) 0.0)", "1.0");
            // fixed point
            AssertEqualAfterSimplification("(pow (variable 2.0 a) 1.0)", "(variable 2.0 a)");
            // inversion fixed point
            AssertEqualAfterSimplification("(pow (variable 2.0 a) -1.0)", "(/ 1.0 (variable 2.0 a))");
            // inversion
            AssertEqualAfterSimplification("(pow (variable 2.0 a) -2.0)", "(/ 1.0 (pow (variable 2.0 a) 2.0))");
            // constant folding
            AssertEqualAfterSimplification("(pow 3.0 2.0)", "9.0");
            #endregion

            #region root rules
            // cancellation
            AssertEqualAfterSimplification("(root (variable 2.0 a) 0.0)", "1.0");
            // fixed point
            AssertEqualAfterSimplification("(root (variable 2.0 a) 1.0)", "(variable 2.0 a)");
            // inversion fixed point
            AssertEqualAfterSimplification("(root (variable 2.0 a) -1.0)", "(/ 1.0 (variable 2.0 a))");
            // inversion
            AssertEqualAfterSimplification("(root (variable 2.0 a) -2.0)", "(/ 1.0 (root (variable 2.0 a) 2.0))");
            // constant folding
            AssertEqualAfterSimplification("(root 9.0 2.0)", "3.0");
            #endregion

            #region boolean operations
            // always true and
            AssertEqualAfterSimplification("(and 1.0 2.0)", "1.0");
            // always false and
            AssertEqualAfterSimplification("(and 1.0 -2.0)", "-1.0");
            // always true or
            AssertEqualAfterSimplification("(or -1.0 2.0)", "1.0");
            // always false or
            AssertEqualAfterSimplification("(or -1.0 -2.0)", "-1.0");
            // constant not
            AssertEqualAfterSimplification("(not -2.0)", "1.0");
            // constant not
            AssertEqualAfterSimplification("(not 2.0)", "-1.0");
            // constant not
            AssertEqualAfterSimplification("(not 0.0)", "1.0");
            // nested nots
            AssertEqualAfterSimplification("(not (not 1.0))", "1.0");
            // not of non-Boolean argument
            AssertEqualAfterSimplification("(not (variable 1.0 a))", "(not (> (variable 1.0 a) 0.0))");
            // not Boolean argument
            AssertEqualAfterSimplification("(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))", "(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))");
            #endregion

            #region conditionals
            // always false
            AssertEqualAfterSimplification("(if -1.0 (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)");
            // always true
            AssertEqualAfterSimplification("(if 1.0 (variable 2.0 a) (variable 3.0 a))", "(variable 2.0 a)");
            // always false (0.0)
            AssertEqualAfterSimplification("(if 0.0 (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)");
            // complex constant condition (always false)
            AssertEqualAfterSimplification("(if (* 1.0 -2.0) (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)");
            // complex constant condition (always false)
            AssertEqualAfterSimplification("(if (/ (variable 1.0 a) (variable -2.0 a)) (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)");
            // insertion of relational operator
            AssertEqualAfterSimplification("(if (variable 1.0 a) (variable 2.0 a) (variable 3.0 a))", "(if (> (variable 1.0 a) 0.0) (variable 2.0 a) (variable 3.0 a))");
            #endregion

            #region factor variables
            AssertEqualAfterSimplification("(factor a 1.0)", "(factor a 1.0)");
            // factor folding
            AssertEqualAfterSimplification("(+ (factor a 1.0 1.0) (factor a 2.0 3.0))", "(factor a 3.0 4.0)");
            AssertEqualAfterSimplification("(- (factor a 1.0 1.0) (factor a 2.0 3.0))", "(factor a -1.0 -2.0)");
            AssertEqualAfterSimplification("(* (factor a 2.0 2.0) (factor a 2.0 3.0))", "(factor a 4.0 6.0)");
            AssertEqualAfterSimplification("(/ (factor a 2.0 5.0))", "(factor a 0.5 0.2)");
            AssertEqualAfterSimplification("(/ (factor a 4.0 6.0) (factor a 2.0 3.0))", "(factor a 2.0 2.0)");
            AssertEqualAfterSimplification("(+ 3.0 (factor a 4.0 6.0))", "(factor a 7.0 9.0)");
            AssertEqualAfterSimplification("(+ (factor a 4.0 6.0) 3.0)", "(factor a 7.0 9.0)");
            AssertEqualAfterSimplification("(- 3.0 (factor a 4.0 6.0))", "(factor a -1.0 -3.0)");
            AssertEqualAfterSimplification("(- (factor a 4.0 6.0) 3.0)", "(factor a 1.0 3.0)");
            AssertEqualAfterSimplification("(* 2.0 (factor a 4.0 6.0))", "(factor a 8.0 12.0)");
            AssertEqualAfterSimplification("(* (factor a 4.0 6.0) 2.0)", "(factor a 8.0 12.0)");
            AssertEqualAfterSimplification("(* (factor a 4.0 6.0) (variable 2.0 a))", "(* (factor a 8.0 12.0) (variable 1.0 a))"); // not possible (a is used as factor and double variable) interpreter will fail
            AssertEqualAfterSimplification(
                "(log (factor a 10.0 100.0))",
                string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1})", Math.Log(10.0), Math.Log(100.0)));
            AssertEqualAfterSimplification(
                "(exp (factor a 2.0 3.0))",
                string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1})", Math.Exp(2.0), Math.Exp(3.0)));
            AssertEqualAfterSimplification("(sqrt (factor a 9.0 16.0))", "(factor a 3.0 4.0))");
            AssertEqualAfterSimplification("(sqr (factor a 2.0 3.0))", "(factor a 4.0 9.0))");
            AssertEqualAfterSimplification("(root (factor a 8.0 27.0) 3)", "(factor a 2.0 3.0))");
            AssertEqualAfterSimplification("(pow (factor a 2.0 3.0) 3)", "(factor a 8.0 27.0))");

            AssertEqualAfterSimplification("(sin (factor a 1.0 2.0) )",
                                           string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1}))", Math.Sin(1.0), Math.Sin(2.0)));
            AssertEqualAfterSimplification("(cos (factor a 1.0 2.0) )",
                                           string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1}))", Math.Cos(1.0), Math.Cos(2.0)));
            AssertEqualAfterSimplification("(tan (factor a 1.0 2.0) )",
                                           string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1}))", Math.Tan(1.0), Math.Tan(2.0)));


            AssertEqualAfterSimplification("(binfactor a val 1.0)", "(binfactor a val 1.0)");
            // binfactor folding
            AssertEqualAfterSimplification("(+ (binfactor a val 1.0) (binfactor a val 2.0))", "(binfactor a val 3.0)");
            AssertEqualAfterSimplification("(+ (binfactor a val0 1.0) (binfactor a val1 2.0))", "(+ (binfactor a val0 1.0) (binfactor a val1 2.0))"); // cannot be simplified (different vals)
            AssertEqualAfterSimplification("(+ (binfactor a val 1.0) (binfactor b val 2.0))", "(+ (binfactor a val 1.0) (binfactor b val 2.0))");     // cannot be simplified (different vars)
            AssertEqualAfterSimplification("(- (binfactor a val 1.0) (binfactor a val 2.0))", "(binfactor a val -1.0)");
            AssertEqualAfterSimplification("(* (binfactor a val 2.0) (binfactor a val 3.0))", "(binfactor a val 6.0)");
            AssertEqualAfterSimplification("(/ (binfactor a val 6.0) (binfactor a val 3.0))", "(/ (binfactor a val 6.0) (binfactor a val 3.0))"); // not allowed! 0/0 for other values than 'val'
            AssertEqualAfterSimplification("(/ (binfactor a val 4.0))", "(/ 1.0 (binfactor a val 4.0))");                                         // not allowed!

            AssertEqualAfterSimplification("(+ 3.0 (binfactor a val 4.0 ))", "(+ (binfactor a val 4.0 ) 3.0))");                                  // not allowed
            AssertEqualAfterSimplification("(- 3.0 (binfactor a val 4.0 ))", "(+ (binfactor a val -4.0 ) 3.0)");
            AssertEqualAfterSimplification("(+ (binfactor a val 4.0 ) 3.0)", "(+ (binfactor a val 4.0 ) 3.0)");                                   // not allowed
            AssertEqualAfterSimplification("(- (binfactor a val 4.0 ) 3.0)", "(+ (binfactor a val 4.0 ) -3.0)");
            AssertEqualAfterSimplification("(* 2.0 (binfactor a val 4.0))", "(binfactor a val 8.0 )");
            AssertEqualAfterSimplification("(* (binfactor a val 4.0) 2.0)", "(binfactor a val 8.0 )");
            AssertEqualAfterSimplification("(* (binfactor a val 4.0) (variable 2.0 a))", "(* (binfactor a val 1.0) (variable 1.0 a) 8.0)"); // not possible (a is used as factor and double variable) interpreter will fail
            AssertEqualAfterSimplification("(log (binfactor a val 10.0))", "(log (binfactor a val 10.0))");                                 // not allowed (log(0))

            // exp( binfactor w val=a) = if(val=a) exp(w) else exp(0) = binfactor( (exp(w) - 1) val a) + 1
            AssertEqualAfterSimplification("(exp (binfactor a val 3.0))",
                                           string.Format(CultureInfo.InvariantCulture, "(+ (binfactor a val {0}) 1.0)", Math.Exp(3.0) - 1)
                                           );
            AssertEqualAfterSimplification("(sqrt (binfactor a val 16.0))", "(binfactor a val 4.0))"); // sqrt(0) = 0
            AssertEqualAfterSimplification("(sqr (binfactor a val 3.0))", "(binfactor a val 9.0))");   // 0*0 = 0
            AssertEqualAfterSimplification("(root (binfactor a val 27.0) 3)", "(binfactor a val 3.0))");
            AssertEqualAfterSimplification("(pow (binfactor a val 3.0) 3)", "(binfactor a val 27.0))");

            AssertEqualAfterSimplification("(sin (binfactor a val 2.0) )",
                                           string.Format(CultureInfo.InvariantCulture, "(binfactor a val {0}))", Math.Sin(2.0)));            // sin(0) = 0
            AssertEqualAfterSimplification("(cos (binfactor a val 2.0) )",
                                           string.Format(CultureInfo.InvariantCulture, "(+ (binfactor a val {0}) 1.0)", Math.Cos(2.0) - 1)); // cos(0) = 1
            AssertEqualAfterSimplification("(tan (binfactor a val 2.0) )",
                                           string.Format(CultureInfo.InvariantCulture, "(binfactor a val {0}))", Math.Tan(2.0)));            // tan(0) = 0

            // combination of factor and binfactor
            AssertEqualAfterSimplification("(+ (binfactor a x0 2.0) (factor a 2.0 3.0))", "(factor a 4.0 3.0)");
            AssertEqualAfterSimplification("(+ (factor a 2.0 3.0) (binfactor a x0 2.0))", "(factor a 4.0 3.0)");
            AssertEqualAfterSimplification("(* (binfactor a x1 2.0) (factor a 2.0 3.0))", "(binfactor a x1 6.0)"); // all other values have weight zero in binfactor
            AssertEqualAfterSimplification("(* (factor a 2.0 3.0) (binfactor a x1 2.0))", "(binfactor a x1 6.0)"); // all other values have weight zero in binfactor
            AssertEqualAfterSimplification("(/ (binfactor a x0 2.0) (factor a 2.0 3.0))", "(binfactor a x0 1.0)");
            AssertEqualAfterSimplification("(/ (factor a 2.0 3.0) (binfactor a x0 2.0))",
                                           string.Format(CultureInfo.InvariantCulture, "(factor a 1.0 {0})", 3.0 / 0.0));
            AssertEqualAfterSimplification("(- (binfactor a x0 2.0) (factor a 2.0 3.0))", "(factor a 0.0 -3.0)");
            AssertEqualAfterSimplification("(- (factor a 2.0 3.0) (binfactor a x0 2.0))", "(factor a 0.0 3.0)");
            #endregion

            #region abs
            AssertEqualAfterSimplification("(abs 2.0)", "2.0");
            AssertEqualAfterSimplification("(abs -2.0)", "2.0");                                                  // constant folding
            AssertEqualAfterSimplification("(abs (exp (variable 2.0 x)))", "(exp (variable 2.0 x)))");            // exp is always positive
            AssertEqualAfterSimplification("(abs (exp (variable 2.0 x)))", "(exp (variable 2.0 x)))");            // exp is always positive
            AssertEqualAfterSimplification("(abs (sqr (variable 2.0 a)))", "(sqr (variable 2.0 a))");             // sqr is always positive
            AssertEqualAfterSimplification("(abs (sqrt (variable 2.0 a)))", "(sqrt (variable 2.0 a))");           // sqrt is always positive (for our cases)
            AssertEqualAfterSimplification("(abs (cuberoot (variable 2.0 a)))", "(cuberoot (variable 2.0 a))");   // cuberoot is always positive (for our cases)

            AssertEqualAfterSimplification("(* (abs (variable 2.0 x)) 2.0)", "(abs (variable 4.0 x))");           // can multiply positive constants into abs
            AssertEqualAfterSimplification("(* (abs (variable 2.0 x)) -2.0)", "(* (abs (variable 4.0 x)) -1.0)"); // for negative constants keep the sign

            AssertEqualAfterSimplification("(abs (* (variable 1.0 a) (variable 2.0 b)))", "(* (abs (variable 1.0 a)) (abs (variable 1.0 b)) 2.0))");
            AssertEqualAfterSimplification("(abs (/ (variable 1.0 a) (variable 2.0 b)))", "(/ (abs (variable 1.0 a)) (abs (variable 2.0 b))))");
            #endregion

            #region square and sqrt
            AssertEqualAfterSimplification("(sqr (sqrt (variable 2.0 x)))", "(variable 2.0 x)");
            AssertEqualAfterSimplification("(sqrt (sqr (variable 2.0 x)))", "(variable 2.0 x)");
            AssertEqualAfterSimplification("(sqr (abs (variable 2.0 a)))", "(sqr (variable 2.0 a))");
            AssertEqualAfterSimplification("(sqr (exp (variable 2.0 x)))", "(exp (variable 4.0 x))");

            AssertEqualAfterSimplification("(sqr (* (variable 2.0 a) (variable 3.0 b) (variable 4.0 c)))",
                                           "(* (sqr (variable 1.0 a)) (sqr (variable 1.0 b)) (sqr (variable 1.0 c)) 576)"); // 2²*3²*4²
            #endregion

            #region cube and cuberoot
            AssertEqualAfterSimplification("(cube (cuberoot (variable 2.0 x)))", "(variable 2.0 x)");
            AssertEqualAfterSimplification("(cuberoot (cube (variable 2.0 x)))", "(variable 2.0 x)");
            AssertEqualAfterSimplification("(cube (exp (variable 2.0 x)))", "(exp (variable 6.0 x))");

            AssertEqualAfterSimplification("(sqr (cube (variable 2.0 x)))", "(pow (variable 2.0 x) 6)");
            AssertEqualAfterSimplification("(cube (sqr (variable 2.0 x)))", "(pow (variable 2.0 x) 6)");
            #endregion

            #region AQ
            AssertEqualAfterSimplification("(* (aq (variable 1.0 x) (variable 1.0 y)) 2.0)", "(aq (variable 2.0 x) (variable 1.0 y))");
            AssertEqualAfterSimplification("(/ (aq (variable 1.0 x) (variable 1.0 y)) 2.0)", "(aq (variable 0.5 x) (variable 1.0 y))");

            #endregion
        }