[14727] | 1 | namespace HeuristicLab.Tests.Benchmark.Problem {
|
---|
| 2 | using System;
|
---|
| 3 | using System.Collections.Generic;
|
---|
| 4 | using System.Linq;
|
---|
| 5 | using System.Threading.Tasks;
|
---|
| 6 |
|
---|
| 7 | using HeuristicLab.BenchmarkSuite;
|
---|
| 8 | using HeuristicLab.BenchmarkSuite.Problems;
|
---|
| 9 | using HeuristicLab.Problems.Instances;
|
---|
| 10 | using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
|
---|
| 11 | using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
|
---|
[14834] | 12 | using HeuristicLab.Problems.ProgramSynthesis.Push.Generators.CodeGenerator;
|
---|
[14727] | 13 | using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
|
---|
| 14 | using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
|
---|
| 15 | using HeuristicLab.Random;
|
---|
| 16 |
|
---|
| 17 | using Microsoft.VisualStudio.TestTools.UnitTesting;
|
---|
| 18 |
|
---|
| 19 | [TestClass]
|
---|
| 20 | public class ProblemTests {
|
---|
| 21 | [TestMethod]
|
---|
| 22 | [TestProperty("Time", "Medium")]
|
---|
| 23 | [TestCategory("ProblemTest")]
|
---|
| 24 | public void CountOdds() {
|
---|
| 25 | RandomWalk(new CountOdds());
|
---|
| 26 | }
|
---|
| 27 |
|
---|
[14777] | 28 | //[TestMethod]
|
---|
| 29 | //[TestProperty("Time", "Medium")]
|
---|
| 30 | //[TestCategory("ProblemTest")]
|
---|
| 31 | //public void Checksum() {
|
---|
| 32 | // RandomWalk(new Checksum());
|
---|
| 33 | //}
|
---|
[14727] | 34 |
|
---|
| 35 | //[TestMethod]
|
---|
| 36 | //[TestProperty("Time", "Medium")]
|
---|
| 37 | //[TestCategory("ProblemTest")]
|
---|
| 38 | //public void CollatzNumbers() {
|
---|
| 39 | // RandomWalk(new CollatzNumbers());
|
---|
| 40 | //}
|
---|
| 41 |
|
---|
| 42 | //[TestMethod]
|
---|
| 43 | //[TestProperty("Time", "Medium")]
|
---|
| 44 | //[TestCategory("ProblemTest")]
|
---|
| 45 | //public void CompareStringLengths() {
|
---|
| 46 | // RandomWalk(new CompareStringLengths());
|
---|
| 47 | //}
|
---|
| 48 |
|
---|
| 49 | //[TestMethod]
|
---|
| 50 | //[TestProperty("Time", "Medium")]
|
---|
| 51 | //[TestCategory("ProblemTest")]
|
---|
| 52 | //public void Digits() {
|
---|
| 53 | // RandomWalk(new Digits());
|
---|
| 54 | //}
|
---|
| 55 |
|
---|
| 56 | //[TestMethod]
|
---|
| 57 | //[TestProperty("Time", "Medium")]
|
---|
| 58 | //[TestCategory("ProblemTest")]
|
---|
| 59 | //public void DoubleLetters() {
|
---|
| 60 | // RandomWalk(new DoubleLetters());
|
---|
| 61 | //}
|
---|
| 62 |
|
---|
| 63 | //[TestMethod]
|
---|
| 64 | //[TestProperty("Time", "Medium")]
|
---|
| 65 | //[TestCategory("ProblemTest")]
|
---|
| 66 | //public void EvenSquares() {
|
---|
| 67 | // RandomWalk(new EvenSquares());
|
---|
| 68 | //}
|
---|
| 69 |
|
---|
| 70 | //[TestMethod]
|
---|
| 71 | //[TestProperty("Time", "Medium")]
|
---|
| 72 | //[TestCategory("ProblemTest")]
|
---|
| 73 | //public void ForLoopIndex() {
|
---|
| 74 | // RandomWalk(new ForLoopIndex());
|
---|
| 75 | //}
|
---|
| 76 |
|
---|
| 77 | //[TestMethod]
|
---|
| 78 | //[TestProperty("Time", "Medium")]
|
---|
| 79 | //[TestCategory("ProblemTest")]
|
---|
| 80 | //public void Grades() {
|
---|
| 81 | // RandomWalk(new Grades());
|
---|
| 82 | //}
|
---|
| 83 |
|
---|
| 84 | //[TestMethod]
|
---|
| 85 | //[TestProperty("Time", "Medium")]
|
---|
| 86 | //[TestCategory("ProblemTest")]
|
---|
| 87 | //public void LastIndexOfZero() {
|
---|
| 88 | // RandomWalk(new LastIndexOfZero());
|
---|
| 89 | //}
|
---|
| 90 |
|
---|
| 91 | //[TestMethod]
|
---|
| 92 | //[TestProperty("Time", "Medium")]
|
---|
| 93 | //[TestCategory("ProblemTest")]
|
---|
| 94 | //public void Median() {
|
---|
| 95 | // RandomWalk(new Median());
|
---|
| 96 | //}
|
---|
| 97 |
|
---|
| 98 | //[TestMethod]
|
---|
| 99 | //[TestProperty("Time", "Medium")]
|
---|
| 100 | //[TestCategory("ProblemTest")]
|
---|
| 101 | //public void MirrorImage() {
|
---|
| 102 | // RandomWalk(new MirrorImage());
|
---|
| 103 | //}
|
---|
| 104 |
|
---|
| 105 | //[TestMethod]
|
---|
| 106 | //[TestProperty("Time", "Medium")]
|
---|
| 107 | //[TestCategory("ProblemTest")]
|
---|
| 108 | //public void NegativeToZero() {
|
---|
| 109 | // RandomWalk(new NegativeToZero());
|
---|
| 110 | //}
|
---|
| 111 |
|
---|
| 112 | //[TestMethod]
|
---|
| 113 | //[TestProperty("Time", "Medium")]
|
---|
| 114 | //[TestCategory("ProblemTest")]
|
---|
| 115 | //public void NumberIo() {
|
---|
| 116 | // RandomWalk(new NumberIo());
|
---|
| 117 | //}
|
---|
| 118 |
|
---|
| 119 | //[TestMethod]
|
---|
| 120 | //[TestProperty("Time", "Medium")]
|
---|
| 121 | //[TestCategory("ProblemTest")]
|
---|
| 122 | //public void PigLatin() {
|
---|
| 123 | // RandomWalk(new PigLatin());
|
---|
| 124 | //}
|
---|
| 125 |
|
---|
| 126 | //[TestMethod]
|
---|
| 127 | //[TestProperty("Time", "Medium")]
|
---|
| 128 | //[TestCategory("ProblemTest")]
|
---|
| 129 | //public void ReplaceSpaceWithNewLine() {
|
---|
| 130 | // RandomWalk(new ReplaceSpaceWithNewline());
|
---|
| 131 | //}
|
---|
| 132 |
|
---|
| 133 | private static void RandomWalk(IDataDescriptor descriptor) {
|
---|
| 134 | var maxProgramSizeLimit = 1024;
|
---|
| 135 | var iterations = 100;
|
---|
| 136 | var best = double.MaxValue;
|
---|
[14875] | 137 | var globalExecCounter = 0L;
|
---|
[14727] | 138 | var lockObj = new object();
|
---|
| 139 | var lockCount = new object();
|
---|
| 140 | var random = new FastRandom(1337);
|
---|
| 141 |
|
---|
| 142 | Expression bestProgram = null;
|
---|
[14733] | 143 | var config = new PushConfiguration { EvalPushLimit = 4096 };
|
---|
| 144 | var pool = new PushInterpreterPool(config);
|
---|
[14727] | 145 |
|
---|
| 146 | var instance = new BenchmarkSuiteInstanceProvider();
|
---|
| 147 | var data = instance.LoadData(descriptor);
|
---|
| 148 |
|
---|
[14875] | 149 | Parallel.For(0u, iterations, i => {
|
---|
| 150 | var execCounter = 0L;
|
---|
| 151 | var results = new double[data.TrainingCount];
|
---|
[14747] | 152 | PushProgram program;
|
---|
[14727] | 153 |
|
---|
[14777] | 154 | using (var interpreter = pool.Create(random)) {
|
---|
| 155 | program = RecursiveCodeGenerator.RandomProgram(maxProgramSizeLimit, random);
|
---|
[14746] | 156 |
|
---|
[14875] | 157 | for (var j = 0; j < data.TrainingCount; j++) {
|
---|
[14727] | 158 | var example = data.Examples[i];
|
---|
| 159 |
|
---|
| 160 | interpreter.BooleanStack.Push(example.InputBoolean);
|
---|
[14875] | 161 | interpreter.IntegerStack.Push(example.InputInteger);
|
---|
[14727] | 162 | interpreter.FloatStack.Push(example.InputFloat);
|
---|
| 163 |
|
---|
| 164 | interpreter.Run(program);
|
---|
| 165 |
|
---|
[14875] | 166 | var diff = GetDiff(example.OutputInteger, interpreter.IntegerStack)
|
---|
[14746] | 167 | + GetDiff(example.OutputFloat, interpreter.FloatStack)
|
---|
| 168 | + GetDiff(example.OutputBoolean, interpreter.BooleanStack);
|
---|
[14727] | 169 |
|
---|
| 170 | results[j] = diff;
|
---|
| 171 |
|
---|
| 172 | execCounter += interpreter.ExecCounter;
|
---|
| 173 | interpreter.Clear();
|
---|
| 174 | }
|
---|
| 175 | }
|
---|
| 176 |
|
---|
| 177 | lock (lockCount) {
|
---|
| 178 | globalExecCounter += execCounter;
|
---|
| 179 | }
|
---|
| 180 |
|
---|
| 181 | var avg = results.Average();
|
---|
| 182 |
|
---|
| 183 | if (avg >= best) return;
|
---|
| 184 |
|
---|
| 185 | lock (lockObj) {
|
---|
| 186 | if (avg < best) {
|
---|
| 187 | best = avg;
|
---|
| 188 | bestProgram = program;
|
---|
| 189 | }
|
---|
| 190 | }
|
---|
| 191 | });
|
---|
| 192 |
|
---|
[14875] | 193 | var resultsTest = new double[data.TestCount];
|
---|
| 194 | Parallel.For(data.TestCount, data.TestCount, i => {
|
---|
[14777] | 195 | using (var interpreter = pool.Create()) {
|
---|
[14727] | 196 | var example = data.Examples[i];
|
---|
| 197 |
|
---|
| 198 | interpreter.BooleanStack.Push(example.InputBoolean);
|
---|
[14875] | 199 | interpreter.IntegerStack.Push(example.InputInteger);
|
---|
[14727] | 200 | interpreter.FloatStack.Push(example.InputFloat);
|
---|
| 201 |
|
---|
| 202 | interpreter.Run(bestProgram);
|
---|
| 203 |
|
---|
[14875] | 204 | var diff = GetDiff(example.OutputInteger, interpreter.IntegerStack) +
|
---|
[14727] | 205 | GetDiff(example.OutputFloat, interpreter.FloatStack) +
|
---|
| 206 | GetDiff(example.OutputBoolean, interpreter.BooleanStack);
|
---|
| 207 |
|
---|
| 208 | resultsTest[i] = diff;
|
---|
| 209 | }
|
---|
| 210 | });
|
---|
| 211 |
|
---|
| 212 | var averageTestResult = resultsTest.Average();
|
---|
| 213 |
|
---|
| 214 | Console.WriteLine("Best Training: {0}", best);
|
---|
| 215 | Console.WriteLine("Test: {0}", averageTestResult);
|
---|
| 216 | Console.WriteLine("Best trainig program: {0}", bestProgram);
|
---|
| 217 | Console.WriteLine("ExecCounter: {0}", globalExecCounter);
|
---|
| 218 | }
|
---|
| 219 |
|
---|
[14834] | 220 | private static double GetDiff<T>(IReadOnlyList<T> estimated, IPushStack<T> resultStack)
|
---|
[14727] | 221 | where T : IComparable {
|
---|
| 222 | var count = Math.Min(estimated.Count, resultStack.Count);
|
---|
| 223 | var result = resultStack.Peek(count);
|
---|
| 224 | var comparableLength = Math.Min(estimated.Count, result.Length);
|
---|
| 225 | var diff = 0d;
|
---|
| 226 |
|
---|
| 227 | for (var i = 0; i < comparableLength; i++) {
|
---|
| 228 | diff += Math.Abs(estimated[i].CompareTo(result[i]));
|
---|
| 229 | }
|
---|
| 230 |
|
---|
| 231 | if (estimated.Count > result.Length) {
|
---|
| 232 | for (var i = comparableLength; i < estimated.Count; i++) {
|
---|
| 233 | diff += Math.Abs(estimated[i].CompareTo(default(T)));
|
---|
| 234 | }
|
---|
| 235 | }
|
---|
| 236 |
|
---|
| 237 | return diff;
|
---|
| 238 | }
|
---|
| 239 | }
|
---|
| 240 | } |
---|