Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
10/27/13 20:17:17 (11 years ago)
Author:
gkronber
Message:

#2026 worked on random search solver (now all examples are working)

Location:
branches/HeuristicLab.Problems.GPDL/CodeGenerator
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.Problems.GPDL/CodeGenerator/BruteForceCodeGen.cs

    r10080 r10086  
    8181            nextAlternative = (nextAlternative + 1) % subTrees.Length;
    8282          } while (subTrees[nextAlternative] != null && subTrees[nextAlternative].Done);
    83 
    84           // from the nodes which are not done take the first with minimum count
    85           //nextAlternative = (from i in Enumerable.Range(0, subTrees.Length)
    86           //                   where subTrees[i] == null || !subTrees[i].Done
    87           //                   orderby subTrees[i]==null?0:subTrees[i].Count ascending
    88           //                   select i).FirstOrDefault(); // possibly there are no children left that can be tried
    8983        } else {
    9084          // for sequenceNodes update all sub-trees
     
    177171
    178172    private AttributedGrammar CreateGrammarFromAst(GPDefNode ast) {
     173
     174      var nonTerminals = ast.NonTerminals.Select(t => new Symbol(t.Ident, GetSymbolAttributes(t.FormalParameters))).ToArray();
     175      var terminals = ast.Terminals.Select(t => new Symbol(t.Ident, GetSymbolAttributes(t.FormalParameters))).ToArray();
    179176      string startSymbolName = ast.Rules.First().NtSymbol;
    180       var startSymbolNode = ast.NonTerminals.Single(nt => nt.Ident == startSymbolName);
     177
    181178      // create startSymbol
    182       var g = new AttributedGrammar(new Symbol(startSymbolName, ParseSymbolAttributes(startSymbolNode.FormalParameters)));
     179      var startSymbol = nonTerminals.Single(s => s.Name == startSymbolName);
     180      var g = new AttributedGrammar(startSymbol, nonTerminals, terminals);
     181
     182      // add all production rules
    183183      foreach (var rule in ast.Rules) {
    184         // create nt-symbol
    185         var ntSymbolName = rule.NtSymbol;
    186         var ntSymbolNode = ast.NonTerminals.Single(nt => nt.Ident == ntSymbolName);
    187         var attributes = ParseSymbolAttributes(ntSymbolNode.FormalParameters);
    188         var ntSymbol = new Symbol(ntSymbolName, attributes);
    189         foreach (var alt in GetAlternatives(rule.Alternatives)) {
     184        var ntSymbol = nonTerminals.Single(s => s.Name == rule.NtSymbol);
     185        foreach (var alt in GetAlternatives(rule.Alternatives, nonTerminals.Concat(terminals))) {
    190186          g.AddProductionRule(ntSymbol, alt);
    191187        }
     
    196192    }
    197193
    198     private IEnumerable<IAttribute> ParseSymbolAttributes(string formalParameters) {
     194    private IEnumerable<IAttribute> GetSymbolAttributes(string formalParameters) {
    199195      return (from fieldDef in Util.ExtractParameters(formalParameters)
    200196              select new Attribute(fieldDef.Identifier, fieldDef.Type, AttributeType.Parse(fieldDef.RefOrOut))).
     
    202198    }
    203199
    204     private IEnumerable<Sequence> GetAlternatives(AlternativesNode altNode) {
     200    private IEnumerable<Sequence> GetAlternatives(AlternativesNode altNode, IEnumerable<ISymbol> allSymbols) {
    205201      foreach (var alt in altNode.Alternatives) {
    206         yield return GetSequence(alt.Sequence);
    207       }
    208     }
    209 
    210     private Sequence GetSequence(IEnumerable<RuleExprNode> sequence) {
     202        yield return GetSequence(alt.Sequence, allSymbols);
     203      }
     204    }
     205
     206    private Sequence GetSequence(IEnumerable<RuleExprNode> sequence, IEnumerable<ISymbol> allSymbols) {
    211207      Debug.Assert(sequence.All(s => s is CallSymbolNode || s is RuleActionNode));
    212208      var l = new List<ISymbol>();
     
    215211        var actionNode = node as RuleActionNode;
    216212        if (callSymbolNode != null) {
    217           l.Add(new Symbol(callSymbolNode.Ident, ParseSymbolAttributes(callSymbolNode.ActualParameter)));
     213          Debug.Assert(allSymbols.Any(s => s.Name == callSymbolNode.Ident));
     214          // create a new symbol with actual parameters
     215          l.Add(new Symbol(callSymbolNode.Ident, GetSymbolAttributes(callSymbolNode.ActualParameter)));
    218216        } else if (actionNode != null) {
    219217          l.Add(new SemanticSymbol("SEM", actionNode.SrcCode));
     
    313311
    314312      // make sure we first descent into terminal alternatives -> we just order by number of non-terminals in the alternative
    315       var altsWithSemActions = g.GetAlternativesWithSemanticActions(s).OrderBy(alt => alt.Count(symb => g.IsNonTerminal(symb))).ToArray();
     313      var altsWithSemActions = g.GetAlternativesWithSemanticActions(s)
     314        .OrderBy(alt => alt.Count(symb => g.IsNonTerminal(symb))).ToArray();
    316315
    317316      if (altsWithSemActions.Length > 1) {
  • branches/HeuristicLab.Problems.GPDL/CodeGenerator/RandomSearchCodeGen.cs

    r10080 r10086  
    2020namespace ?PROBLEMNAME? {
    2121  public sealed class ?IDENT?Solver {
     22    public sealed class SolverState {
     23      private int currentSeed;
     24      public Random random;
     25      public int depth;
     26      public int steps;
     27      public int maxDepth;
     28      public SolverState(int seed) {
     29        this.currentSeed = seed;
     30      }
     31
     32      public SolverState IncDepth() {
     33        depth++;
     34        if(depth>maxDepth) maxDepth = depth;
     35        return this;
     36      }
     37      public SolverState Prepare() {
     38        this.random = new Random(currentSeed);
     39        depth = 0;
     40        maxDepth = 0;
     41        steps = 0;
     42        return this;
     43      }
     44    }
    2245
    2346    public static void Main(string[] args) {
     
    3861    }
    3962
    40 
    41     private Random seedRandom;
    42     private int currentSeed;
     63    private double TerminalProbForDepth(int depth) {
     64      const double baseProb = 0.05;  // 5% of all samples are only a terminal node
     65      const double probIncPerLevel = 0.05; // for each level the probability to sample a terminal grows by 5%
     66      return baseProb + depth * probIncPerLevel;
     67    }
     68
     69    private SolverState _state;
    4370    private void Start() {
    44       seedRandom = new Random();
     71      var seedRandom = new Random();
    4572      var bestF = ?MAXIMIZATION? ? double.NegativeInfinity : double.PositiveInfinity;
    4673      int n = 0;
     
    5178        // must make sure that calling the start-symbol multiple times in the fitness function always leads to the same path through the grammar
    5279        // so we use a PRNG for generating seeds for a separate PRNG that is reset each time the start symbol is called
    53         currentSeed = seedRandom.Next();
     80       
     81        _state = new SolverState(seedRandom.Next());
     82
    5483        var f = Calculate();
    5584
    5685        n++;
    57         if (IsBetter(f, bestF)) bestF = f;
    58         if (n % 100 == 0) {
     86        if (IsBetter(f, bestF)) {
     87          bestF = f;
     88          Console.WriteLine(""{0}\t{1}\t(depth={2})"", n, bestF, _state.maxDepth);
     89        }
     90        if (n % 1000 == 0) {
    5991          sw.Stop();
    60           Console.WriteLine(""{0}\t{1}\t{2}\t({3:0.00} sols/ms)"", n, bestF, f, 100.0 / sw.ElapsedMilliseconds);
     92          Console.WriteLine(""{0}\t{1}\t{2}\t({3:0.00} sols/ms)"", n, bestF, f, 1000.0 / sw.ElapsedMilliseconds);
    6193          sw.Reset();
    6294          sw.Start();
     
    112144    }
    113145
     146    #region create grammar instance from AST
    114147    private AttributedGrammar CreateGrammarFromAst(GPDefNode ast) {
     148
     149      var nonTerminals = ast.NonTerminals.Select(t => new Symbol(t.Ident, GetSymbolAttributes(t.FormalParameters))).ToArray();
     150      var terminals = ast.Terminals.Select(t => new Symbol(t.Ident, GetSymbolAttributes(t.FormalParameters))).ToArray();
    115151      string startSymbolName = ast.Rules.First().NtSymbol;
    116       var startSymbolNode = ast.NonTerminals.Single(nt => nt.Ident == startSymbolName);
     152
    117153      // create startSymbol
    118       var g = new AttributedGrammar(new Symbol(startSymbolName, ParseSymbolAttributes(startSymbolNode.FormalParameters)));
     154      var startSymbol = nonTerminals.Single(s => s.Name == startSymbolName);
     155      var g = new AttributedGrammar(startSymbol, nonTerminals, terminals);
     156
     157      // add all production rules
    119158      foreach (var rule in ast.Rules) {
    120         // create nt-symbol
    121         var ntSymbolName = rule.NtSymbol;
    122         var ntSymbolNode = ast.NonTerminals.Single(nt => nt.Ident == ntSymbolName);
    123         var attributes = ParseSymbolAttributes(ntSymbolNode.FormalParameters);
    124         var ntSymbol = new Symbol(ntSymbolName, attributes);
    125         foreach (var alt in GetAlternatives(rule.Alternatives)) {
     159        var ntSymbol = nonTerminals.Single(s => s.Name == rule.NtSymbol);
     160        foreach (var alt in GetAlternatives(rule.Alternatives, nonTerminals.Concat(terminals))) {
    126161          g.AddProductionRule(ntSymbol, alt);
    127162        }
     
    132167    }
    133168
    134     private IEnumerable<IAttribute> ParseSymbolAttributes(string formalParameters) {
     169    private IEnumerable<IAttribute> GetSymbolAttributes(string formalParameters) {
    135170      return (from fieldDef in Util.ExtractParameters(formalParameters)
    136171              select new Attribute(fieldDef.Identifier, fieldDef.Type, AttributeType.Parse(fieldDef.RefOrOut))).
     
    138173    }
    139174
    140     private IEnumerable<Sequence> GetAlternatives(AlternativesNode altNode) {
     175    private IEnumerable<Sequence> GetAlternatives(AlternativesNode altNode, IEnumerable<ISymbol> allSymbols) {
    141176      foreach (var alt in altNode.Alternatives) {
    142         yield return GetSequence(alt.Sequence);
    143       }
    144     }
    145 
    146     private Sequence GetSequence(IEnumerable<RuleExprNode> sequence) {
     177        yield return GetSequence(alt.Sequence, allSymbols);
     178      }
     179    }
     180
     181    private Sequence GetSequence(IEnumerable<RuleExprNode> sequence, IEnumerable<ISymbol> allSymbols) {
    147182      Debug.Assert(sequence.All(s => s is CallSymbolNode || s is RuleActionNode));
    148183      var l = new List<ISymbol>();
     
    151186        var actionNode = node as RuleActionNode;
    152187        if (callSymbolNode != null) {
    153           l.Add(new Symbol(callSymbolNode.Ident, ParseSymbolAttributes(callSymbolNode.ActualParameter)));
     188          Debug.Assert(allSymbols.Any(s => s.Name == callSymbolNode.Ident));
     189          // create a new symbol with actual parameters
     190          l.Add(new Symbol(callSymbolNode.Ident, GetSymbolAttributes(callSymbolNode.ActualParameter)));
    154191        } else if (actionNode != null) {
    155192          l.Add(new SemanticSymbol("SEM", actionNode.SrcCode));
     
    158195      return new Sequence(l);
    159196    }
    160 
     197    #endregion
     198
     199    #region helper methods for terminal symbols
    161200    // produces helper methods for the attributes of all terminal nodes
    162201    private string GenerateConstraintMethods(List<SymbolNode> symbols) {
     
    177216          sb.AppendFormat("public {0} GetMax{1}_{2}() {{ return {3}; }}", fieldType, t.Ident, c.Ident, c.RangeMaxExpression).AppendLine();
    178217          sb.AppendFormat("public {0} GetMin{1}_{2}() {{ return {3}; }}", fieldType, t.Ident, c.Ident, c.RangeMinExpression).AppendLine();
     218          sb.AppendFormat("public {0} GetRandom{1}_{2}(SolverState _state) {{ return _state.random.NextDouble() * (GetMax{1}_{2}() - GetMin{1}_{2}()) + GetMin{1}_{2}(); }}", fieldType, t.Ident, c.Ident).AppendLine();
    179219        } else if (c.Type == ConstraintNodeType.Set) {
    180           sb.AppendFormat("public IEnumerable<{0}> GetAllowed{1}_{2}() {{ return {3} }}", fieldType, t.Ident, c.Ident, c.SetExpression).AppendLine();
    181         }
    182       }
    183       return sb.ToString();
    184     }
     220          sb.AppendFormat("public IEnumerable<{0}> GetAllowed{1}_{2}() {{ return {3}; }}", fieldType, t.Ident, c.Ident, c.SetExpression).AppendLine();
     221          sb.AppendFormat("public {0} GetRandom{1}_{2}(SolverState _state) {{ var tmp = GetAllowed{1}_{2}().ToArray(); return tmp[_state.random.Next(tmp.Length)]; }}", fieldType, t.Ident, c.Ident).AppendLine();
     222        }
     223      }
     224      return sb.ToString();
     225    }
     226    #endregion
    185227
    186228    private string GenerateInterpreterSource(AttributedGrammar grammar) {
     
    197239    }
    198240
    199     private string GenerateTerminalInterpreterMethod(ISymbol s) {
    200       var sb = new StringBuilder();
    201       // if the terminal symbol has attributes then we must create values for these attributes
    202       if (!s.Attributes.Any())
    203         sb.AppendFormat("private void {0}(Random random) {{", s.Name);
    204       else
    205         sb.AppendFormat("private void {0}(Random random, {1}) {{", s.Name, s.GetAttributeString());
    206 
    207       // each field must match a formal parameter, assign a value for each parameter
    208       foreach (var element in s.Attributes) {
    209         // only works for "IN SET"-Constraints
    210         sb.AppendFormat("{{ var tmp = GetAllowed{1}_{0}().ToArray(); {0} = tmp[random.Next(tmp.Length)]; }} ", element.Name, s.Name);
    211       }
    212       sb.AppendLine("}");
    213       return sb.ToString();
    214     }
    215 
    216241    private string GenerateInterpreterMethod(AttributedGrammar g, ISymbol s) {
    217242      var sb = new StringBuilder();
     243
    218244      // if this is the start symbol we additionally have to create the method which can be called from the fitness function
    219 
    220245      if (g.StartSymbol.Equals(s)) {
    221246        if (!s.Attributes.Any())
     
    234259          actualParameter = string.Empty;
    235260
    236         sb.AppendFormat("{0}(new Random(currentSeed), {1});", g.StartSymbol.Name, actualParameter).AppendLine();
     261        sb.AppendFormat("{0}(_state.Prepare(), {1});", g.StartSymbol.Name, actualParameter).AppendLine();
    237262        sb.AppendLine("}");
    238263      }
    239264
    240265      if (!s.Attributes.Any())
    241         sb.AppendFormat("private void {0}(Random random) {{", s.Name);
     266        sb.AppendFormat("private void {0}(SolverState _state) {{", s.Name);
    242267      else
    243         sb.AppendFormat("private void {0}(Random random, {1}) {{", s.Name, s.GetAttributeString());
     268        sb.AppendFormat("private void {0}(SolverState _state, {1}) {{", s.Name, s.GetAttributeString());
    244269
    245270      // generate local definitions
     
    250275      var terminalAlts = altsWithSemActions.Where(alt => alt.Count(g.IsNonTerminal) == 0);
    251276      var nonTerminalAlts = altsWithSemActions.Where(alt => alt.Count(g.IsNonTerminal) > 0);
    252       bool hasTerminalAlts = terminalAlts.Count() > 0;
    253       bool hasNonTerminalAlts = nonTerminalAlts.Count() > 0;
     277      bool hasTerminalAlts = terminalAlts.Any();
     278      bool hasNonTerminalAlts = nonTerminalAlts.Any();
    254279
    255280      if (altsWithSemActions.Length > 1) {
     
    261286        // the probability of choosing terminals should depend on the depth of the tree (small likelihood to choose terminals for small depths, large likelihood for large depths)
    262287        if (hasTerminalAlts && hasNonTerminalAlts) {
    263           sb.AppendLine("if(random.NextDouble() < 0.5) {");
     288          sb.AppendLine("if(_state.random.NextDouble() < TerminalProbForDepth(_state.depth)) {");
    264289          // terminals
    265290          sb.AppendLine("// terminals ");
     
    287312
    288313    private void GenerateSwitchStatement(StringBuilder sb, IEnumerable<Sequence> alts) {
    289       sb.AppendFormat("switch(random.Next({0})) {{", alts.Count());
     314      sb.AppendFormat("switch(_state.random.Next({0})) {{", alts.Count());
    290315      // generate a case for each alternative
    291316      int i = 0;
     
    313338      } else {
    314339        if (!s.Attributes.Any())
    315           return string.Format("{0}(random);", s.Name);
     340          return string.Format("{0}(_state.IncDepth()); _state.depth--;", s.Name);
    316341        else
    317           return string.Format("{0}(random, {1});", s.Name, s.GetAttributeString());
    318       }
     342          return string.Format("{0}(_state.IncDepth(), {1}); _state.depth--;", s.Name, s.GetAttributeString());
     343      }
     344    }
     345
     346    private string GenerateTerminalInterpreterMethod(ISymbol s) {
     347      var sb = new StringBuilder();
     348      // if the terminal symbol has attributes then we must samples values for these attributes
     349      if (!s.Attributes.Any())
     350        sb.AppendFormat("private void {0}(SolverState _state) {{", s.Name);
     351      else
     352        sb.AppendFormat("private void {0}(SolverState _state, {1}) {{", s.Name, s.GetAttributeString());
     353
     354      // each field must match a formal parameter, assign a value for each parameter
     355      foreach (var element in s.Attributes) {
     356        sb.AppendFormat("{{ {0} = GetRandom{1}_{0}(_state); }} ", element.Name, s.Name);
     357      }
     358      sb.AppendLine("}");
     359      return sb.ToString();
    319360    }
    320361  }
Note: See TracChangeset for help on using the changeset viewer.