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.Problems.ProgramSynthesis.Push.Expressions;
|
---|
9 | using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
|
---|
10 | using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
|
---|
11 |
|
---|
12 | public static class PushEvaluator {
|
---|
13 | public static double Evaluate(IPushInterpreter interpreter, PushProgram program, Example example, double worstResult) {
|
---|
14 | interpreter.BooleanStack.Push(example.InputBoolean);
|
---|
15 | interpreter.IntegerStack.Push(example.InputInt);
|
---|
16 | interpreter.FloatStack.Push(example.InputFloat);
|
---|
17 |
|
---|
18 | interpreter.Run(program);
|
---|
19 |
|
---|
20 | var result = GetDiff(example.OutputInt, interpreter.IntegerStack, worstResult, LongDiffer)
|
---|
21 | + GetDiff(example.OutputFloat, interpreter.FloatStack, worstResult, DoubleDiffer)
|
---|
22 | + GetDiff(example.OutputBoolean, interpreter.BooleanStack, worstResult, BooleanDiffer);
|
---|
23 |
|
---|
24 | return result;
|
---|
25 | }
|
---|
26 |
|
---|
27 | public static EvaluationResult Evaluate(PushProgram program, PushInterpreterPool pool, IRandom random, Data data, int startIndex, int endIndex) {
|
---|
28 | var length = endIndex - startIndex;
|
---|
29 | if (length <= 0) return null;
|
---|
30 |
|
---|
31 | var evaluationResult = new EvaluationResult(length);
|
---|
32 |
|
---|
33 | using (var interpreter = pool.Create(random)) {
|
---|
34 | for (var i = startIndex; i < endIndex; i++) {
|
---|
35 | var result = Evaluate(interpreter, program, data.Examples[i], data.WorstResult);
|
---|
36 | evaluationResult.ExampleQualities[i - startIndex] = result;
|
---|
37 | evaluationResult.TotalQuality += result;
|
---|
38 | interpreter.Reset();
|
---|
39 | }
|
---|
40 | }
|
---|
41 |
|
---|
42 | evaluationResult.TotalQuality /= length;
|
---|
43 |
|
---|
44 | return evaluationResult;
|
---|
45 | }
|
---|
46 |
|
---|
47 | //public static EvaluationResult Evaluate(Individual individual, PushInterpreterPool pool, IRandom random, Data data, int startIndex, int endIndex) {
|
---|
48 | // var program = individual.ToPushProgram(pool.PushGpConfiguration);
|
---|
49 | // return Evaluate(program, pool, random, data, startIndex, endIndex);
|
---|
50 | //}
|
---|
51 |
|
---|
52 | private static double DoubleDiffer(double a, double b) {
|
---|
53 | var result = a - b;
|
---|
54 |
|
---|
55 | if (result == double.MinValue || double.IsPositiveInfinity(result) || double.IsNaN(result))
|
---|
56 | return double.MaxValue;
|
---|
57 |
|
---|
58 | if (result == double.MaxValue || double.IsNegativeInfinity(result))
|
---|
59 | return double.MinValue;
|
---|
60 |
|
---|
61 | return Math.Abs(result);
|
---|
62 | }
|
---|
63 |
|
---|
64 | private static double LongDiffer(long a, long b) {
|
---|
65 | var result = a - b;
|
---|
66 |
|
---|
67 | return result == long.MinValue ? long.MaxValue : Math.Abs(result);
|
---|
68 | }
|
---|
69 |
|
---|
70 | private static double BooleanDiffer(bool a, bool b) {
|
---|
71 | return a && b ? 0 : a || b ? 1 : 2;
|
---|
72 | }
|
---|
73 |
|
---|
74 | private static double GetDiff<T>(IReadOnlyList<T> estimated, IPushStack<T> resultStack, double worstResult, Func<T, T, double> differ)
|
---|
75 | where T : IComparable {
|
---|
76 | if (estimated.Count == 0) return 0d;
|
---|
77 |
|
---|
78 | var diff = 0d;
|
---|
79 | var comparableLength = 0;
|
---|
80 |
|
---|
81 | if (!resultStack.IsEmpty) {
|
---|
82 | var count = Math.Min(estimated.Count, resultStack.Count);
|
---|
83 | var result = resultStack.Peek(count);
|
---|
84 | comparableLength = Math.Min(estimated.Count, result.Length);
|
---|
85 |
|
---|
86 | for (var i = 0; i < comparableLength; i++) {
|
---|
87 | diff += Math.Min(differ(estimated[i], result[i]), worstResult);
|
---|
88 | }
|
---|
89 | }
|
---|
90 |
|
---|
91 | for (var i = comparableLength; i < estimated.Count - comparableLength; i++) {
|
---|
92 | diff += differ(estimated[i], default(T));
|
---|
93 | }
|
---|
94 |
|
---|
95 | return diff;
|
---|
96 | }
|
---|
97 | }
|
---|
98 | }
|
---|