Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisModelComplexityCalculator.cs @ 13220

Last change on this file since 13220 was 13220, checked in by mkommend, 8 years ago

#2175: Improve source code and usability of complexity calculator.

File size: 5.1 KB
Line 
1#region License Information
2
3/* HeuristicLab
4 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#endregion
23
24using System;
25using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
26
27namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
28  public static class SymbolicDataAnalysisModelComplexityCalculator {
29    public static double CalculateComplexity(ISymbolicExpressionTree tree) {
30      return CalculateComplexity(tree.Root);
31    }
32    public static double CalculateComplexity(ISymbolicExpressionTreeNode treeNode) {
33      var node = treeNode;
34      if (node.Symbol is ProgramRootSymbol) node = node.GetSubtree(0);
35      if (node.Symbol is StartSymbol) node = node.GetSubtree(0);
36
37      switch (OpCodes.MapSymbolToOpCode(node)) {
38        case OpCodes.Constant: {
39            return 1;
40          }
41        case OpCodes.Variable: {
42            return 2;
43          }
44        case OpCodes.Add: {
45            double complexity = 0;
46            for (int i = 0; i < node.SubtreeCount; i++) {
47              complexity += CalculateComplexity(node.GetSubtree(i));
48            }
49            return complexity;
50          }
51        case OpCodes.Sub: {
52            double complexity = 0;
53            for (int i = 0; i < node.SubtreeCount; i++) {
54              complexity += CalculateComplexity(node.GetSubtree(i));
55            }
56            return complexity;
57          }
58        case OpCodes.Mul: {
59            double complexity = 1;
60            for (int i = 0; i < node.SubtreeCount; i++) {
61              var nodeComplexity = CalculateComplexity(node.GetSubtree(i));
62              complexity *= nodeComplexity + 1;
63            }
64            return complexity;
65          }
66        case OpCodes.Div: {
67            double complexity = 1;
68            for (int i = 0; i < node.SubtreeCount; i++) {
69              var nodeComplexity = CalculateComplexity(node.GetSubtree(i));
70              complexity *= nodeComplexity + 1;
71            }
72            return complexity;
73          }
74        case OpCodes.Sin: {
75            double complexity = CalculateComplexity(node.GetSubtree(0));
76            return Math.Pow(2.0, complexity);
77          }
78        case OpCodes.Cos: {
79            double complexity = CalculateComplexity(node.GetSubtree(0));
80            return Math.Pow(2.0, complexity);
81          }
82        case OpCodes.Tan: {
83            double complexity = CalculateComplexity(node.GetSubtree(0));
84            return Math.Pow(2.0, complexity);
85          }
86        case OpCodes.Exp: {
87            double complexity = CalculateComplexity(node.GetSubtree(0));
88            return Math.Pow(2.0, complexity);
89          }
90        case OpCodes.Log: {
91            double complexity = CalculateComplexity(node.GetSubtree(0));
92            return Math.Pow(2.0, complexity);
93          }
94        case OpCodes.Square: {
95            double complexity = CalculateComplexity(node.GetSubtree(0));
96            return complexity * complexity;
97          }
98        case OpCodes.SquareRoot: {
99            double complexity = CalculateComplexity(node.GetSubtree(0));
100            return complexity * complexity * complexity;
101          }
102        case OpCodes.Power: {
103            double complexity = CalculateComplexity(node.GetSubtree(0));
104            var exponentNode = node.GetSubtree(1) as ConstantTreeNode;
105            if (exponentNode != null) {
106              double exponent = exponentNode.Value;
107              if (exponent < 0) exponent = Math.Abs(exponent);
108              if (exponent < 1) exponent = 1 / exponent;
109              return Math.Pow(complexity, Math.Round(exponent));
110            }
111
112            double exponentComplexity = CalculateComplexity(node.GetSubtree(1));
113            return Math.Pow(complexity, 2 * exponentComplexity);
114          }
115        case OpCodes.Root: {
116            double complexity = CalculateComplexity(node.GetSubtree(0));
117            var rootNode = node.GetSubtree(1) as ConstantTreeNode;
118            if (rootNode != null) {
119              double root = rootNode.Value;
120              if (root < 0) root = Math.Abs(root);
121              if (root < 1) root = 1 / root;
122              return Math.Pow(complexity, Math.Round(root));
123            }
124
125            double rootComplexity = CalculateComplexity(node.GetSubtree(1));
126            return Math.Pow(complexity, 2 * rootComplexity);
127          }
128
129        default:
130          throw new NotSupportedException();
131      }
132    }
133  }
134}
Note: See TracBrowser for help on using the repository browser.