1  #region License Information


2 


3  /* HeuristicLab


4  * Copyright (C) 20022016 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 


24  using System;


25  using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;


26 


27  namespace 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  case OpCodes.FactorVariable: {


43  return 2;


44  }


45  case OpCodes.Add:


46  case OpCodes.Sub: {


47  double complexity = 0;


48  for (int i = 0; i < node.SubtreeCount; i++) {


49  complexity += CalculateComplexity(node.GetSubtree(i));


50  }


51  return complexity;


52  }


53  case OpCodes.Mul:


54  case OpCodes.Div: {


55  double complexity = 1;


56  for (int i = 0; i < node.SubtreeCount; i++) {


57  var nodeComplexity = CalculateComplexity(node.GetSubtree(i));


58  complexity *= nodeComplexity + 1;


59  }


60  return complexity;


61  }


62  case OpCodes.Sin:


63  case OpCodes.Cos:


64  case OpCodes.Tan:


65  case OpCodes.Exp:


66  case OpCodes.Log: {


67  double complexity = CalculateComplexity(node.GetSubtree(0));


68  return Math.Pow(2.0, complexity);


69  }


70  case OpCodes.Square: {


71  double complexity = CalculateComplexity(node.GetSubtree(0));


72  return complexity * complexity;


73  }


74  case OpCodes.SquareRoot: {


75  double complexity = CalculateComplexity(node.GetSubtree(0));


76  return complexity * complexity * complexity;


77  }


78  case OpCodes.Power:


79  case OpCodes.Root: {


80  double complexity = CalculateComplexity(node.GetSubtree(0));


81  var exponent = node.GetSubtree(1) as ConstantTreeNode;


82  if (exponent != null) {


83  double expVal = exponent.Value;


84  if (expVal < 0) expVal = Math.Abs(expVal);


85  if (expVal < 1) expVal = 1 / expVal;


86  return Math.Pow(complexity, Math.Round(expVal));


87  }


88 


89  double expComplexity = CalculateComplexity(node.GetSubtree(1));


90  return Math.Pow(complexity, 2 * expComplexity);


91  }


92 


93  default:


94  throw new NotSupportedException();


95  }


96  }


97  }


98  }

