Index: /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3.csproj	(revision 3511)
+++ /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3.csproj	(revision 3512)
@@ -98,4 +98,7 @@
     <Compile Include="Creators\SymbolicExpressionTreeCreator.cs" />
     <Compile Include="Crossovers\SymbolicExpressionTreeCrossover.cs" />
+    <Compile Include="Manipulators\ChangeNodeTypeManipulation.cs" />
+    <Compile Include="Manipulators\FullTreeShaker.cs" />
+    <Compile Include="Manipulators\OnePointShaker.cs" />
     <Compile Include="Manipulators\SymbolicExpressionTreeManipulator.cs" />
     <Compile Include="SymbolicExpressionTreeTopLevelNode.cs" />
Index: /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/ChangeNodeTypeManipulation.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/ChangeNodeTypeManipulation.cs	(revision 3511)
+++ /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/ChangeNodeTypeManipulation.cs	(revision 3512)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -20,21 +20,15 @@
 #endregion
 
-using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Core;
+using HeuristicLab.Operators;
 using HeuristicLab.Random;
-using System.Diagnostics;
-using HeuristicLab.GP.Interfaces;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
-namespace HeuristicLab.Encodings.SymbolicExpressionTree {
-  public class ChangeNodeTypeManipulation : GPManipulatorBase {
-
-    public override string Description {
-      get {
-        return @"This manipulation operator selects a random tree-node and changes the function type.
-If this leads to a constraint-violation (wrong number or type of sub-trees) the sub-trees are repaired
-resulting in a valid tree again.";
-      }
-    }
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Manipulators {
+  [StorableClass]
+  [Item("ChangeNodeTypeManipulation", "Selects a random tree node and changes the symbol size.")]
+  public class ChangeNodeTypeManipulation : SymbolicExpressionTreeManipulator {
 
     public ChangeNodeTypeManipulation()
@@ -42,127 +36,44 @@
     }
 
-    internal override IOperation Manipulate(MersenneTwister random, IGeneticProgrammingModel gpModel, FunctionLibrary library, int maxTreeSize, int maxTreeHeight, IScope scope) {
-      TreeGardener gardener = new TreeGardener(random, library);
-      IFunctionTree parent = gardener.GetRandomParentNode(gpModel.FunctionTree);
-      IFunctionTree selectedChild;
-      int selectedChildIndex;
-      if (parent == null) {
-        selectedChildIndex = 0;
-        selectedChild = gpModel.FunctionTree;
-      } else {
-        selectedChildIndex = random.Next(parent.SubTrees.Count);
-        selectedChild = parent.SubTrees[selectedChildIndex];
+    protected override void Manipulate(IRandom random, SymbolicExpressionTree symbolicExpressionTree, ISymbolicExpressionGrammar grammar, IntValue maxTreeSize, IntValue maxTreeHeight, out bool success) {
+
+      // select any node except the with a parent where the parent is not the root node)
+      var manipulationPoint = (from parent in symbolicExpressionTree.Root.IterateNodesPrefix().Skip(1)
+                               from subtree in parent.SubTrees
+                               select new { Parent = parent, Node = subtree, Index = parent.SubTrees.IndexOf(subtree) }).SelectRandom(random);
+      // find possible symbols for the node (also considering the existing branches below it)
+      var allowedSymbols = from symbol in manipulationPoint.Parent.GetAllowedSymbols(manipulationPoint.Index)
+                           where manipulationPoint.Node.SubTrees.Count <= manipulationPoint.Node.Grammar.GetMaxSubtreeCount(symbol)
+                           where manipulationPoint.Node.SubTrees.Count >= manipulationPoint.Node.Grammar.GetMinSubtreeCount(symbol)
+                           select symbol;
+
+      if (allowedSymbols.Count() <= 1) {
+        success = false;
+        return;
       }
+      var node = manipulationPoint.Node;
+      // keep only symbols that are still possible considering the existing sub-trees
+      var constrainedSymbols = from symbol in allowedSymbols
+                               let disallowedSubtrees =
+                                     from subtree in node.SubTrees
+                                     where !node.Grammar.IsAllowedChild(symbol, subtree.Symbol, node.SubTrees.IndexOf(subtree))
+                                     select subtree
+                               where disallowedSubtrees.Count() == 0
+                               select symbol;
+      if (constrainedSymbols.Count() <= 1) {
+        success = false;
+        return;
+      }
+      var newSymbol = constrainedSymbols.SelectRandom(random);
 
-      if (selectedChild.SubTrees.Count == 0) {
-        IFunctionTree newTerminal = ChangeTerminalType(parent, selectedChild, selectedChildIndex, gardener, random);
-        if (parent == null) {
-          // no parent means the new child is the initial operator
-          gpModel.FunctionTree = newTerminal;
-        } else {
-          parent.RemoveSubTree(selectedChildIndex);
-          parent.InsertSubTree(selectedChildIndex, newTerminal);
-          // updating the variable is not necessary because it stays the same
-        }
-        Debug.Assert(gardener.IsValidTree(gpModel.FunctionTree));
-        // size and height stays the same when changing a terminal so no need to update the variables
-        // schedule an operation to initialize the new terminal
-        return Util.CreateInitializationOperation(TreeGardener.GetAllSubTrees(newTerminal), scope);
-      } else {
-        List<IFunctionTree> uninitializedBranches;
-        IFunctionTree newFunctionTree = ChangeFunctionType(parent, selectedChild, selectedChildIndex, gardener, random, out uninitializedBranches);
-        // in rare cases the function creates a tree that breaks the size limits
-        // calculate the height and size difference and 
-        // check if the size of the new tree is still in the allowed bounds
-        int oldChildSize = selectedChild.GetSize();
-        int oldChildHeight = selectedChild.GetHeight();
-        int newChildSize = newFunctionTree.GetSize();
-        int newChildHeight = newFunctionTree.GetHeight();
-        if ((gpModel.Height - oldChildHeight) + newChildHeight > maxTreeHeight ||
-          (gpModel.Size - oldChildSize) + newChildSize > maxTreeSize) {
-          // if size-constraints are violated don't change anything
-          return null;
-        }
-        if (parent == null) {
-          // no parent means the new function is the initial operator
-          gpModel.FunctionTree = newFunctionTree;
-        } else {
-          // remove the old child
-          parent.RemoveSubTree(selectedChildIndex);
-          // add the new child as sub-tree of parent
-          parent.InsertSubTree(selectedChildIndex, newFunctionTree);
-        }
-        // update size and height
-        gpModel.Size = gpModel.Size - oldChildSize + newChildSize;
-        gpModel.Height = gpModel.FunctionTree.GetHeight(); // must recalculate height because we can't know wether the manipulated branch was the deepest branch
-        // check if whole tree is ok
-        Debug.Assert(gardener.IsValidTree(gpModel.FunctionTree));
-        // return a composite operation that initializes all created sub-trees
-        return Util.CreateInitializationOperation(uninitializedBranches, scope);
-      }
-    }
-
-    private IFunctionTree ChangeTerminalType(IFunctionTree parent, IFunctionTree child, int childIndex, TreeGardener gardener, MersenneTwister random) {
-      IList<IFunction> allowedTerminals;
-      if (parent == null) {
-        allowedTerminals = gardener.Terminals;
-      } else {
-        allowedTerminals = new List<IFunction>();
-        var allAllowedChildren = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
-        foreach (IFunction c in allAllowedChildren) {
-          if (TreeGardener.IsTerminal(c)) allowedTerminals.Add(c);
-        }
-      }
-      // selecting from the terminals should always work since the current child was also a terminal
-      // so in the worst case we will just create a new terminal of the same type again.
-      return gardener.CreateRandomTree(allowedTerminals, 1, 1);
-    }
-
-    private IFunctionTree ChangeFunctionType(IFunctionTree parent, IFunctionTree child, int childIndex, TreeGardener gardener, MersenneTwister random,
-      out List<IFunctionTree> uninitializedBranches) {
-      // since there are subtrees, we have to check which 
-      // and how many of the existing subtrees we can reuse.
-      // first let's choose the function we want to use instead of the old child. For this we have to determine the
-      // pool of allowed functions based on constraints of the parent if there is one.
-      List<IFunction> allowedFunctions = new List<IFunction>(gardener.GetAllowedSubFunctions(parent != null ? parent.Function : null, childIndex));
-      // try to make a tree with the same arity as the old child.
-      int actualArity = child.SubTrees.Count;
-      // create a new tree-node for a randomly selected function
-      IFunction selectedFunction = allowedFunctions[random.Next(allowedFunctions.Count)];
-      // arity of the selected operator
-      int minArity = selectedFunction.MinSubTrees;
-      int maxArity = selectedFunction.MaxSubTrees;
-      // if the old child had too many sub-trees then the new child should keep as many sub-trees as possible
-      if (actualArity > maxArity)
-        actualArity = maxArity;
-      if (actualArity < minArity)
-        actualArity = minArity;
-      // create a list that holds old sub-trees that we can reuse in the new tree
-      List<IFunctionTree> availableSubTrees = new List<IFunctionTree>(child.SubTrees);
-      List<IFunctionTree> freshSubTrees = new List<IFunctionTree>();
-      IFunctionTree newTree = selectedFunction.GetTreeNode();
-      // randomly select the sub-trees that we keep
-      for (int i = 0; i < actualArity; i++) {
-        // fill all sub-tree slots of the new tree
-        // if for a given slot i there are multiple existing sub-trees that can be used in that slot
-        // then use a random existing sub-tree. When there are no existing sub-trees
-        // that fit in the given slot then create a new random tree and use it for the slot
-        ICollection<IFunction> allowedSubFunctions = gardener.GetAllowedSubFunctions(selectedFunction, i);
-        var matchingSubTrees = availableSubTrees.Where(subTree => allowedSubFunctions.Contains(subTree.Function));
-        if (matchingSubTrees.Count() > 0) {
-          IFunctionTree selectedSubTree = matchingSubTrees.ElementAt(random.Next(matchingSubTrees.Count()));
-          // we can just add it as subtree
-          newTree.InsertSubTree(i, selectedSubTree);
-          availableSubTrees.Remove(selectedSubTree); // the branch shouldn't be available for the following slots
-        } else {
-          // no existing matching tree found => create a new tree of minimal size
-          IFunctionTree freshTree = gardener.CreateRandomTree(allowedSubFunctions, 1, 1);
-          freshSubTrees.AddRange(TreeGardener.GetAllSubTrees(freshTree));
-          newTree.InsertSubTree(i, freshTree);
-        }
-      }
-      freshSubTrees.Add(newTree);
-      uninitializedBranches = freshSubTrees;
-      return newTree;
+      // replace the old node with the new node
+      var newNode = newSymbol.CreateTreeNode();
+      if (newNode.HasLocalParameters)
+        newNode.ResetLocalParameters(random);
+      foreach (var subtree in node.SubTrees)
+        newNode.AddSubTree(subtree);
+      manipulationPoint.Parent.RemoveSubTree(manipulationPoint.Index);
+      manipulationPoint.Parent.InsertSubTree(manipulationPoint.Index, newNode);
+      success = true;
     }
   }
Index: /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/FullTreeShaker.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/FullTreeShaker.cs	(revision 3511)
+++ /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/FullTreeShaker.cs	(revision 3512)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,49 +25,22 @@
 using HeuristicLab.Random;
 using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
-namespace HeuristicLab.Encodings.SymbolicExpressionTree {
-  public class FullTreeShaker : DelegatingOperator {
-    public override string Description {
-      get { return "Manipulates all tree nodes for which a manipulator is defined."; }
-    }
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Manipulators {
+  [StorableClass]
+  [Item("FullTreeShaker", "Manipulates all nodes that have local parameters.")]
+  public class FullTreeShaker : SymbolicExpressionTreeManipulator {
 
     public FullTreeShaker()
       : base() {
-      AddVariableInfo(new VariableInfo("Random", "A random generator (uniform)", typeof(MersenneTwister), VariableKind.In));
-      AddVariableInfo(new VariableInfo("FunctionLibrary", "Function library that defines function mutations", typeof(FunctionLibrary), VariableKind.In));
-      AddVariableInfo(new VariableInfo("ShakingFactor", "Variable that determines the force of the shaking operation", typeof(DoubleData), VariableKind.In));
-      AddVariableInfo(new VariableInfo("FunctionTree", "The function tree that should be mutated", typeof(IGeneticProgrammingModel), VariableKind.In | VariableKind.Out));
     }
 
-    public override IOperation Apply(IScope scope) {
-      FunctionLibrary library = GetVariableValue<FunctionLibrary>("FunctionLibrary", scope, true);
-      IGeneticProgrammingModel gpModel = GetVariableValue<IGeneticProgrammingModel>("FunctionTree", scope, false);
-      MersenneTwister mt = GetVariableValue<MersenneTwister>("Random", scope, true);
-
-      // save all existing sub-scopes in a backup scope
-      Scope backupScope = new Scope("backup");
-      foreach (Scope subScope in scope.SubScopes) {
-        backupScope.AddSubScope(subScope);
+    protected override void Manipulate(IRandom random, SymbolicExpressionTree symbolicExpressionTree, ISymbolicExpressionGrammar grammar, IntValue maxTreeSize, IntValue maxTreeHeight, out bool success) {
+      foreach (var node in symbolicExpressionTree.IterateNodesPrefix()) {
+        if (node.HasLocalParameters) {
+          node.ShakeLocalParameters(random, 1.0);
+        }
       }
-
-      // create a scope for all shaking operations
-      Scope tempScope = new Scope("Temp. manipulation scope");
-      scope.AddSubScope(tempScope); // scope containing a subscope for each manipulation
-      scope.AddSubScope(backupScope); // scope containing the old subscopes
-
-      // create a composite operation for all shaking operations
-      CompositeOperation next = new CompositeOperation();
-      next.ExecuteInParallel = false;
-
-      // enqueue all shaking operations
-      foreach (IFunctionTree subTree in TreeGardener.GetAllSubTrees(gpModel.FunctionTree).Where(x=>x.HasLocalParameters)) {
-        IOperation shakingOperation = subTree.CreateShakingOperation(tempScope);
-        next.AddOperation(shakingOperation);
-      }
-
-      // schedule a reducer operation to delete all temporary scopes and restore
-      // the subscopes of the backup scope after all manipulations are finished.
-      next.AddOperation(new AtomicOperation(new RightReducer(), scope));
-      return next;
+      success = true;
     }
   }
Index: /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/OnePointShaker.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/OnePointShaker.cs	(revision 3511)
+++ /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/OnePointShaker.cs	(revision 3512)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,49 +25,23 @@
 using HeuristicLab.Random;
 using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
-namespace HeuristicLab.Encodings.SymbolicExpressionTree {
-  public class OnePointShaker : DelegatingOperator {
-    public override string Description {
-      get { return "Selects a random node of all tree-nodes that have a manipulator defined and manipulates the selected node."; }
-    }
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Manipulators {
+  [StorableClass]
+  [Item("OnePointShaker", "Selects a random node with local parameters and manipulates the selected node.")]
+  public class OnePointShaker : SymbolicExpressionTreeManipulator {
 
     public OnePointShaker()
       : base() {
-      AddVariableInfo(new VariableInfo("FunctionLibrary", "Function library that defines mutation operations for functions", typeof(FunctionLibrary), VariableKind.In));
-      AddVariableInfo(new VariableInfo("Random", "A random generator (uniform)", typeof(MersenneTwister), VariableKind.In));
-      AddVariableInfo(new VariableInfo("ShakingFactor", "Factor that determines the force of the shaking operation", typeof(DoubleData), VariableKind.In));
-      AddVariableInfo(new VariableInfo("FunctionTree", "The function tree that should be mutated", typeof(IGeneticProgrammingModel), VariableKind.In | VariableKind.Out));
     }
 
-    public override IOperation Apply(IScope scope) {
-      FunctionLibrary library = GetVariableValue<FunctionLibrary>("FunctionLibrary", scope, true);
-      IGeneticProgrammingModel gpModel = GetVariableValue<IGeneticProgrammingModel>("FunctionTree", scope, false);
-      MersenneTwister mt = GetVariableValue<MersenneTwister>("Random", scope, true);
+    protected override void Manipulate(IRandom random, SymbolicExpressionTree symbolicExpressionTree, ISymbolicExpressionGrammar grammar, IntValue maxTreeSize, IntValue maxTreeHeight, out bool success) {
 
-      // get all nodes with local parameters
-      var parametricBranches = TreeGardener.GetAllSubTrees(gpModel.FunctionTree).Where(branch => branch.HasLocalParameters);
-      if (parametricBranches.Count() == 0) return null; // don't manipulate anything if there are no nodes with a manipulation operator
-      IFunctionTree selectedBranch = parametricBranches.ElementAt(mt.Next(parametricBranches.Count()));
+      SymbolicExpressionTreeNode selectedPoint = (from node in symbolicExpressionTree.IterateNodesPrefix()
+                                                  where node.HasLocalParameters
+                                                  select node).SelectRandom(random);
 
-      // save the exising sub-scopes in a backup scope
-      Scope backupScope = new Scope("backup");
-      foreach (Scope subScope in scope.SubScopes) {
-        backupScope.AddSubScope(subScope);
-      }
-
-      // create a scope for all shaking operations
-      Scope tempScope = new Scope("Temp. manipulation scope");
-      
-      // add the new sub-scopes
-      scope.AddSubScope(tempScope);
-      scope.AddSubScope(backupScope);
-
-      CompositeOperation next = new CompositeOperation();
-      next.ExecuteInParallel = false;
-      // the next operation should first manipulate and then restore the sub-scopes from the backup scope
-      next.AddOperation(selectedBranch.CreateShakingOperation(tempScope));
-      next.AddOperation(new AtomicOperation(new RightReducer(), scope));
-
-      return next;
+      selectedPoint.ShakeLocalParameters(random, 1.0);
+      success = true;
     }
   }
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Constant.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Constant.cs	(revision 3511)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Constant.cs	(revision 3512)
@@ -28,4 +28,5 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
+using System;
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols {
   [StorableClass]
@@ -45,7 +46,26 @@
       set { maxValue = value; }
     }
+    [Storable]
+    private double manipulatorNu;
+    public double ManipulatorNu {
+      get { return manipulatorNu; }
+      set { manipulatorNu = value; }
+    }
+    [Storable]
+    private double manipulatorSigma;
+    public double ManipulatorSigma {
+      get { return manipulatorSigma; }
+      set {
+        if (value < 0) throw new ArgumentException();
+        manipulatorSigma = value;
+      }
+    }
     #endregion
     public Constant()
       : base() {
+      manipulatorNu = 0.0;
+      manipulatorSigma = 1.0;
+      minValue = -20.0;
+      maxValue = 20.0;
     }
 
@@ -55,7 +75,9 @@
 
     public override IDeepCloneable Clone(Cloner cloner) {
-      Constant clone = (Constant) base.Clone(cloner);
+      Constant clone = (Constant)base.Clone(cloner);
       clone.minValue = minValue;
       clone.maxValue = maxValue;
+      clone.manipulatorNu = manipulatorNu;
+      clone.manipulatorSigma = manipulatorSigma;
       return clone;
     }
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/ConstantTreeNode.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/ConstantTreeNode.cs	(revision 3511)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/ConstantTreeNode.cs	(revision 3512)
@@ -63,4 +63,11 @@
     }
 
+    public override void ShakeLocalParameters(IRandom random, double shakingFactor) {
+      base.ShakeLocalParameters(random, shakingFactor);
+      var normalDistributedRNG = new NormalDistributedRandom(random, Symbol.ManipulatorNu, Symbol.ManipulatorSigma);
+      double x = normalDistributedRNG.NextDouble();
+      Value = Value + x * shakingFactor;
+    }
+
     public override object Clone() {
       return new ConstantTreeNode(this);
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Variable.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Variable.cs	(revision 3511)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Variable.cs	(revision 3512)
@@ -52,4 +52,19 @@
     }
     [Storable]
+    private double weightManipulatorNu;
+    public double WeightManipulatorNu {
+      get { return weightManipulatorNu; }
+      set { weightManipulatorNu = value; }
+    }
+    [Storable]
+    private double weightManipulatorSigma;
+    public double WeightManipulatorSigma {
+      get { return weightManipulatorSigma; }
+      set {
+        if (weightManipulatorSigma < 0.0) throw new ArgumentException("Negative sigma is not allowed.");
+        weightManipulatorSigma = value;
+      }
+    }
+    [Storable]
     private List<string> variableNames;
     public IEnumerable<string> VariableNames {
@@ -66,4 +81,6 @@
       weightNu = 1.0;
       weightSigma = 1.0;
+      weightManipulatorNu = 0.0;
+      weightManipulatorSigma = 1.0;
       variableNames = new List<string>();
     }
@@ -78,4 +95,6 @@
       clone.weightSigma = weightSigma;
       clone.variableNames = new List<string>(variableNames);
+      clone.weightManipulatorNu = weightManipulatorNu;
+      clone.weightManipulatorSigma = weightManipulatorSigma;
       return clone;
     }
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/VariableTreeNode.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/VariableTreeNode.cs	(revision 3511)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/VariableTreeNode.cs	(revision 3512)
@@ -69,8 +69,15 @@
       var normalDistributedRNG = new NormalDistributedRandom(random, Symbol.WeightNu, Symbol.WeightSigma);
       weight = normalDistributedRNG.NextDouble();
-      var variableList = new List<string>(Symbol.VariableNames);
-      int variableIndex = random.Next(0, variableList.Count);
-      variableName = variableList[variableIndex];
+      variableName = Symbol.VariableNames.SelectRandom(random);
     }
+
+    public override void ShakeLocalParameters(IRandom random, double shakingFactor) {
+      base.ShakeLocalParameters(random, shakingFactor);
+      var normalDistributedRNG = new NormalDistributedRandom(random, Symbol.WeightManipulatorNu, Symbol.WeightManipulatorSigma);
+      double x = normalDistributedRNG.NextDouble();
+      weight = weight + x * shakingFactor;
+      variableName = Symbol.VariableNames.SelectRandom(random);
+    }
+
 
     public override object Clone() {
