public void PermutationsShouldBeUnbiased(int count)
        {
            // Arrange
            var data         = Enumerable.Range(1, count).ToArray();
            var permutations = PermutationLexicographicOrdering.EnumeratePermutations(data)
                               .ToDictionary(Stringify, x => 0);

            var random  = new RandomWithSeed();
            var shuffle = new FisherYatesShuffle(random);

            var idealNumberOfOccurrences = 10000;
            var trials = permutations.Count * idealNumberOfOccurrences;

            // Act
            for (var i = 0; i < trials; ++i)
            {
                var tmp = Enumerable.Range(1, count).ToArray();
                shuffle.Shuffle(tmp);
                permutations[Stringify(tmp)]++;
            }

            // Assert
            var deviation  = 0.04;
            var maxAllowed = (int)(idealNumberOfOccurrences * (1 + deviation));
            var minAllowed = (int)(idealNumberOfOccurrences * (1 - deviation));

            foreach (var pair in permutations)
            {
                var occurences = pair.Value;
                var message    = $"Expected permutation to be yielded {minAllowed} <= x <= {maxAllowed} times, " +
                                 $"but was {occurences}. Seed: {random.Seed}";

                Assert.True(occurences >= minAllowed && occurences <= maxAllowed, message);
            }
        }
예제 #2
0
        public void ShouldNotModifyPermutationIfGivenOneIsLastAlready(int count)
        {
            // Arrange
            var original = Enumerable.Range(1, count).OrderByDescending(x => x).ToArray();
            var copy     = new int[count];

            Array.Copy(original, copy, count);

            // Act
            var wasFoundNext = PermutationLexicographicOrdering.NextPermutation(copy);

            // Assert
            Assert.False(wasFoundNext);
            Assert.Equal(Stringify(original), Stringify(copy));
        }
예제 #3
0
        public void ShouldEnumeratePermutationsInLexicographicOrder(int count)
        {
            // Arrange
            var expected = GetPermutations(Enumerable.Range(1, count).ToArray(), count)
                           .Select(Stringify)
                           .ToArray();

            var input = Enumerable.Range(1, count).ToArray();

            // Act
            var actual = PermutationLexicographicOrdering.EnumeratePermutations(input)
                         .Select(Stringify)
                         .ToArray();

            // Assert
            Assert.True(actual.SequenceEqual(expected));
        }
예제 #4
0
        public void ShouldProperlyFindNextPermutationInLexicographicOrder(int count)
        {
            // Arrange
            var permutations = GetPermutations(Enumerable.Range(1, count).ToArray(), count)
                               .ToArray();

            for (var i = 0; i < permutations.Length - 1; ++i)
            {
                var input    = permutations[i].ToArray();
                var expected = permutations[i + 1];

                // Act
                var wasFoundNext = PermutationLexicographicOrdering.NextPermutation(input);

                // Assert
                Assert.True(wasFoundNext);
                Assert.Equal(Stringify(expected), Stringify(input));
            }
        }