[15334] | 1 | using System.Linq;
|
---|
| 2 | // ReSharper disable PossibleNullReferenceException
|
---|
| 3 |
|
---|
| 4 | namespace HeuristicLab.Tests.Benchmark {
|
---|
| 5 | using System;
|
---|
| 6 | using System.Threading;
|
---|
| 7 |
|
---|
| 8 | using HeuristicLab.Algorithms.GeneticAlgorithm;
|
---|
| 9 | using HeuristicLab.BenchmarkSuite;
|
---|
| 10 | using HeuristicLab.BenchmarkSuite.Problems;
|
---|
| 11 | using HeuristicLab.Data;
|
---|
| 12 | using HeuristicLab.ParallelEngine;
|
---|
[15771] | 13 | using HeuristicLab.Problems.ProgramSynthesis;
|
---|
[15334] | 14 |
|
---|
| 15 | using Microsoft.VisualStudio.TestTools.UnitTesting;
|
---|
| 16 |
|
---|
| 17 | [TestClass]
|
---|
| 18 | public class GpTests {
|
---|
| 19 |
|
---|
| 20 | [TestMethod]
|
---|
| 21 | [TestProperty("Time", "Long")]
|
---|
| 22 | [TestCategory("ProblemTest")]
|
---|
| 23 | public void Checksum() {
|
---|
| 24 | Run<Checksum>();
|
---|
| 25 | }
|
---|
| 26 |
|
---|
| 27 | [TestMethod]
|
---|
| 28 | [TestProperty("Time", "Long")]
|
---|
| 29 | [TestCategory("ProblemTest")]
|
---|
| 30 | public void CollatzNumbers() {
|
---|
| 31 | Run<CollatzNumbers>();
|
---|
| 32 | }
|
---|
| 33 |
|
---|
| 34 | [TestMethod]
|
---|
| 35 | [TestProperty("Time", "Long")]
|
---|
| 36 | [TestCategory("ProblemTest")]
|
---|
| 37 | public void CompareStringLengths() {
|
---|
| 38 | Run<CompareStringLengths>();
|
---|
| 39 | }
|
---|
| 40 |
|
---|
| 41 | [TestMethod]
|
---|
| 42 | [TestProperty("Time", "Long")]
|
---|
| 43 | [TestCategory("ProblemTest")]
|
---|
| 44 | public void CountOdds() {
|
---|
| 45 | Run<CountOdds>();
|
---|
| 46 | }
|
---|
| 47 |
|
---|
| 48 | [TestMethod]
|
---|
| 49 | [TestProperty("Time", "Long")]
|
---|
| 50 | [TestCategory("ProblemTest")]
|
---|
| 51 | public void Digits() {
|
---|
| 52 | Run<Digits>();
|
---|
| 53 | }
|
---|
| 54 |
|
---|
| 55 | [TestMethod]
|
---|
| 56 | [TestProperty("Time", "Long")]
|
---|
| 57 | [TestCategory("ProblemTest")]
|
---|
| 58 | public void DoubleLetters() {
|
---|
| 59 | Run<DoubleLetters>();
|
---|
| 60 | }
|
---|
| 61 |
|
---|
| 62 | [TestMethod]
|
---|
| 63 | [TestProperty("Time", "Long")]
|
---|
| 64 | [TestCategory("ProblemTest")]
|
---|
| 65 | public void EvenSquares() {
|
---|
| 66 | Run<EvenSquares>();
|
---|
| 67 | }
|
---|
| 68 |
|
---|
| 69 | [TestMethod]
|
---|
| 70 | [TestProperty("Time", "Long")]
|
---|
| 71 | [TestCategory("ProblemTest")]
|
---|
| 72 | public void ForLoopIndex() {
|
---|
| 73 | Run<ForLoopIndex>();
|
---|
| 74 | }
|
---|
| 75 |
|
---|
| 76 | [TestMethod]
|
---|
| 77 | [TestProperty("Time", "Long")]
|
---|
| 78 | [TestCategory("ProblemTest")]
|
---|
| 79 | public void Grades() {
|
---|
| 80 | Run<Grades>();
|
---|
| 81 | }
|
---|
| 82 |
|
---|
| 83 | [TestMethod]
|
---|
| 84 | [TestProperty("Time", "Long")]
|
---|
| 85 | [TestCategory("ProblemTest")]
|
---|
| 86 | public void LastIndexOfZero() {
|
---|
| 87 | Run<LastIndexOfZero>();
|
---|
| 88 | }
|
---|
| 89 |
|
---|
| 90 | [TestMethod]
|
---|
| 91 | [TestProperty("Time", "Long")]
|
---|
| 92 | [TestCategory("ProblemTest")]
|
---|
| 93 | public void Median() {
|
---|
| 94 | Run<Median>();
|
---|
| 95 | }
|
---|
| 96 |
|
---|
| 97 | [TestMethod]
|
---|
| 98 | [TestProperty("Time", "Long")]
|
---|
| 99 | [TestCategory("ProblemTest")]
|
---|
| 100 | public void MirrorImage() {
|
---|
| 101 | Run<MirrorImage>();
|
---|
| 102 | }
|
---|
| 103 |
|
---|
| 104 | [TestMethod]
|
---|
| 105 | [TestProperty("Time", "Long")]
|
---|
| 106 | [TestCategory("ProblemTest")]
|
---|
| 107 | public void NegativeToZero() {
|
---|
| 108 | Run<NegativeToZero>();
|
---|
| 109 | }
|
---|
| 110 |
|
---|
| 111 | [TestMethod]
|
---|
| 112 | [TestProperty("Time", "Long")]
|
---|
| 113 | [TestCategory("ProblemTest")]
|
---|
| 114 | public void NumberIo() {
|
---|
| 115 | Run<NumberIO>();
|
---|
| 116 | }
|
---|
| 117 |
|
---|
| 118 | [TestMethod]
|
---|
| 119 | [TestProperty("Time", "Long")]
|
---|
| 120 | [TestCategory("ProblemTest")]
|
---|
| 121 | public void PigLatin() {
|
---|
| 122 | Run<PigLatin>();
|
---|
| 123 | }
|
---|
| 124 |
|
---|
| 125 | [TestMethod]
|
---|
| 126 | [TestProperty("Time", "Long")]
|
---|
| 127 | [TestCategory("ProblemTest")]
|
---|
| 128 | public void ReplaceSpaceWithNewLine() {
|
---|
| 129 | Run<ReplaceSpaceWithNewline>();
|
---|
| 130 | }
|
---|
| 131 |
|
---|
| 132 | [TestMethod]
|
---|
| 133 | [TestProperty("Time", "Long")]
|
---|
| 134 | [TestCategory("ProblemTest")]
|
---|
| 135 | public void ScrabbleScore() {
|
---|
| 136 | Run<ScrabbleScore>();
|
---|
| 137 | }
|
---|
| 138 |
|
---|
| 139 | [TestMethod]
|
---|
| 140 | [TestProperty("Time", "Long")]
|
---|
| 141 | [TestCategory("ProblemTest")]
|
---|
| 142 | public void Smallest() {
|
---|
| 143 | Run<Smallest>();
|
---|
| 144 | }
|
---|
| 145 |
|
---|
| 146 | [TestMethod]
|
---|
| 147 | [TestProperty("Time", "Long")]
|
---|
| 148 | [TestCategory("ProblemTest")]
|
---|
| 149 | public void SmallOrLarge() {
|
---|
| 150 | Run<SmallOrLarge>();
|
---|
| 151 | }
|
---|
| 152 |
|
---|
| 153 | [TestMethod]
|
---|
| 154 | [TestProperty("Time", "Long")]
|
---|
| 155 | [TestCategory("ProblemTest")]
|
---|
| 156 | public void StringDifferences() {
|
---|
| 157 | Run<StringDifferences>();
|
---|
| 158 | }
|
---|
| 159 |
|
---|
| 160 | [TestMethod]
|
---|
| 161 | [TestProperty("Time", "Long")]
|
---|
| 162 | [TestCategory("ProblemTest")]
|
---|
| 163 | public void StringLengthsBackwards() {
|
---|
| 164 | Run<StringLengthsBackwards>();
|
---|
| 165 | }
|
---|
| 166 |
|
---|
| 167 | [TestMethod]
|
---|
| 168 | [TestProperty("Time", "Long")]
|
---|
| 169 | [TestCategory("ProblemTest")]
|
---|
| 170 | public void SumOfSquares() {
|
---|
| 171 | Run<SumOfSquares>();
|
---|
| 172 | }
|
---|
| 173 |
|
---|
| 174 | [TestMethod]
|
---|
| 175 | [TestProperty("Time", "Long")]
|
---|
| 176 | [TestCategory("ProblemTest")]
|
---|
| 177 | public void SuperAnagrams() {
|
---|
| 178 | Run<SuperAnagrams>();
|
---|
| 179 | }
|
---|
| 180 |
|
---|
| 181 | [TestMethod]
|
---|
| 182 | [TestProperty("Time", "Long")]
|
---|
| 183 | [TestCategory("ProblemTest")]
|
---|
| 184 | public void Syllables() {
|
---|
| 185 | Run<Syllables>();
|
---|
| 186 | }
|
---|
| 187 |
|
---|
| 188 | [TestMethod]
|
---|
| 189 | [TestProperty("Time", "Long")]
|
---|
| 190 | [TestCategory("ProblemTest")]
|
---|
| 191 | public void VectorAverage() {
|
---|
| 192 | Run<VectorAverage>();
|
---|
| 193 | }
|
---|
| 194 |
|
---|
| 195 | [TestMethod]
|
---|
| 196 | [TestProperty("Time", "Long")]
|
---|
| 197 | [TestCategory("ProblemTest")]
|
---|
| 198 | public void VectorSummed() {
|
---|
| 199 | Run<VectorSummed>();
|
---|
| 200 | }
|
---|
| 201 |
|
---|
| 202 | [TestMethod]
|
---|
| 203 | [TestProperty("Time", "Long")]
|
---|
| 204 | [TestCategory("ProblemTest")]
|
---|
| 205 | public void WallisPi() {
|
---|
| 206 | Run<WallisPi>();
|
---|
| 207 | }
|
---|
| 208 |
|
---|
| 209 | [TestMethod]
|
---|
| 210 | [TestProperty("Time", "Long")]
|
---|
| 211 | [TestCategory("ProblemTest")]
|
---|
| 212 | public void WordStats() {
|
---|
| 213 | Run<WordStats>();
|
---|
| 214 | }
|
---|
| 215 |
|
---|
| 216 | [TestMethod]
|
---|
| 217 | [TestProperty("Time", "Long")]
|
---|
| 218 | [TestCategory("ProblemTest")]
|
---|
| 219 | public void XWordLines() {
|
---|
| 220 | Run<XWordLines>();
|
---|
| 221 | }
|
---|
| 222 |
|
---|
| 223 | static void Run<T>() where T : IBenchmarkSuiteDataDescriptor, new() {
|
---|
| 224 | var trigger = new AutoResetEvent(false);
|
---|
| 225 | var alg = GetAlgorithm(new T());
|
---|
| 226 | Exception exception = null;
|
---|
| 227 |
|
---|
| 228 | alg.ExceptionOccurred += (sender, args) => {
|
---|
| 229 | exception = args.Value;
|
---|
| 230 | trigger.Set();
|
---|
| 231 | };
|
---|
| 232 |
|
---|
| 233 | alg.Stopped += (sender, args) => {
|
---|
| 234 | trigger.Set();
|
---|
| 235 | };
|
---|
| 236 |
|
---|
| 237 | var lastGeneration = -1;
|
---|
| 238 | alg.ExecutionTimeChanged += (sender, args) => {
|
---|
| 239 | if (!alg.Results.Any() || !alg.Results.ContainsKey("CurrentBestQuality")) return;
|
---|
| 240 |
|
---|
| 241 | var generation = (alg.Results["Generations"].Value as IntValue).Value;
|
---|
| 242 |
|
---|
| 243 | if (lastGeneration != -1 && generation == lastGeneration) return;
|
---|
| 244 |
|
---|
| 245 | Console.WriteLine(@"Generation: {0}", generation);
|
---|
| 246 |
|
---|
| 247 | if (alg.Results.ContainsKey("CurrentBestQuality")) {
|
---|
| 248 | var best = (alg.Results["CurrentBestQuality"].Value as DoubleValue).Value;
|
---|
| 249 | Console.WriteLine(@"CurrentBestQuality: {0}", best);
|
---|
| 250 | }
|
---|
| 251 |
|
---|
| 252 | if (alg.Results.ContainsKey("CurrentAverageQuality")) {
|
---|
| 253 | var average = (alg.Results["CurrentAverageQuality"].Value as DoubleValue).Value;
|
---|
| 254 | Console.WriteLine(@"CurrentAverageQuality: {0}", average);
|
---|
| 255 | }
|
---|
| 256 |
|
---|
| 257 | if (alg.Results.ContainsKey("CurrentWorstQuality")) {
|
---|
| 258 | var worst = (alg.Results["CurrentWorstQuality"].Value as DoubleValue).Value;
|
---|
| 259 | Console.WriteLine(@"CurrentWorstQuality: {0}", worst);
|
---|
| 260 | }
|
---|
| 261 |
|
---|
| 262 | Console.WriteLine();
|
---|
| 263 | lastGeneration = generation;
|
---|
| 264 | };
|
---|
| 265 |
|
---|
| 266 | alg.Prepare();
|
---|
| 267 | alg.Start();
|
---|
| 268 | trigger.WaitOne();
|
---|
| 269 |
|
---|
| 270 | if (exception != null) {
|
---|
| 271 | Console.WriteLine(exception.Message);
|
---|
| 272 | throw exception;
|
---|
| 273 | }
|
---|
| 274 |
|
---|
| 275 | var finalGeneration = (alg.Results["Generations"].Value as IntValue).Value;
|
---|
| 276 | var bestQuality = (alg.Results["CurrentBestQuality"].Value as DoubleValue).Value;
|
---|
| 277 | var averageQuality = (alg.Results["CurrentAverageQuality"].Value as DoubleValue).Value;
|
---|
| 278 | var worstQuality = (alg.Results["CurrentWorstQuality"].Value as DoubleValue).Value;
|
---|
| 279 |
|
---|
| 280 | Console.WriteLine(@"Final Generation: {0}", finalGeneration);
|
---|
| 281 | Console.WriteLine(@"CurrentBestQuality: {0}", bestQuality);
|
---|
| 282 | Console.WriteLine(@"CurrentAverageQuality: {0}", averageQuality);
|
---|
| 283 | Console.WriteLine(@"CurrentWorstQuality: {0}", worstQuality);
|
---|
| 284 | }
|
---|
| 285 |
|
---|
| 286 | static GeneticAlgorithm GetAlgorithm(IBenchmarkSuiteDataDescriptor descriptor) {
|
---|
| 287 | var ga = new GeneticAlgorithm();
|
---|
| 288 |
|
---|
| 289 | var problemData = descriptor.CreateProblemData();
|
---|
| 290 | var pushProblem = new PlushPushBenchmarkSuiteProblem();
|
---|
| 291 |
|
---|
| 292 | pushProblem.Load(problemData);
|
---|
| 293 | ga.Name = "GA " + pushProblem.Name;
|
---|
| 294 |
|
---|
| 295 | ga.Problem = pushProblem;
|
---|
| 296 |
|
---|
| 297 | var crossover = ga.CrossoverParameter.ValidValues.OfType<AlternationCrossover>().First();
|
---|
| 298 |
|
---|
| 299 | switch (problemData.ProblemType) {
|
---|
| 300 | case ProblemType.NumberIO:
|
---|
| 301 | case ProblemType.SmallOrLarge:
|
---|
| 302 | case ProblemType.Median:
|
---|
| 303 | case ProblemType.Smallest:
|
---|
| 304 | crossover.AlignmentDeviation = 5;
|
---|
| 305 | break;
|
---|
| 306 |
|
---|
| 307 | default:
|
---|
| 308 | crossover.AlignmentDeviation = 10;
|
---|
| 309 | break;
|
---|
| 310 | }
|
---|
| 311 |
|
---|
| 312 | crossover.AlternationRate = 0.01;
|
---|
| 313 | ga.Crossover = crossover;
|
---|
| 314 |
|
---|
| 315 | ga.Selector = ga.SelectorParameter.ValidValues.OfType<LexicaseSelector>().First();
|
---|
| 316 |
|
---|
| 317 | var mutator = ga.MutatorParameter.ValidValues.OfType<UniformMutation>().First();
|
---|
| 318 | mutator.InstructionMutationProbability = 0.875;
|
---|
| 319 | mutator.CloseMutationProbability = 0.125;
|
---|
| 320 | mutator.CloseIncrementRate = 0.1;
|
---|
| 321 | ga.Mutator = mutator;
|
---|
| 322 |
|
---|
| 323 | ga.MutationProbability.Value = 0.8;
|
---|
| 324 | ga.SetSeedRandomly.Value = true;
|
---|
| 325 | ga.PopulationSize.Value = 1000;
|
---|
| 326 |
|
---|
| 327 | ga.MaximumGenerations.Value = 9; // problemData.ProgramExecutionBudget / problemData.TrainingCount / 1000;
|
---|
| 328 |
|
---|
| 329 | // remove unnecessary analyzers to improve performance
|
---|
| 330 | pushProblem.OperatorsParameter.Value
|
---|
| 331 | .RemoveAll(analyzer =>
|
---|
| 332 | analyzer.GetType() == typeof(IndividualZeroErrorAnalyzer) ||
|
---|
| 333 | analyzer.GetType() == typeof(PushExpressionFrequencyAnalyzer));
|
---|
| 334 |
|
---|
| 335 | ga.Engine = new ParallelEngine();
|
---|
| 336 |
|
---|
| 337 | return ga;
|
---|
| 338 | }
|
---|
| 339 | }
|
---|
| 340 | }
|
---|