- Timestamp:
- 03/26/10 19:34:29 (15 years ago)
- Location:
- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Creators/ProbabilisticTreeCreator.cs
r3219 r3223 24 24 using HeuristicLab.Random; 25 25 using System; 26 27 namespace HeuristicLab.Encodings.SymbolicExpressionTree { 28 public class ProbabilisticTreeCreator : OperatorBase { 29 private static int MAX_TRIES { get { return 100; } } 30 31 public override string Description {32 get { return @"Generates a new random operator tree."; }33 }34 26 using System.Linq; 27 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 28 using System.Collections.Generic; 29 30 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding { 31 [StorableClass] 32 [Item("ProbabilisticTreeCreator", "An operator that creates new symbolic expression trees with uniformly distributed size")] 33 public class ProbabilisticTreeCreator : SymbolicExpressionTreeCreator { 34 private const int MAX_TRIES = 100; 35 35 public ProbabilisticTreeCreator() 36 36 : base() { 37 AddVariableInfo(new VariableInfo("Random", "Uniform random number generator", typeof(MersenneTwister), VariableKind.In)); 38 AddVariableInfo(new VariableInfo("FunctionLibrary", "The function library containing all available functions", typeof(FunctionLibrary), VariableKind.In)); 39 AddVariableInfo(new VariableInfo("MinTreeSize", "The minimal allowed size of the tree", typeof(IntData), VariableKind.In)); 40 AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size of the tree", typeof(IntData), VariableKind.In)); 41 AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In)); 42 AddVariableInfo(new VariableInfo("FunctionTree", "The created tree", typeof(IGeneticProgrammingModel), VariableKind.New | VariableKind.Out)); 43 } 44 45 public override IOperation Apply(IScope scope) { 46 IRandom random = GetVariableValue<IRandom>("Random", scope, true); 47 FunctionLibrary funLibrary = GetVariableValue<FunctionLibrary>("FunctionLibrary", scope, true); 48 int minTreeSize = GetVariableValue<IntData>("MinTreeSize", scope, true).Data; 49 int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data; 50 int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data; 51 52 IFunctionTree root = Create(random, funLibrary, minTreeSize, maxTreeSize, maxTreeHeight); 53 scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), new GeneticProgrammingModel(root))); 54 return Util.CreateInitializationOperation(TreeGardener.GetAllSubTrees(root), scope); 55 } 56 57 58 public static IFunctionTree Create(IRandom random, FunctionLibrary funLib, int minSize, int maxSize, int maxHeight) { 59 int treeSize = random.Next(minSize, maxSize); 60 IFunctionTree root = null; 37 } 38 39 protected override SymbolicExpressionTree Create(IRandom random, ISymbolicExpressionGrammar grammar, IntValue maxTreeSize, IntValue maxTreeHeight) { 40 return Apply(random, grammar, maxTreeSize.Value, maxTreeHeight.Value); 41 } 42 43 public SymbolicExpressionTree Apply(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeSize, int maxTreeHeight) { 44 // tree size is limited by the grammar and by the explicit size constraints 45 int allowedMinSize = grammar.MinimalExpressionLength(grammar.StartSymbol); 46 int allowedMaxSize = Math.Min(maxTreeSize, grammar.MaximalExpressionLength(grammar.StartSymbol)); 47 // select a target tree size uniformly in the possible range (as determined by explicit limits and limits of the grammar) 48 int treeSize = random.Next(allowedMinSize, allowedMaxSize); 49 SymbolicExpressionTree tree = new SymbolicExpressionTree(); 61 50 int tries = 0; 62 TreeGardener gardener = new TreeGardener(random, funLib);63 51 do { 64 52 try { 65 root = gardener.PTC2(treeSize, maxHeight); 53 // determine possible root symbols to create a tree of the target size 54 var possibleRootSymbols = from symbol in grammar.AllowedSymbols(grammar.StartSymbol, 0) 55 where treeSize <= grammar.MaximalExpressionLength(symbol) 56 where treeSize >= grammar.MinimalExpressionLength(symbol) 57 select symbol; 58 Symbol rootSymbol = SelectRandomSymbol(random, possibleRootSymbols); 59 tree.Root = PTC2(random, grammar, rootSymbol, treeSize, maxTreeHeight); 66 60 } 67 61 catch (ArgumentException) { 68 62 // try a different size 69 treeSize = random.Next( minSize, maxSize);63 treeSize = random.Next(allowedMinSize, allowedMaxSize); 70 64 tries = 0; 71 65 } 72 66 if (tries++ >= MAX_TRIES) { 73 67 // try a different size 74 treeSize = random.Next( minSize, maxSize);68 treeSize = random.Next(allowedMinSize, allowedMaxSize); 75 69 tries = 0; 76 70 } 77 } while (root == null || root.GetSize() > maxSize || root.GetHeight() > maxHeight); 71 } while (tree.Root == null || tree.Size > maxTreeSize || tree.Height > maxTreeHeight); 72 return tree; 73 } 74 75 private Symbol SelectRandomSymbol(IRandom random, IEnumerable<Symbol> symbols) { 76 var symbolList = symbols.ToList(); 77 return symbolList[random.Next(symbolList.Count)]; 78 } 79 80 81 private SymbolicExpressionTreeNode PTC2(IRandom random, ISymbolicExpressionGrammar grammar, Symbol rootSymbol, int size, int maxDepth) { 82 SymbolicExpressionTreeNode root = rootSymbol.CreateTreeNode(); 83 if (size <= 1 || maxDepth <= 1) return root; 84 List<object[]> list = new List<object[]>(); 85 int currentSize = 1; 86 int totalListMinSize = grammar.MinimalExpressionLength(rootSymbol) - 1; 87 88 int actualArity = SampleArity(random, grammar, rootSymbol, size); 89 for (int i = 0; i < actualArity; i++) { 90 // insert a dummy sub-tree and add the pending extension to the list 91 root.AddSubTree(null); 92 list.Add(new object[] { root, i, 2 }); 93 } 94 95 // while there are pending extension points and we have not reached the limit of adding new extension points 96 while (list.Count > 0 && totalListMinSize + currentSize < size) { 97 int randomIndex = random.Next(list.Count); 98 object[] nextExtension = list[randomIndex]; 99 list.RemoveAt(randomIndex); 100 SymbolicExpressionTreeNode parent = (SymbolicExpressionTreeNode)nextExtension[0]; 101 int argumentIndex = (int)nextExtension[1]; 102 int extensionDepth = (int)nextExtension[2]; 103 if (extensionDepth + grammar.MinimalExpressionDepth(parent.Symbol) >= maxDepth) { 104 parent.RemoveSubTree(argumentIndex); 105 SymbolicExpressionTreeNode branch = CreateMinimalTree(random, grammar, grammar.AllowedSymbols(parent.Symbol, argumentIndex)); 106 parent.InsertSubTree(argumentIndex, branch); // insert a smallest possible tree 107 currentSize += branch.GetSize(); 108 totalListMinSize -= branch.GetSize(); 109 } else { 110 var allowedSubFunctions = from s in grammar.AllowedSymbols(parent.Symbol, argumentIndex) 111 where grammar.MinimalExpressionDepth(parent.Symbol) + extensionDepth - 1 < maxDepth 112 where grammar.MaximalExpressionLength(s) > size - totalListMinSize - currentSize || 113 totalListMinSize + currentSize >= size * 0.9 // if the necessary size is almost reached then also allow 114 // terminals or terminal-branches 115 select s; 116 Symbol selectedSymbol = SelectRandomSymbol(random, allowedSubFunctions); 117 SymbolicExpressionTreeNode newTree = selectedSymbol.CreateTreeNode(); 118 parent.RemoveSubTree(argumentIndex); 119 parent.InsertSubTree(argumentIndex, newTree); 120 currentSize++; 121 totalListMinSize--; 122 123 actualArity = SampleArity(random, grammar, selectedSymbol, size - currentSize); 124 for (int i = 0; i < actualArity; i++) { 125 // insert a dummy sub-tree and add the pending extension to the list 126 newTree.AddSubTree(null); 127 list.Add(new object[] { newTree, i, extensionDepth + 1 }); 128 } 129 totalListMinSize += grammar.MinimalExpressionLength(selectedSymbol); 130 } 131 } 132 // fill all pending extension points 133 while (list.Count > 0) { 134 int randomIndex = random.Next(list.Count); 135 object[] nextExtension = list[randomIndex]; 136 list.RemoveAt(randomIndex); 137 SymbolicExpressionTreeNode parent = (SymbolicExpressionTreeNode)nextExtension[0]; 138 int a = (int)nextExtension[1]; 139 int d = (int)nextExtension[2]; 140 parent.RemoveSubTree(a); 141 parent.InsertSubTree(a, 142 CreateMinimalTree(random, grammar, grammar.AllowedSymbols(parent.Symbol, a))); // append a tree with minimal possible height 143 } 78 144 return root; 79 145 } 146 147 private int SampleArity(IRandom random, ISymbolicExpressionGrammar grammar, Symbol symbol, int targetSize) { 148 // select actualArity randomly with the constraint that the sub-trees in the minimal arity can become large enough 149 int minArity = grammar.MinSubTrees(symbol); 150 int maxArity = grammar.MaxSubTrees(symbol); 151 if (maxArity >= targetSize) { 152 maxArity = targetSize; 153 } 154 // the min number of sub-trees has to be set to a value that is large enough so that the largest possible tree is at least tree size 155 // if 1..3 trees are possible and the largest possible first sub-tree is smaller larger than the target size then minArity should be at least 2 156 int aggregatedLongestExpressionLength = 1; 157 for (int i = 0; i < maxArity; i++) { 158 aggregatedLongestExpressionLength += (from s in grammar.AllowedSymbols(symbol, i) 159 select grammar.MaximalExpressionLength(symbol)).Max(); 160 if (aggregatedLongestExpressionLength < targetSize) minArity = i; 161 else break; 162 } 163 164 // the max number of sub-trees has to be set to a value that is small enough so that the smallest possible tree is at most tree size 165 // if 1..3 trees are possible and the smallest possible first sub-tree is already larger than the target size then maxArity should be at most 0 166 int aggregatedShortestExpressionLength = 1; 167 for (int i = 0; i < maxArity; i++) { 168 aggregatedShortestExpressionLength += (from s in grammar.AllowedSymbols(symbol, i) 169 select grammar.MinimalExpressionLength(symbol)).Min(); 170 if (aggregatedShortestExpressionLength > targetSize) { 171 maxArity = i; 172 break; 173 } 174 } 175 if (minArity > maxArity) throw new ArgumentException(); 176 return random.Next(minArity, maxArity + 1); 177 } 178 179 private SymbolicExpressionTreeNode CreateMinimalTree(IRandom random, ISymbolicExpressionGrammar grammar, IEnumerable<Symbol> symbols) { 180 // determine possible symbols that will lead to the smallest possible tree 181 var possibleSymbols = (from s in symbols 182 group s by grammar.MinimalExpressionLength(s) into g 183 orderby g.Key 184 select g).First(); 185 var selectedSymbol = SelectRandomSymbol(random, possibleSymbols); 186 // build minimal tree by recursive application 187 var tree = selectedSymbol.CreateTreeNode(); 188 for (int i = 0; i < grammar.MinSubTrees(selectedSymbol); i++) 189 tree.AddSubTree(CreateMinimalTree(random, grammar, grammar.AllowedSymbols(selectedSymbol, i))); 190 return tree; 191 } 192 193 //private bool IsRecursiveExpansionPossible(Symbol symbol) { 194 // return FindCycle(function, new Stack<IFunction>()); 195 //} 196 197 //private Dictionary<IFunction, bool> inCycle = new Dictionary<IFunction, bool>(); 198 //private bool FindCycle(IFunction function, Stack<IFunction> functionChain) { 199 // if (inCycle.ContainsKey(function)) { 200 // return inCycle[function]; 201 // } else if (IsTerminal(function)) { 202 // inCycle[function] = false; 203 // return false; 204 // } else if (functionChain.Contains(function)) { 205 // inCycle[function] = true; 206 // return true; 207 // } else { 208 // functionChain.Push(function); 209 // bool result = false; 210 // // all slot indexes 211 // for (int i = 0; i < function.MaxSubTrees; i++) { 212 // foreach (IFunction subFunction in GetAllowedSubFunctions(function, i)) { 213 // result |= FindCycle(subFunction, functionChain); 214 // } 215 // } 216 217 // functionChain.Pop(); 218 // inCycle[function] = result; 219 // return result; 220 // } 221 //} 222 80 223 } 81 224 }
Note: See TracChangeset
for help on using the changeset viewer.