source: branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/ExhaustiveDepthFirstSearch.cs @ 11732

Last change on this file since 11732 was 11732, checked in by gkronber, 5 years ago

#2283: refactoring and bug fixes

File size: 2.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using HeuristicLab.Problems.GrammaticalOptimization;
6
7namespace HeuristicLab.Algorithms.GrammaticalOptimization {
8  public class ExhaustiveDepthFirstSearch {
9    public event Action<string, double> FoundNewBestSolution;
10    public event Action<string, double> SolutionEvaluated;
11
12    private readonly int maxLen;
13    private readonly Stack<Sequence> stack = new Stack<Sequence>();
14    private readonly IProblem problem;
15
16    public ExhaustiveDepthFirstSearch(IProblem problem, int maxLen) {
17      this.maxLen = maxLen;
18      this.problem = problem;
19    }
20
21    public void Run(int maxIterations) {
22      double bestQuality = double.MinValue;
23      stack.Push(new Sequence(problem.Grammar.SentenceSymbol));
24      var sentences = GenerateLanguage(problem.Grammar);
25      var sentenceEnumerator = sentences.GetEnumerator();
26      for (int i = 0; sentenceEnumerator.MoveNext() && i < maxIterations; i++) {
27        var sentence = sentenceEnumerator.Current.ToString();
28        var quality = problem.Evaluate(sentence) / problem.BestKnownQuality(maxLen);
29        RaiseSolutionEvaluated(sentence, quality);
30
31        if (quality > bestQuality) {
32          bestQuality = quality;
33          RaiseFoundNewBestSolution(sentence, quality);
34        }
35      }
36    }
37
38    // create sentences lazily
39    private IEnumerable<Sequence> GenerateLanguage(IGrammar grammar) {
40      while (stack.Any()) {
41        var phrase = stack.Pop();
42
43        char nt = phrase.FirstNonTerminal;
44        var alts = grammar.GetAlternatives(nt);
45        foreach (var alt in alts) {
46          var newPhrase = new Sequence(phrase);
47          newPhrase.ReplaceAt(newPhrase.FirstNonTerminalIndex, 1, alt);
48
49          if (newPhrase.IsTerminal && newPhrase.Length <= maxLen) {
50            yield return newPhrase;
51          } else if (grammar.MinPhraseLength(newPhrase) <= maxLen) {
52            stack.Push(newPhrase);
53          }
54        }
55      }
56    }
57
58
59    private void RaiseSolutionEvaluated(string sentence, double quality) {
60      var handler = SolutionEvaluated;
61      if (handler != null) handler(sentence, quality);
62    }
63    private void RaiseFoundNewBestSolution(string sentence, double quality) {
64      var handler = FoundNewBestSolution;
65      if (handler != null) handler(sentence, quality);
66    }
67  }
68}
Note: See TracBrowser for help on using the repository browser.