source: branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/ExhaustiveBreadthFirstSearch.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 ExhaustiveBreadthFirstSearch {
9    public event Action<string, double> FoundNewBestSolution;
10    public event Action<string, double> SolutionEvaluated;
11
12    private readonly int maxLen;
13    private readonly Queue<Sequence> bfsQueue = new Queue<Sequence>();
14    private readonly IProblem problem;
15
16    public ExhaustiveBreadthFirstSearch(IProblem problem, int maxLen) {
17      this.problem = problem;
18      this.maxLen = maxLen;
19    }
20
21    public void Run(int maxIterations) {
22      double bestQuality = double.MinValue;
23      bfsQueue.Enqueue(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 (bfsQueue.Any()) {
41        var phrase = bfsQueue.Dequeue();
42
43        char nt = phrase.FirstNonTerminal;
44        int ntIdx;
45
46        var alts = grammar.GetAlternatives(nt);
47        foreach (var alt in alts) {
48          var newPhrase = new Sequence(phrase);
49          newPhrase.ReplaceAt(newPhrase.FirstNonTerminalIndex, 1, alt);
50          if (newPhrase.IsTerminal && newPhrase.Length <= maxLen) {
51            yield return newPhrase;
52          } else if (grammar.MinPhraseLength(newPhrase) <= maxLen) {
53            bfsQueue.Enqueue(newPhrase);
54          }
55        }
56      }
57    }
58
59
60    private void RaiseSolutionEvaluated(string sentence, double quality) {
61      var handler = SolutionEvaluated;
62      if (handler != null) handler(sentence, quality);
63    }
64    private void RaiseFoundNewBestSolution(string sentence, double quality) {
65      var handler = FoundNewBestSolution;
66      if (handler != null) handler(sentence, quality);
67    }
68  }
69}
Note: See TracBrowser for help on using the repository browser.