Changeset 17347
- Timestamp:
- 10/30/19 14:53:54 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Creators/BalancedTreeCreator.cs
r17345 r17347 26 26 using HeuristicLab.Common; 27 27 using HeuristicLab.Core; 28 using HeuristicLab.Data; 29 using HeuristicLab.Parameters; 28 30 using HeuristicLab.PluginInfrastructure; 29 31 using HeuristicLab.Random; … … 34 36 [Item("BalancedTreeCreator", "An operator that produces trees with a specified distribution")] 35 37 public class BalancedTreeCreator : SymbolicExpressionTreeCreator { 38 private const string IrregularityBiasParameterName = "IrregularityBias"; 39 40 public IFixedValueParameter<PercentValue> IrregularityBiasParameter { 41 get { return (IFixedValueParameter<PercentValue>)Parameters[IrregularityBiasParameterName]; } 42 } 43 44 public double IrregularityBias { 45 get { return IrregularityBiasParameter.Value.Value; } 46 set { IrregularityBiasParameter.Value.Value = value; } 47 } 48 36 49 [StorableConstructor] 37 50 protected BalancedTreeCreator(StorableConstructorFlag _) : base(_) { } 38 51 52 [StorableHook(HookType.AfterDeserialization)] 53 private void AfterDeserialization() { 54 if (!Parameters.ContainsKey(IrregularityBiasParameterName)) { 55 Parameters.Add(new FixedValueParameter<PercentValue>(IrregularityBiasParameterName, new PercentValue(0.0))); 56 } 57 } 58 39 59 protected BalancedTreeCreator(BalancedTreeCreator original, Cloner cloner) : base(original, cloner) { } 40 60 41 public BalancedTreeCreator() { } 61 public BalancedTreeCreator() { 62 Parameters.Add(new FixedValueParameter<PercentValue>(IrregularityBiasParameterName, new PercentValue(0.0))); 63 } 42 64 43 65 public override IDeepCloneable Clone(Cloner cloner) { … … 46 68 47 69 public override ISymbolicExpressionTree CreateTree(IRandom random, ISymbolicExpressionGrammar grammar, int maxLength, int maxDepth) { 48 return Create(random, grammar, maxLength, maxDepth );49 } 50 51 public static ISymbolicExpressionTree Create(IRandom random, ISymbolicExpressionGrammar grammar, int maxLength, int maxDepth ) {70 return Create(random, grammar, maxLength, maxDepth, IrregularityBias); 71 } 72 73 public static ISymbolicExpressionTree Create(IRandom random, ISymbolicExpressionGrammar grammar, int maxLength, int maxDepth, double irregularityBias = 0) { 52 74 int targetLength = random.Next(3, maxLength); // because we have 2 extra nodes for the root and start symbols, and the end is exclusive 53 return CreateExpressionTree(random, grammar, targetLength, maxDepth );75 return CreateExpressionTree(random, grammar, targetLength, maxDepth, irregularityBias); 54 76 } 55 77 … … 61 83 62 84 private class SymbolCache { 63 public SymbolCache(ISymbolicExpressionGrammar grammar) {85 public SymbolCache(ISymbolicExpressionGrammarBase grammar) { 64 86 Grammar = grammar; 65 87 } … … 81 103 weights.Add(child.InitialFrequency); 82 104 } 83 if ( !symbols.Any()) {105 if (symbols.Count == 0) { 84 106 throw new ArgumentException("SampleNode: parent symbol " + parent.Name 85 107 + " does not have any allowed child symbols with min arity " + minArity … … 94 116 } 95 117 96 public ISymbolicExpressionGrammar Grammar {118 public ISymbolicExpressionGrammarBase Grammar { 97 119 get { return grammar; } 98 120 set { … … 153 175 } 154 176 155 private ISymbolicExpressionGrammar grammar;177 private ISymbolicExpressionGrammarBase grammar; 156 178 private Dictionary<Tuple<ISymbol, ISymbol>, bool[]> allowedCache; 157 179 private Dictionary<ISymbol, SymbolCacheEntry> symbolCache; 158 180 } 159 181 160 public static ISymbolicExpressionTree CreateExpressionTree(IRandom random, ISymbolicExpressionGrammar grammar, int targetLength, int maxDepth ) {182 public static ISymbolicExpressionTree CreateExpressionTree(IRandom random, ISymbolicExpressionGrammar grammar, int targetLength, int maxDepth, double irregularityBias = 1) { 161 183 // even lengths cannot be achieved without symbols of odd arity 162 184 // therefore we randomly pick a neighbouring odd length value 185 var tree = MakeStump(random, grammar); // create a stump consisting of just a ProgramRootSymbol and a StartSymbol 186 CreateExpression(random, tree.Root.GetSubtree(0), targetLength - 2, maxDepth - 2, irregularityBias); // -2 because the stump has length 2 and depth 2 187 return tree; 188 } 189 190 public static void CreateExpression(IRandom random, ISymbolicExpressionTreeNode root, int targetLength, int maxDepth, double irregularityBias = 1) { 191 var grammar = root.Grammar; 163 192 var symbolCache = new SymbolCache(grammar); 164 if (!symbolCache.HasUnarySymbols && targetLength % 2 == 0) { 165 targetLength += random.NextDouble() < 0.5 ? -1 : +1; 166 } 167 return CreateExpressionTree(random, symbolCache, targetLength, maxDepth); 168 } 169 170 private static ISymbolicExpressionTree CreateExpressionTree(IRandom random, SymbolCache symbolCache, int targetLength, int maxDepth) { 171 var allowedSymbols = symbolCache.AllowedSymbols; 172 var tree = MakeStump(random, symbolCache.Grammar); 173 var tuples = new List<NodeInfo>(targetLength) { 174 new NodeInfo { Node = tree.Root, Depth = 0, Arity = 1 }, 175 new NodeInfo { Node = tree.Root.GetSubtree(0), Depth = 1, Arity = 1 } 176 }; 177 targetLength -= 2; // remaining length; -2 because we already have a root and start node 178 int openSlots = 1; // remaining extension points; startNode has arity 1 179 180 for (int i = 1; i < tuples.Count; ++i) { 193 var entry = symbolCache[root.Symbol]; 194 var arity = random.Next(entry.MinSubtreeCount, entry.MaxSubtreeCount + 1); 195 var tuples = new List<NodeInfo>(targetLength) { new NodeInfo { Node = root, Depth = 0, Arity = arity } }; 196 int openSlots = arity; 197 198 for (int i = 0; i < tuples.Count; ++i) { 181 199 var t = tuples[i]; 182 200 var node = t.Node; … … 186 204 // min and max arity here refer to the required arity limits for the child node 187 205 int maxChildArity = t.Depth == maxDepth - 1 ? 0 : Math.Min(parentEntry.MaxChildArity[childIndex], targetLength - openSlots); 188 int minChildArity = Math.Min( 1, maxChildArity);206 int minChildArity = Math.Min((openSlots - tuples.Count > 1 && random.NextDouble() < irregularityBias) ? 0 : 1, maxChildArity); 189 207 var child = symbolCache.SampleNode(random, node.Symbol, childIndex, minChildArity, maxChildArity); 190 208 var childEntry = symbolCache[child.Symbol]; … … 196 214 } 197 215 } 198 return tree;199 216 } 200 217
Note: See TracChangeset
for help on using the changeset viewer.