1  #region License Information


2 


3  /* HeuristicLab


4  * Copyright (C) 20022015 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  return 2;


43  }


44  case OpCodes.Add:


45  case OpCodes.Sub: {


46  double complexity = 0;


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


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


49  }


50  return complexity;


51  }


52  case OpCodes.Mul:


53  case OpCodes.Div: {


54  double complexity = 1;


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


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


57  complexity *= nodeComplexity + 1;


58  }


59  return complexity;


60  }


61  case OpCodes.Sin:


62  case OpCodes.Cos:


63  case OpCodes.Tan:


64  case OpCodes.Exp:


65  case OpCodes.Log: {


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


67  return Math.Pow(2.0, complexity);


68  }


69  case OpCodes.Square: {


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


71  return complexity * complexity;


72  }


73  case OpCodes.SquareRoot: {


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


75  return complexity * complexity * complexity;


76  }


77  case OpCodes.Power:


78  case OpCodes.Root: {


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


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


81  if (exponent != null) {


82  double expVal = exponent.Value;


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


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


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


86  }


87 


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


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


90  }


91 


92  default:


93  throw new NotSupportedException();


94  }


95  }


96  }


97  }

