using System; using System.Collections.Generic; using System.Linq; using HeuristicLab.Algorithms.ParameterlessPopulationPyramid; using HeuristicLab.Random; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace ParameterlessPopulationPyramid.Test { [TestClass] public class LinkageTreeTest { private static int Length = 9; private static bool[][] solutions = new bool[][] { new bool[] { true, true, false, false, false, false, false, false, false }, // 110000000 new bool[] { false, false, true, true, false, false, false, false, false }, // 001100000 new bool[] { false, false, false, false, true, true, false, false, false }, // 000011000 new bool[] { false, false, false, false, false, false, true, true, true }, // 000000111 new bool[] { true, true, true, true, false, false, false, false, false }, // 111100000 new bool[] { true, true, true, true, true, true, true, true, true }, // 111111111 }; private static int[][] correctClusters = new int[][] { new int[] { 2, 3 }, new int[] { 4, 5 }, new int[] { 0, 1 }, new int[] { 6, 7, 8 }, new int[] { 0, 1, 2, 3}, new int[] { 4, 5, 6, 7, 8}, }; [TestMethod] public void LinkageTreeTestAdd() { LinkageTree tree = new LinkageTree(Length); tree.Add(solutions[0]); tree.Add(solutions[1]); PrivateObject hidden = new PrivateObject(tree); int[][][] result = (int[][][])hidden.GetField("occurances"); Assert.AreEqual(1, result[1][0][0]); // Positions 0 and 1 had value 00 exactly once Assert.AreEqual(2, result[Length - 1][Length - 2][0]); // Positions 0 and 1 had value 00 exactly once Assert.AreEqual(0, result[Length - 1][Length - 2][1]); // Positions 7 and 8 never had value 10 Assert.AreEqual(1, result[1][0][3]); // Positions 0 and 1 had value 11 exactly once } [TestMethod] public void LinkageTreeTestEntropyDistance() { LinkageTree tree = new LinkageTree(Length); PrivateObject hidden = new PrivateObject(tree); // No information should result in a distance of 0 Assert.AreEqual((double)0, hidden.Invoke("EntropyDistance", new object[] { 0, 1 })); foreach (var solution in solutions) { tree.Add(solution); } // Check that 0 and 1 are closer than 0 and 2 var linked = (double)hidden.Invoke("EntropyDistance", new object[] { 0, 1 }); var unlinked = (double)hidden.Invoke("EntropyDistance", new object[] { 0, 2 }); Assert.IsTrue(linked < unlinked); // Reversing the arguments should not change the result var forward = hidden.Invoke("EntropyDistance", new object[] { Length - 1, Length - 2 }); var backward = hidden.Invoke("EntropyDistance", new object[] { Length - 2, Length - 1 }); Assert.AreEqual(forward, backward); } [TestMethod] public void LinkageTreeTestRebuild() { LinkageTree tree = new LinkageTree(Length); foreach (var solution in solutions) { tree.Add(solution); } MersenneTwister rand = new MersenneTwister(123); tree.Rebuild(rand); PrivateObject hidden = new PrivateObject(tree); var ordering = (List)hidden.GetField("clusterOrdering"); var clusters = (List[])hidden.GetField("clusters"); int[][] comparable = new int[ordering.Count][]; for (int i = 0; i < ordering.Count; i++) { var found = clusters[ordering[i]].ToArray(); Array.Sort(found); Assert.IsTrue(correctClusters[i].SequenceEqual(found)); } } } }