Changeset 14352 for trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/GrammarUtils.cs
- Timestamp:
- 10/23/16 18:49:21 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/GrammarUtils.cs
r14342 r14352 25 25 using System.Collections.Generic; 26 26 using System.Linq; 27 28 27 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding { 29 28 public static class GrammarUtils { 29 private static IEnumerable<ISymbol> GetTopmostSymbols(this ISymbolicExpressionGrammarBase grammar) { 30 // build parents list so we can find out the topmost symbol(s) 31 var parents = new Dictionary<ISymbol, List<ISymbol>>(); 32 foreach (var symbol in grammar.Symbols.Where(x => grammar.GetMinimumSubtreeCount(x) > 0)) { 33 var minSubtreeCount = grammar.GetMinimumSubtreeCount(symbol); 34 for (int argIndex = 0; argIndex < minSubtreeCount; ++argIndex) { 35 foreach (var childSymbol in grammar.GetAllowedChildSymbols(symbol, argIndex)) { 36 if (!parents.ContainsKey(childSymbol)) 37 parents[childSymbol] = new List<ISymbol>(); 38 parents[childSymbol].Add(symbol); 39 } 40 } 41 } 42 // the topmost symbols have no parents 43 return parents.Values.SelectMany(x => x).Distinct().Where(x => !parents.ContainsKey(x)); 44 } 30 45 31 46 public static void CalculateMinimumExpressionLengths(ISymbolicExpressionGrammarBase grammar, 32 47 Dictionary<string, int> minimumExpressionLengths) { 33 34 48 minimumExpressionLengths.Clear(); 35 49 //terminal symbols => minimum expression length = 1 36 foreach (var s in grammar.Symbols.Where(s => grammar.GetMinimumSubtreeCount(s) == 0))37 minimumExpressionLengths [s.Name] = 1;50 foreach (var symbol in grammar.Symbols.Where(x => grammar.GetMinimumSubtreeCount(x) == 0)) 51 minimumExpressionLengths.Add(symbol.Name, 1); 38 52 39 var symbolAdded = true; 40 while (symbolAdded) { 41 symbolAdded = false; 42 foreach (var remainingSymbol in grammar.Symbols) { 43 if (minimumExpressionLengths.ContainsKey(remainingSymbol.Name)) continue; 53 foreach (var topSymbol in grammar.GetTopmostSymbols()) { 54 // sort symbols in reverse breadth order (starting from the topSymbol) 55 // each symbol is visited only once (this avoids infinite recursion) 56 var numberedSymbols = new List<Tuple<ISymbol, int>> { Tuple.Create(topSymbol, 0) }; 57 var visited = new HashSet<ISymbol> { topSymbol }; 58 int i = 0, index = 0; 59 while (i < numberedSymbols.Count) { 60 var symbol = numberedSymbols[i].Item1; 61 var minSubtreeCount = grammar.GetMinimumSubtreeCount(symbol); 44 62 45 var arguments = grammar.GetMinimumSubtreeCount(remainingSymbol); 46 int minLength = 1; 63 for (int argIndex = 0; argIndex < minSubtreeCount; ++argIndex) { 64 foreach (var childSymbol in grammar.GetAllowedChildSymbols(symbol, argIndex)) { 65 if (grammar.GetMinimumSubtreeCount(childSymbol) == 0) 66 continue; 47 67 48 foreach (int argumentIndex in Enumerable.Range(0, arguments)) { 49 var capturedMinimumLengths = minimumExpressionLengths; 50 var childSymbols = grammar.GetAllowedChildSymbols(remainingSymbol, argumentIndex) 51 .Where(c => c.InitialFrequency > 0.0 && capturedMinimumLengths.ContainsKey(c.Name)); 68 if (visited.Add(childSymbol)) { 69 numberedSymbols.Add(Tuple.Create(childSymbol, ++index)); 70 } 71 } 72 } 73 ++i; 74 } 75 numberedSymbols.Reverse(); // sort descending by index 52 76 53 if (!childSymbols.Any()) { 54 minLength = -1; 55 break; 56 } 57 var minLengthPerArgument = childSymbols.Min(c => capturedMinimumLengths[c.Name]); 58 minLength += minLengthPerArgument; 77 // going bottom-up (reverse breadth order), we ensure lengths are calculated bottom-up 78 foreach (var symbol in numberedSymbols.Select(x => x.Item1)) { 79 long minLength = 1; 80 for (int argIndex = 0; argIndex < grammar.GetMinimumSubtreeCount(symbol); ++argIndex) { 81 long length = grammar.GetAllowedChildSymbols(symbol, argIndex) 82 .Where(x => minimumExpressionLengths.ContainsKey(x.Name)) 83 .Select(x => minimumExpressionLengths[x.Name]).DefaultIfEmpty(int.MaxValue).Min(); 84 minLength += length; 59 85 } 60 61 if (minLength != -1) { 62 minimumExpressionLengths[remainingSymbol.Name] = minLength; 63 symbolAdded = true; 64 } 86 int oldLength; 87 if (minimumExpressionLengths.TryGetValue(symbol.Name, out oldLength)) 88 minLength = Math.Min(minLength, oldLength); 89 minimumExpressionLengths[symbol.Name] = (int)Math.Min(int.MaxValue, minLength); 65 90 } 66 91 } 67 92 68 //set minLength to int.Max value for all symbols that are not reacheable93 //set minLength to int.MaxValue for all symbols that are not reacheable 69 94 foreach (var remainingSymbols in grammar.Symbols) { 70 95 if (!minimumExpressionLengths.ContainsKey(remainingSymbols.Name)) … … 72 97 } 73 98 } 74 75 99 76 100 public static void CalculateMinimumExpressionDepth(ISymbolicExpressionGrammarBase grammar, … … 82 106 minimumExpressionDepths[s.Name] = 1; 83 107 84 var symbolAdded = true; 85 while (symbolAdded) { 86 symbolAdded = false; 87 foreach (var remainingSymbol in grammar.Symbols) { 88 if (minimumExpressionDepths.ContainsKey(remainingSymbol.Name)) continue; 108 foreach (var topSymbol in grammar.GetTopmostSymbols()) { 109 // sort symbols in reverse breadth order (starting from the topSymbol) 110 // each symbol is visited only once (this avoids infinite recursion) 111 var numberedSymbols = new List<Tuple<ISymbol, int>> { Tuple.Create(topSymbol, 0) }; 112 var visited = new HashSet<ISymbol> { topSymbol }; 113 int i = 0, index = 0; 114 while (i < numberedSymbols.Count) { 115 var symbol = numberedSymbols[i].Item1; 116 var minSubtreeCount = grammar.GetMinimumSubtreeCount(symbol); 89 117 90 var arguments = grammar.GetMinimumSubtreeCount(remainingSymbol); 91 int minDepth = -1; 118 for (int argIndex = 0; argIndex < minSubtreeCount; ++argIndex) { 119 foreach (var childSymbol in grammar.GetAllowedChildSymbols(symbol, argIndex)) { 120 if (grammar.GetMinimumSubtreeCount(childSymbol) == 0) 121 continue; 92 122 93 foreach (int argumentIndex in Enumerable.Range(0, arguments)) { 94 var capturedMinimumDepths = minimumExpressionDepths; 95 var childSymbols = grammar.GetAllowedChildSymbols(remainingSymbol, argumentIndex) 96 .Where(c => c.InitialFrequency > 0.0 && capturedMinimumDepths.ContainsKey(c.Name)); 97 if (!childSymbols.Any()) { 98 minDepth = -1; 99 break; 123 if (visited.Add(childSymbol)) { 124 numberedSymbols.Add(Tuple.Create(childSymbol, ++index)); 125 } 100 126 } 101 var minDepthPerArgument = childSymbols.Min(c => capturedMinimumDepths[c.Name]);102 minDepth = Math.Max(minDepth, 1 + minDepthPerArgument);103 127 } 128 ++i; 129 } 130 numberedSymbols.Reverse(); // sort descending by index 104 131 105 if (minDepth != -1) { 106 minimumExpressionDepths[remainingSymbol.Name] = minDepth; 107 symbolAdded = true; 132 // going bottom-up (reverse breadth order), we ensure depths are calculated bottom-up 133 foreach (var symbol in numberedSymbols.Select(x => x.Item1)) { 134 long minDepth = int.MaxValue; 135 for (int argIndex = 0; argIndex < grammar.GetMinimumSubtreeCount(symbol); ++argIndex) { 136 long depth = grammar.GetAllowedChildSymbols(symbol, argIndex) 137 .Where(x => minimumExpressionDepths.ContainsKey(x.Name)) 138 .Select(x => minimumExpressionDepths[x.Name]).DefaultIfEmpty(int.MaxValue).Min(); 139 minDepth = Math.Min(minDepth, depth + 1); 108 140 } 141 int oldDepth; 142 if (minimumExpressionDepths.TryGetValue(symbol.Name, out oldDepth)) 143 minDepth = Math.Min(minDepth, oldDepth); 144 minimumExpressionDepths[symbol.Name] = (int)Math.Min(int.MaxValue, minDepth); 109 145 } 110 146 }
Note: See TracChangeset
for help on using the changeset viewer.