1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)


4  *


5  * This file is part of HeuristicLab.


6  *


7  * HeuristicLab is free software: you can redistribute it and/or modify


8  * it under the terms of the GNU General Public License as published by


9  * the Free Software Foundation, either version 3 of the License, or


10  * (at your option) any later version.


11  *


12  * HeuristicLab is distributed in the hope that it will be useful,


13  * but WITHOUT ANY WARRANTY; without even the implied warranty of


14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the


15  * GNU General Public License for more details.


16  *


17  * You should have received a copy of the GNU General Public License


18  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.


19  */


20  #endregion


21 


22  using System;


23  using System.Collections.Generic;


24  using System.Linq;


25  using HeuristicLab.Common;


26  using HeuristicLab.Core;


27  using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;


28  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;


29  using HeuristicLab.Random;


30  namespace HeuristicLab.Problems.DataAnalysis.Symbolic {


31  [StorableClass]


32  public sealed class FactorVariableTreeNode : SymbolicExpressionTreeTerminalNode, IVariableTreeNode {


33  public new FactorVariable Symbol {


34  get { return (FactorVariable)base.Symbol; }


35  }


36  [Storable]


37  private double[] weights;


38  public double[] Weights {


39  get { return weights; }


40  set { weights = value; }


41  }


42  [Storable]


43  private string variableName;


44  public string VariableName {


45  get { return variableName; }


46  set { variableName = value; }


47  }


48 


49  [StorableConstructor]


50  private FactorVariableTreeNode(bool deserializing) : base(deserializing) { }


51  private FactorVariableTreeNode(FactorVariableTreeNode original, Cloner cloner)


52  : base(original, cloner) {


53  variableName = original.variableName;


54  if(original.weights != null) {


55  this.weights = new double[original.Weights.Length];


56  Array.Copy(original.Weights, weights, weights.Length);


57  }


58  }


59 


60  public FactorVariableTreeNode(FactorVariable variableSymbol)


61  : base(variableSymbol) {


62  }


63 


64  public override bool HasLocalParameters {


65  get { return true; }


66  }


67 


68  public override void ResetLocalParameters(IRandom random) {


69  base.ResetLocalParameters(random);


70  variableName = Symbol.VariableNames.SampleRandom(random);


71  weights =


72  Symbol.GetVariableValues(variableName)


73  .Select(_ => NormalDistributedRandom.NextDouble(random, 0, 1)).ToArray();


74  }


75 


76  public override void ShakeLocalParameters(IRandom random, double shakingFactor) {


77  // mutate only one randomly selected weight


78  var idx = random.Next(weights.Length);


79  // 50% additive & 50% multiplicative


80  if(random.NextDouble() < 0.5) {


81  double x = NormalDistributedRandom.NextDouble(random, Symbol.WeightManipulatorMu,


82  Symbol.WeightManipulatorSigma);


83  weights[idx] = weights[idx] + x * shakingFactor;


84  } else {


85  double x = NormalDistributedRandom.NextDouble(random, 1.0, Symbol.MultiplicativeWeightManipulatorSigma);


86  weights[idx] = weights[idx] * x;


87  }


88  if(random.NextDouble() < Symbol.VariableChangeProbability) {


89  VariableName = Symbol.VariableNames.SampleRandom(random);


90  if(weights.Length != Symbol.GetVariableValues(VariableName).Count()) {


91  // if the length of the weight array does not match => reinitialize weights


92  weights =


93  Symbol.GetVariableValues(variableName)


94  .Select(_ => NormalDistributedRandom.NextDouble(random, 0, 1))


95  .ToArray();


96  }


97  }


98  }


99 


100  public override IDeepCloneable Clone(Cloner cloner) {


101  return new FactorVariableTreeNode(this, cloner);


102  }


103 


104  public double GetValue(string cat) {


105  return weights[Symbol.GetIndexForValue(VariableName, cat)];


106  }


107 


108  public override string ToString() {


109  var weightStr = string.Join("; ",


110  Symbol.GetVariableValues(VariableName).Select(value => value + ": " + GetValue(value).ToString("E4")));


111  return VariableName + " (factor) "


112  + "[" + weightStr + "]";


113  }


114  }


115  }


116 

