Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.Algorithms.PushGP/HeuristicLab.Algorithms.PushGP/Generators/CodeGenerator.cs @ 14513

Last change on this file since 14513 was 14513, checked in by pkimmesw, 7 years ago

#2665 Added Problem.ProgramSynthesis Project, Fixed Expression Issues, Fixed Code Generation

File size: 3.1 KB
Line 
1namespace HeuristicLab.Algorithms.PushGP.Generators {
2  using System;
3  using System.Collections.Generic;
4  using System.Linq;
5  using System.Threading;
6
7  using HeuristicLab.Algorithms.PushGP.Data.Random;
8  using HeuristicLab.Algorithms.PushGP.Expressions;
9  using HeuristicLab.Core;
10  using HeuristicLab.Random;
11
12  /// <summary>
13  ///     The following is the standard Push random code generation algorithm, which is used for the CODE.RAND instruction.
14  ///     It may also be useful for the initialization of programs in evolutionary computation systems, and it is used for
15  ///     this purpose in PushGP.
16  ///     It produces a uniform distribution of sizes and what seems to be a reasonable distribution of shapes, in a
17  ///     reasonable amount of time.
18  /// </summary>
19  /// <see cref="http://faculty.hampshire.edu/lspector/push3-description.html#RandomCode" />
20  public static class CodeGenerator {
21    private static readonly ThreadLocal<IRandom> random = RandomFactory.GetRandom();
22
23    /// <summary>
24    ///     Generates a random program with a given max size
25    /// </summary>
26    /// <param name="maxPoints"></param>
27    /// <returns>Returns an ExpandExpression if maxPoints smaller or equal to Configuration.MaxProgramPoints and Noop otherwise</returns>
28    public static ExecExpandExpression RandomProgram(int maxPoints, IDictionary<string, Expression> customExpressions = null) {
29      var code = RandomCode(maxPoints, customExpressions).ToArray();
30
31      return new ExecExpandExpression(code);
32    }
33
34    public static IEnumerable<Expression> RandomCode(int maxPoints, IDictionary<string, Expression> customExpressions = null) {
35      var actualPoints = random.Value.Next(1, Math.Max(1, maxPoints));
36
37      return RandomCodeWithSize(actualPoints, customExpressions);
38    }
39
40    private static IEnumerable<Expression> RandomCodeWithSize(
41      int points,
42      IDictionary<string, Expression> customExpressions = null) {
43      if (points == 1) {
44        var customCount = customExpressions == null ? 0 : customExpressions.Count - 1;
45        var index = random.Value.Next(0, ExpressionTable.Count + customCount - 1);
46        return new[] { CreateExpression(index, customExpressions) };
47      }
48
49      var sizesThisLevel = Decompose(points - 1, points - 1);
50      return sizesThisLevel.SelectMany(size => RandomCodeWithSize(size, customExpressions)).Shuffle(random.Value);
51    }
52
53    private static IEnumerable<int> Decompose(int number, int maxParts) {
54      if ((number == 1) || (maxParts == 1)) return new[] { number };
55      var thisPart = random.Value.Next(1, number - 1);
56      return new[] { thisPart }.Concat(Decompose(number - thisPart, maxParts - 1));
57    }
58
59    private static Expression CreateExpression(int index, IDictionary<string, Expression> customExpressions = null) {
60      if ((index >= 0) && (index < ExpressionTable.Count)) return ExpressionTable.GetExpression(index);
61
62      if (customExpressions == null) throw new IndexOutOfRangeException();
63      return new NameDefineXExecExpression(customExpressions.ElementAt(index - (ExpressionTable.Count - 1)).Key);
64    }
65  }
66}
Note: See TracBrowser for help on using the repository browser.