Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/GrammarUtils.cs @ 14342

Last change on this file since 14342 was 14342, checked in by mkommend, 7 years ago

#2685: Refactored calculation of minimum expression length and depth into an separate class. Removed separate initialization code for the grammar caches in the ctor.

File size: 4.6 KB
Line 
1#region License Information
2
3/* HeuristicLab
4 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#endregion
23
24using System;
25using System.Collections.Generic;
26using System.Linq;
27
28namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
29  public static class GrammarUtils {
30
31    public static void CalculateMinimumExpressionLengths(ISymbolicExpressionGrammarBase grammar,
32      Dictionary<string, int> minimumExpressionLengths) {
33
34      minimumExpressionLengths.Clear();
35      //terminal symbols => minimum expression length = 1
36      foreach (var s in grammar.Symbols.Where(s => grammar.GetMinimumSubtreeCount(s) == 0))
37        minimumExpressionLengths[s.Name] = 1;
38
39      var symbolAdded = true;
40      while (symbolAdded) {
41        symbolAdded = false;
42        foreach (var remainingSymbol in grammar.Symbols) {
43          if (minimumExpressionLengths.ContainsKey(remainingSymbol.Name)) continue;
44
45          var arguments = grammar.GetMinimumSubtreeCount(remainingSymbol);
46          int minLength = 1;
47
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));
52
53            if (!childSymbols.Any()) {
54              minLength = -1;
55              break;
56            }
57            var minLengthPerArgument = childSymbols.Min(c => capturedMinimumLengths[c.Name]);
58            minLength += minLengthPerArgument;
59          }
60
61          if (minLength != -1) {
62            minimumExpressionLengths[remainingSymbol.Name] = minLength;
63            symbolAdded = true;
64          }
65        }
66      }
67
68      //set minLength to int.Maxvalue for all symbols that are not reacheable
69      foreach (var remainingSymbols in grammar.Symbols) {
70        if (!minimumExpressionLengths.ContainsKey(remainingSymbols.Name))
71          minimumExpressionLengths[remainingSymbols.Name] = int.MaxValue;
72      }
73    }
74
75
76    public static void CalculateMinimumExpressionDepth(ISymbolicExpressionGrammarBase grammar,
77      Dictionary<string, int> minimumExpressionDepths) {
78
79      minimumExpressionDepths.Clear();
80      //terminal symbols => minimum expression depth = 1
81      foreach (var s in grammar.Symbols.Where(s => grammar.GetMinimumSubtreeCount(s) == 0))
82        minimumExpressionDepths[s.Name] = 1;
83
84      var symbolAdded = true;
85      while (symbolAdded) {
86        symbolAdded = false;
87        foreach (var remainingSymbol in grammar.Symbols) {
88          if (minimumExpressionDepths.ContainsKey(remainingSymbol.Name)) continue;
89
90          var arguments = grammar.GetMinimumSubtreeCount(remainingSymbol);
91          int minDepth = -1;
92
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;
100            }
101            var minDepthPerArgument = childSymbols.Min(c => capturedMinimumDepths[c.Name]);
102            minDepth = Math.Max(minDepth, 1 + minDepthPerArgument);
103          }
104
105          if (minDepth != -1) {
106            minimumExpressionDepths[remainingSymbol.Name] = minDepth;
107            symbolAdded = true;
108          }
109        }
110      }
111
112      //set minDepth to int.Maxvalue for all symbols that are not reacheable
113      foreach (var remainingSymbols in grammar.Symbols) {
114        if (!minimumExpressionDepths.ContainsKey(remainingSymbols.Name))
115          minimumExpressionDepths[remainingSymbols.Name] = int.MaxValue;
116      }
117    }
118  }
119}
Note: See TracBrowser for help on using the repository browser.