Changeset 10392
- Timestamp:
- 01/24/14 17:54:35 (11 years ago)
- Location:
- branches/HeuristicLab.Problems.GPDL
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.Problems.GPDL/CodeGenerator/BruteForceCodeGen.cs
r10388 r10392 10 10 11 11 private string solverTemplate = @" 12 12 13 namespace ?PROBLEMNAME? { 13 14 public sealed class ?IDENT?Solver { 14 public class SearchTreeNode {15 public bool ready = false;16 public SearchTreeNode[] children;17 public int state;18 public int nextAltIdx;19 15 20 public SearchTreeNode(int state) { 21 // do not initialize children yet to save mem 22 nextAltIdx = 0; 16 private readonly ?IDENT?Problem problem; 17 private readonly Random random; 18 19 private IEnumerable<Tree> GenerateTrees(int parentState, int depth) { 20 if(depth<=1) { 21 if(Grammar.subtreeCount[parentState] == 0) 22 foreach(var terminal in CreateTerminalNodes(parentState, problem)) 23 yield return terminal; 24 } else if(Grammar.subtreeCount[parentState] == 1) { 25 for(int altIdx = 0; altIdx < Grammar.transition[parentState].Length; altIdx++) { 26 var targetState = Grammar.transition[parentState][altIdx]; 27 foreach(var subtree in GenerateTrees(targetState, depth - 1)) { 28 var solution = new Tree(altIdx, new Tree[1] {subtree}); 29 yield return solution; 30 } 31 } 32 } else if(Grammar.subtreeCount[parentState] > 1) { 33 var trees = new IEnumerable<Tree>[Grammar.subtreeCount[parentState]]; 34 for(int subtreeIdx = 0; subtreeIdx < Grammar.subtreeCount[parentState]; subtreeIdx++) { 35 trees[subtreeIdx] = GenerateTrees(Grammar.transition[parentState][subtreeIdx], depth - 1); 36 } 37 foreach(var e in CartesianProduct(trees)) { 38 yield return new Tree(-1, e.ToArray()); // altIdx is ignored 39 } 40 } 41 } 42 43 public IEnumerable<IEnumerable<Tree>> CartesianProduct(IEnumerable<IEnumerable<Tree>> sets) { 44 if(sets.Count() == 1) { 45 foreach(var e in sets.First()) { 46 yield return new Tree[] {e}; 47 } 23 48 } 24 public SearchTreeNode GetNextNode() { 25 if(children == null) { 26 int nChildren = Grammar.subtreeCount[state] == 1 ? Grammar.transitions[state].Length : Grammar.subtreeCount[state]; 27 children = new SearchTreeNode[nChildren]; 28 } 29 if(children[nextAltIdx] == null) { 30 children[nextAltIdx] = 49 else { 50 var firstSet = sets.First(); 51 foreach(var e in firstSet) { 52 foreach(var p in CartesianProduct(sets.Skip(1))) { 53 yield return new Tree[] {e}.Concat(p); 54 } 31 55 } 32 56 } 33 57 } 34 58 35 36 private readonly ?IDENT?Problem problem; 37 private readonly Random random; 38 private SearchTreeNode searchTree = null; 39 40 private IEnumerable<Tree> GenerateTrees(int maxDepth) { 41 if(searchTree==null) searchTree = new SearchTreeNode(0); 42 43 } 44 45 private Tree GenerateTree(SearchTreeNode node) { 46 curDepth += 1; 47 steps += 1; 48 depth = Math.Max(depth, curDepth); 49 Tree t = null; 50 51 // terminals 52 if(Grammar.subtreeCount[state] == 0) { 53 t = CreateTerminalNode(state, random, problem); 54 } else { 55 // if the symbol has alternatives then we must choose one randomly (only one sub-tree in this case) 56 if(Grammar.subtreeCount[state] == 1) { 57 var targetStates = Grammar.transition[state]; 58 var altIdx = SampleAlternative(random, state, curDepth); 59 var alternative = SampleTree(targetStates[altIdx], ref steps, ref curDepth, ref depth); 60 t = new Tree(altIdx, new Tree[] { alternative }); 61 } else { 62 // if the symbol contains only one sequence we must use create sub-trees for each symbol in the sequence 63 Tree[] subtrees = new Tree[Grammar.subtreeCount[state]]; 64 for(int i = 0; i < Grammar.subtreeCount[state]; i++) { 65 subtrees[i] = SampleTree(Grammar.transition[state][i], ref steps, ref curDepth, ref depth); 66 } 67 t = new Tree(-1, subtrees); // alternative index is ignored 68 } 69 } 70 curDepth -=1; 71 return t; 72 } 73 74 private static Tree CreateTerminalNode(int state, Random random, ?IDENT?Problem problem) { 59 private static IEnumerable<Tree> CreateTerminalNodes(int state, ?IDENT?Problem problem) { 75 60 switch(state) { 76 61 ?CREATETERMINALNODECODE? 77 62 default: { throw new ArgumentException(""Unknown state index"" + state); } 78 63 } 79 }80 81 private int NextAlternative(SearchTreeNode node) {82 ?RETURNNEXTALTERNATIVECODE?83 64 } 84 65 … … 95 76 96 77 private void Start() { 78 const int MAX_SECONDS = 100000; 97 79 var bestF = ?MAXIMIZATION? ? double.NegativeInfinity : double.PositiveInfinity; 98 80 int n = 0; … … 100 82 long sumSize = 0; 101 83 var sumF = 0.0; 84 var terminationTimer = new Stopwatch(); 102 85 var sw = new System.Diagnostics.Stopwatch(); 103 86 sw.Start(); 104 for(int d = 1; d < 20; d++) { 105 foreach(var t in GenerateTrees(d)) { 87 terminationTimer.Start(); 88 for(int depth = 1; terminationTimer.Elapsed.TotalSeconds < MAX_SECONDS; depth ++) { 89 Console.WriteLine(""Depth {0}:"", depth); 90 foreach(var t in GenerateTrees(0, depth)) { 106 91 var f = problem.Evaluate(t); 107 92 //t.PrintTree(0); Console.WriteLine(); 93 var size = t.GetSize(); 94 sumSize += size; 95 sumDepth += depth; 108 96 n++; 109 97 sumF += f; 110 98 if (problem.IsBetter(f, bestF)) { 111 99 bestF = f; 112 Console.WriteLine(""{0}\t{1}\t(size={2}, depth={3})"", n, bestF, 0, 0);100 Console.WriteLine(""{0}\t{1}\t(size={2}, depth={3})"", n, bestF, size, depth); 113 101 } 114 102 if (n % 1000 == 0) { 115 103 sw.Stop(); 116 Console.WriteLine(""{0}\tbest: {1:0.000}\t(avg: {2:0.000})\t(avg size: {3:0.0})\t(avg. depth: {4:0.0})\t({5:0.00} sols/ms)"", n, bestF, sumF/1000.0, sumSize/1000.0, sumDepth/1000.0, 1000.0 / sw.ElapsedMilliseconds); 104 Console.WriteLine(""{6,5:0.0s}: {0}\tbest: {1:0.000}\t(avg: {2:0.000})\t(avg size: {3:0.0})\t(avg. depth: {4:0.0})\t({5:0.00} sols/ms)"", 105 n, bestF, sumF/1000.0, sumSize/1000.0, sumDepth/1000.0, 1000.0 / sw.ElapsedMilliseconds, terminationTimer.Elapsed.TotalSeconds); 117 106 sumSize = 0; 118 107 sumDepth = 0; 119 108 sumF = 0.0; 120 109 sw.Restart(); 110 if(terminationTimer.Elapsed.TotalSeconds >= MAX_SECONDS) break; 121 111 } 122 112 } … … 130 120 solverSourceCode.Append(solverTemplate) 131 121 .Replace("?MAXIMIZATION?", maximization.ToString().ToLowerInvariant()) 132 .Replace("?SAMPLEALTERNATIVECODE?", GenerateSampleAlternativeSource(grammar))133 122 .Replace("?CREATETERMINALNODECODE?", GenerateCreateTerminalCode(grammar, terminals)) 134 123 ; 135 124 136 125 problemSourceCode.Append(solverSourceCode.ToString()); 137 }138 139 140 141 private string GenerateSampleAlternativeSource(IGrammar grammar) {142 Debug.Assert(grammar.Symbols.First().Equals(grammar.StartSymbol));143 var sb = new SourceBuilder();144 int stateCount = 0;145 foreach (var s in grammar.Symbols) {146 sb.AppendFormat("case {0}: ", stateCount++);147 if (grammar.IsTerminal(s)) {148 // ignore149 } else {150 var terminalAltIndexes = grammar.GetAlternatives(s)151 .Select((alt, idx) => new { alt, idx })152 .Where((p) => p.alt.All(symb => grammar.IsTerminal(symb)))153 .Select(p => p.idx);154 var nonTerminalAltIndexes = grammar.GetAlternatives(s)155 .Select((alt, idx) => new { alt, idx })156 .Where((p) => p.alt.Any(symb => grammar.IsNonTerminal(symb)))157 .Select(p => p.idx);158 var hasTerminalAlts = terminalAltIndexes.Any();159 var hasNonTerminalAlts = nonTerminalAltIndexes.Any();160 if (hasTerminalAlts && hasNonTerminalAlts) {161 sb.Append("if(random.NextDouble() < TerminalProbForDepth(depth)) {").BeginBlock();162 GenerateReturnStatement(terminalAltIndexes, sb);163 sb.Append("} else {");164 GenerateReturnStatement(nonTerminalAltIndexes, sb);165 sb.Append("}").EndBlock();166 } else {167 GenerateReturnStatement(grammar.NumberOfAlternatives(s), sb);168 }169 }170 }171 return sb.ToString();172 126 } 173 127 … … 179 133 if (grammar.IsTerminal(s)) { 180 134 sb.AppendFormat("case {0}: {{", allSymbols.IndexOf(s)).BeginBlock(); 181 sb.AppendFormat("var t = new {0}Tree();", s.Name).AppendLine();182 135 var terminal = terminals.Single(t => t.Ident == s.Name); 136 if (terminal.Constraints.Any(c => c.Type == ConstraintNodeType.Range)) { 137 throw new NotSupportedException("Sorry the brute force solver does not support RANGE constraints"); 138 } 139 sb.AppendFormat("{0}Tree t = null;", terminal.Ident).AppendLine(); 140 // create nested loop to produce all combinations of values (only set constraints) 183 141 foreach (var constr in terminal.Constraints) { 184 if (constr.Type == ConstraintNodeType.Set) { 185 sb.Append("{").BeginBlock(); 186 sb.AppendLine("throw new NotImplementedException(\"Enumeration of terminal values is not implemented.\");"); 187 sb.AppendFormat("//var elements = problem.GetAllowed{0}_{1}().ToArray();", terminal.Ident, constr.Ident).AppendLine(); 188 sb.AppendFormat("//t.{0} = elements[random.Next(elements.Length)]; ", constr.Ident).EndBlock(); 189 sb.AppendLine("}"); 190 } else { 191 sb.Append("{").BeginBlock(); 192 sb.AppendLine("throw new NotSupportedException(\"The brute force solver does not support RANGE constraints\");"); 193 sb.AppendLine("}"); 194 } 142 sb.AppendFormat("foreach(var {1} in problem.GetAllowed{0}_{1}()) {{;", terminal.Ident, constr.Ident).BeginBlock(); 195 143 } 196 sb.AppendLine("return t;").EndBlock(); 197 sb.Append("}"); 144 sb.AppendFormat("t = new {0}Tree();", terminal.Ident).AppendLine(); 145 146 foreach (var constr in terminal.Constraints.Reverse()) { 147 sb.AppendFormat("t.{0} = {0};", constr.Ident).EndBlock(); 148 sb.AppendLine("}"); 149 } 150 151 sb.AppendLine("yield return t; ").EndBlock(); 152 153 sb.AppendLine(" break; }"); 198 154 } 199 155 } 200 156 return sb.ToString(); 201 157 } 202 203 private void GenerateReturnStatement(IEnumerable<int> idxs, SourceBuilder sb) {204 if (idxs.Count() == 1) {205 sb.AppendFormat("return {0};", idxs.Single()).AppendLine();206 } else {207 var idxStr = idxs.Aggregate(string.Empty, (str, idx) => str + idx + ", ");208 sb.AppendFormat("return new int[] {{ {0} }}[random.Next({1})]; ", idxStr, idxs.Count()).AppendLine();209 }210 }211 212 private void GenerateReturnStatement(int nAlts, SourceBuilder sb) {213 if (nAlts > 1) {214 sb.AppendFormat("return random.Next({0});", nAlts).AppendLine();215 } else if (nAlts == 1) {216 sb.AppendLine("return 0; ");217 } else {218 sb.AppendLine("throw new InvalidProgramException();");219 }220 }221 158 } 222 159 } -
branches/HeuristicLab.Problems.GPDL/CodeGenerator/ProblemCodeGen.cs
r10388 r10392 14 14 using System; 15 15 using System.Text.RegularExpressions; 16 using System.Diagnostics; 16 17 "; 17 18 … … 63 64 // leave subtrees uninitialized 64 65 } 65 public Tree(int altIdx, Tree[] subtrees ) {66 public Tree(int altIdx, Tree[] subtrees = null) { 66 67 this.altIdx = altIdx; 67 68 this.subtrees = subtrees; 69 } 70 public int GetSize() { 71 if(subtrees==null) return 1; 72 else return 1 + subtrees.Sum(t=>t.GetSize()); 73 } 74 public int GetDepth() { 75 if(subtrees==null) return 1; 76 else return 1 + subtrees.Max(t=>t.GetDepth()); 77 } 78 public void PrintTree(int curState) { 79 Console.Write(""{0} "", Grammar.symb[curState]); 80 if(subtrees != null) { 81 if(subtrees.Length==1) { 82 subtrees[0].PrintTree(Grammar.transition[curState][altIdx]); 83 } else { 84 for(int i=0;i<subtrees.Length;i++) { 85 subtrees[i].PrintTree(Grammar.transition[curState][i]); 86 } 87 } 88 } 68 89 } 69 90 } … … 294 315 } 295 316 296 private void GenerateSwitchStatement(IEnumerable<Sequence> alts, SourceBuilder sb) 297 { 317 private void GenerateSwitchStatement(IEnumerable<Sequence> alts, SourceBuilder sb) { 298 318 sb.Append("switch(_t.altIdx) {").BeginBlock(); 299 319 // generate a case for each alternative … … 340 360 } 341 361 342 362 343 363 344 364 private string GenerateTransitionTable(IGrammar grammar) { -
branches/HeuristicLab.Problems.GPDL/Examples/symbreg Koza.txt
r10338 r10392 106 106 | Multiplication<<row, out val>> 107 107 | Var<<out varName>> SEM << val = GetValue(x, varName, row); >> 108 | ERC<<out val>>108 /* | ERC<<out val>> */ 109 109 . 110 110 -
branches/HeuristicLab.Problems.GPDL/HeuristicLab.Problems.GPDL.sln
r10338 r10392 1 1 2 2 Microsoft Visual Studio Solution File, Format Version 12.00 3 # Visual Studio 2013 4 VisualStudioVersion = 12.0.21005.1 5 MinimumVisualStudioVersion = 10.0.40219.1 3 # Visual Studio 2012 6 4 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3768D612-38EB-47D8-9E79-75D8E5AB00A8}" 7 5 ProjectSection(SolutionItems) = preProject … … 9 7 Performance1.psess = Performance1.psess 10 8 PreBuildEvent.cmd = PreBuildEvent.cmd 9 TestAnt.bat = TestAnt.bat 11 10 TestExamples.bat = TestExamples.bat 12 11 EndProjectSection … … 117 116 {E2060931-6700-464B-9E82-50846D7AE4E9} = {3768D612-38EB-47D8-9E79-75D8E5AB00A8} 118 117 EndGlobalSection 118 GlobalSection(Performance) = preSolution 119 HasPerformanceSessions = true 120 EndGlobalSection 119 121 EndGlobal -
branches/HeuristicLab.Problems.GPDL/TestExamples.bat
r10385 r10392 1 del *.exe 2 del *.cs 3 1 4 for /f "delims=" %%i in ('dir /b /s Examples\*.txt') do ( 2 5 GpdlCompiler\bin\Debug\GpdlCompiler.exe "%%i" … … 4 7 5 8 for /f "delims=" %%i in ('dir /b *.cs') do ( 6 csc /optimize+ "%%i"9 csc /optimize+ /debug- "%%i" 7 10 ) 8 11
Note: See TracChangeset
for help on using the changeset viewer.