1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 |
|
---|
4 | namespace HeuristicLab.Problems.ProgramSynthesis.Push.Problem {
|
---|
5 | using HeuristicLab.BenchmarkSuite;
|
---|
6 | using HeuristicLab.BenchmarkSuite.Problems;
|
---|
7 | using HeuristicLab.Core;
|
---|
8 | using HeuristicLab.Optimization;
|
---|
9 | using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
|
---|
10 | using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
|
---|
11 | using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
|
---|
12 |
|
---|
13 | public static class PushEvaluator {
|
---|
14 | public static double Evaluate(IPushInterpreter interpreter, PushProgram program, Example example, double worstResult) {
|
---|
15 | interpreter.BooleanStack.Push(example.InputBoolean);
|
---|
16 | interpreter.IntegerStack.Push(example.InputInt);
|
---|
17 | interpreter.FloatStack.Push(example.InputFloat);
|
---|
18 |
|
---|
19 | interpreter.Run(program);
|
---|
20 |
|
---|
21 | return GetDiff(example.OutputInt, interpreter.IntegerStack, worstResult, LongDiffer)
|
---|
22 | + GetDiff(example.OutputFloat, interpreter.FloatStack, worstResult, DoubleDiffer)
|
---|
23 | + GetDiff(example.OutputBoolean, interpreter.BooleanStack, worstResult, BooleanDiffer);
|
---|
24 | }
|
---|
25 |
|
---|
26 | public static double Evaluate(PushProgram program, PushInterpreterPool pool, IRandom random, Data data, int startIndex, int endIndex) {
|
---|
27 | if (endIndex - startIndex <= 0) return default(double);
|
---|
28 | var result = 0d;
|
---|
29 |
|
---|
30 | using (var interpreter = pool.Create(random)) {
|
---|
31 | for (var i = startIndex; i < endIndex; i++) {
|
---|
32 | result += Evaluate(interpreter, program, data.Examples[i], data.WorstResult);
|
---|
33 | interpreter.Clear();
|
---|
34 | }
|
---|
35 | }
|
---|
36 |
|
---|
37 | return result / (endIndex - startIndex);
|
---|
38 | }
|
---|
39 |
|
---|
40 | public static double Evaluate(Individual individual, PushInterpreterPool pool, IRandom random, Data data, int startIndex, int endIndex) {
|
---|
41 | var program = individual.PushProgram(pool.PushGpConfiguration.EnabledExpressions as IReadOnlyList<string>);
|
---|
42 | return Evaluate(program, pool, random, data, startIndex, endIndex);
|
---|
43 | }
|
---|
44 |
|
---|
45 | private static double DoubleDiffer(double a, double b) {
|
---|
46 | var result = a - b;
|
---|
47 |
|
---|
48 | return result == double.MinValue ? double.MaxValue : Math.Abs(result);
|
---|
49 | }
|
---|
50 |
|
---|
51 | private static double LongDiffer(long a, long b) {
|
---|
52 | var result = a - b;
|
---|
53 |
|
---|
54 | return result == long.MinValue ? long.MaxValue : Math.Abs(result);
|
---|
55 | }
|
---|
56 |
|
---|
57 | private static double BooleanDiffer(bool a, bool b) {
|
---|
58 | return a && b ? 0 : a || b ? 1 : 2;
|
---|
59 | }
|
---|
60 |
|
---|
61 | private static double GetDiff<T>(IReadOnlyList<T> estimated, IStack<T> resultStack, double worstResult, Func<T, T, double> differ)
|
---|
62 | where T : IComparable {
|
---|
63 |
|
---|
64 | var count = Math.Min(estimated.Count, resultStack.Count);
|
---|
65 | var result = resultStack.Peek(count);
|
---|
66 | var comparableLength = Math.Min(estimated.Count, result.Length);
|
---|
67 | var diff = 0d;
|
---|
68 |
|
---|
69 | for (var i = 0; i < comparableLength; i++) {
|
---|
70 | diff += Math.Min(differ(estimated[i], result[0]), worstResult);
|
---|
71 | }
|
---|
72 |
|
---|
73 | if (estimated.Count > result.Length) {
|
---|
74 | diff += worstResult * (estimated.Count - comparableLength);
|
---|
75 | }
|
---|
76 |
|
---|
77 | return diff;
|
---|
78 | }
|
---|
79 | }
|
---|
80 | }
|
---|