using System.Linq; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Random; using HeuristicLab.Problems.ProgramSynthesis; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace HeuristicLab.Tests.Erc { [TestClass] public class ErcTests { private const double tolerance = 0.15; private IRandom random; [TestInitialize] public void BeforeTest() { random = new MersenneTwister(1337); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ErcTests")] public void MixedIntegerErcValueTests() { var options = new IntegerErcOptions( new IntegerConstantErc(true, 0.8, 11, 12, 13), new IntegerRangeErc(true, -10, 10, 0.2)); Assert.IsTrue(options.IsEnabled); var distribution = Enumerable.Range(0, 1000) .Select(_ => options.GetErcValue(random)) .GroupBy(x => x <= 10 ? "range" : "constants") .ToDictionary(group => group.Key, group => group.Count()); var estimatedRatio = 0.8 / 0.2; var ratio = distribution["constants"] / (double)distribution["range"]; Assert.IsTrue(IsAlmost(estimatedRatio, ratio, tolerance)); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ErcTests")] public void MixedFloatErcValueTests() { var options = new FloatErcOptions( new FloatConstantErc(true, 0.8, 11.1, 12.1, 13.1), new FloatRangeErc(true, -10.5, 10.5, 0.2)); Assert.IsTrue(options.IsEnabled); var distribution = Enumerable.Range(0, 1000) .Select(_ => options.GetErcValue(random)) .GroupBy(x => x <= 10.5 ? "range" : "constants") .ToDictionary(group => group.Key, group => group.Count()); var estimatedRatio = 0.8 / 0.2; var ratio = distribution["constants"] / (double)distribution["range"]; Assert.IsTrue(IsAlmost(estimatedRatio, ratio, tolerance)); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ErcTests")] public void MixedCharErcValueTests() { var options = new CharErcOptions( new IntegerConstantErc(true, 0.8, 11, 12, 13), new IntegerRangeErc(true, 65, 98, 0.2)); Assert.IsTrue(options.IsEnabled); var distribution = Enumerable.Range(0, 1000) .Select(_ => options.GetErcValue(random)) .GroupBy(x => x >= 65 ? "range" : "constants") .ToDictionary(group => group.Key, group => group.Count()); var estimatedRatio = 0.8 / 0.2; var ratio = distribution["constants"] / (double)distribution["range"]; Assert.IsTrue(IsAlmost(estimatedRatio, ratio, tolerance)); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ErcTests")] public void MixedStringErcValueTests() { var options = new StringErcOptions( new StringConstantErc(true, 0.8, "_1", "_2", "_3"), new StringRandomErc(true, 0.2)); Assert.IsTrue(options.IsEnabled); var distribution = Enumerable.Range(0, 1000) .Select(_ => options.GetErcValue(random)) .GroupBy(x => x.StartsWith("_") ? "constants" : "random") .ToDictionary(group => group.Key, group => group.Count()); var estimatedRatio = 0.8 / 0.2; var ratio = distribution["constants"] / (double)distribution["random"]; Assert.IsTrue(IsAlmost(estimatedRatio, ratio, tolerance)); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ErcTests")] public void StringStringErcValueTests() { var options = new StringErcOptions( new StringConstantErc(true, 1.0, "_1", "_2", "_3")); Assert.IsTrue(options.IsEnabled); var distribution = Enumerable.Range(0, 1000) .Select(_ => options.GetErcValue(random)) .GroupBy(x => x) .ToDictionary(group => group.Key, group => group.Count()); var estimatedRatio = 1.0 / 3.0; Assert.IsTrue(IsAlmost(estimatedRatio, distribution["_1"] / 1000.0, tolerance)); Assert.IsTrue(IsAlmost(estimatedRatio, distribution["_2"] / 1000.0, tolerance)); Assert.IsTrue(IsAlmost(estimatedRatio, distribution["_3"] / 1000.0, tolerance)); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ErcTests")] public void MixedIntegerVectorErcValueTests() { var options = new IntegerVectorErcOptions( new IntegerVectorConstantsErc(true, 0.8, new[] { 1, 2, 3 }, new[] { 4, 5, 6 }), new IntegerVectorConstantsErc(true, 0.2, new[] { 10, 11, 12 }, new[] { 13, 14, 15 })); Assert.IsTrue(options.IsEnabled); var distribution = Enumerable.Range(0, 1000) .Select(_ => options.GetErcValue(random)) .GroupBy(x => x.All(_ => _ < 10) ? "constants1" : "constants2") .ToDictionary(group => group.Key, group => group.Count()); var estimatedRatio = 0.8 / 0.2; var ratio = distribution["constants1"] / (double)distribution["constants2"]; Assert.IsTrue(IsAlmost(estimatedRatio, ratio, tolerance)); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ErcTests")] public void DisabledIntegerVectorErcValueTests() { var options = new IntegerVectorErcOptions( new IntegerVectorConstantsErc(false, 0.8, new[] { 1, 2, 3 }, new[] { 4, 5, 6 }), new IntegerVectorConstantsErc(true, 0.2, new[] { 10, 11, 12 }, new[] { 13, 14, 15 })); Assert.IsTrue(options.IsEnabled); var distribution = Enumerable.Range(0, 1000) .Select(_ => options.GetErcValue(random)) .GroupBy(x => x.All(_ => _ < 10) ? "constants1" : "constants2") .ToDictionary(group => group.Key, group => group.Count()); Assert.IsFalse(distribution.ContainsKey("constants1")); Assert.AreEqual(1000, distribution["constants2"]); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ErcTests")] public void MixedFloatVectorErcValueTests() { var options = new FloatVectorErcOptions( new FloatVectorConstantsErc(true, 0.8, new[] { 1.0, 2.2, 3.1 }, new[] { 4.1, 5.2, 6.3 }), new FloatVectorConstantsErc(true, 0.2, new[] { 10.1, 11.1, 12.2 }, new[] { 13.1, 14.2, 15.3 })); Assert.IsTrue(options.IsEnabled); var distribution = Enumerable.Range(0, 1000) .Select(_ => options.GetErcValue(random)) .GroupBy(x => x.All(_ => _ < 10) ? "constants1" : "constants2") .ToDictionary(group => group.Key, group => group.Count()); var estimatedRatio = 0.8 / 0.2; var ratio = distribution["constants1"] / (double)distribution["constants2"]; Assert.IsTrue(IsAlmost(estimatedRatio, ratio, tolerance)); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ErcTests")] public void MixedStringVectorErcValueTests() { var options = new StringVectorErcOptions( new StringVectorConstantsErc(true, 0.8, new StringArray(new[] { "_1", "_2", "_3" }), new StringArray(new[] { "_4", "_5", "_5" })), new StringVectorConstantsErc(true, 0.2, new StringArray(new[] { "-1", "-2", "-3" }), new StringArray(new[] { "-4", "-5", "-5" }))); Assert.IsTrue(options.IsEnabled); var distribution = Enumerable.Range(0, 1000) .Select(_ => options.GetErcValue(random)) .GroupBy(x => x.Any(_ => _.StartsWith("_")) ? "constants1" : "constants2") .ToDictionary(group => group.Key, group => group.Count()); var estimatedRatio = 0.8 / 0.2; var ratio = distribution["constants1"] / (double)distribution["constants2"]; Assert.IsTrue(IsAlmost(estimatedRatio, ratio, tolerance)); } private static bool IsAlmost(double x, double y, double tolerance) { return y < x * (1 + tolerance) && y > x * (1 - tolerance); } } }