public void GetPairsWithApproximateMinimumCost_ReturnsOnePair_ForTwoElementSequence()
        {
            var result = Pairing.GetPairsWithApproximateMinimumCost(new[] { 1, 2 }, DistanceCostOfPairsEvaluator);

            Assert.AreEqual(1, result.Length);
            Assert.IsTrue(result[0].Equals((1, 2)) || result[0].Equals((2, 1)));
        }
        public void GetPairsWithApproximateMinimumCost_OperatesAsExpected_AtLargeInputs(int length)
        {
            var random   = new Random();
            var sequence = new List <int>();
            var expected = new Dictionary <int, int>();

            for (var i = 0; i < length; i++)
            {
                var item = random.Next(length);
                sequence.Add(item);
                expected.AddOrUpdate(item, 1, e => e + 1);
            }

            var result = Pairing.GetPairsWithApproximateMinimumCost(sequence, DistanceCostOfPairsEvaluator);

            foreach (var r in result)
            {
                var x = new[] { r.Item1, r.Item2 };
                foreach (var item in x)
                {
                    Assert.IsTrue(expected.TryGetValue(item, out var appearances));
                    if (appearances == 1)
                    {
                        expected.Remove(item);
                    }
                    else
                    {
                        expected[item] = appearances - 1;
                    }
                }
            }

            Assert.AreEqual(0, expected.Count);
        }
        public void GetPairsWithApproximateMinimumCost_ApproximatesAtExpectedError(int length, int samples,
                                                                                   int iterations,
                                                                                   double expectedMaxError)
        {
            var totalError = .0;

            for (var it = 0; it < samples; it++)
            {
                var random   = new Random(Environment.TickCount);
                var sequence = new List <int>();
                for (var i = 0; i < length; i++)
                {
                    var item = random.Next(length);
                    sequence.Add(item);
                }

                var approxResult =
                    Pairing.GetPairsWithApproximateMinimumCost(sequence, DistanceCostOfPairsEvaluator, iterations);
                var approxCost = approxResult.Sum(s => DistanceCostOfPairsEvaluator(s.Item1, s.Item2));

                sequence.Sort();
                var minCost = .0;
                var maxCost = .0;
                for (var i = 0; i < sequence.Count; i += 2)
                {
                    minCost += DistanceCostOfPairsEvaluator(sequence[i], sequence[i + 1]);
                    maxCost += DistanceCostOfPairsEvaluator(sequence[i], sequence[sequence.Count - i - 1]);
                }

                var error = 1 - (maxCost - approxCost) / (maxCost - minCost);
                if (double.IsNaN(error))
                {
                    error = 0;
                }

                totalError += error;
            }

            totalError /= samples;

            Assert.IsTrue(totalError <= expectedMaxError,
                          $"Total error {totalError * 100:N}% should be less than or equal to {expectedMaxError * 100:N}%");
        }
 public void GetPairsWithApproximateMinimumCost_ThrowsException_ForZeroOrLessIterationCount()
 {
     Assert.Throws <ArgumentOutOfRangeException>(
         () => Pairing.GetPairsWithApproximateMinimumCost(new[] { 1, 2 }, DistanceCostOfPairsEvaluator, 0));
 }
 public void GetPairsWithApproximateMinimumCost_ThrowsException_ForSequenceWithOddNumberOfElements()
 {
     Assert.Throws <ArgumentException>(
         () => Pairing.GetPairsWithApproximateMinimumCost(new[] { 1, 2, 3 }, DistanceCostOfPairsEvaluator));
 }
 public void GetPairsWithApproximateMinimumCost_ThrowsException_ForNullSequence()
 {
     Assert.Throws <ArgumentNullException>(
         () => Pairing.GetPairsWithApproximateMinimumCost <int>(null, DistanceCostOfPairsEvaluator));
 }
 public void GetPairsWithApproximateMinimumCost_ThrowsException_ForNullEvaluateCostOfPairFunc()
 {
     Assert.Throws <ArgumentNullException>(
         () => Pairing.GetPairsWithApproximateMinimumCost(new[] { 1, 2 }, null));
 }
        public void GetPairsWithApproximateMinimumCost_ReturnsEmptyArray_ForEmptySequence()
        {
            var result = Pairing.GetPairsWithApproximateMinimumCost(new int[] { }, DistanceCostOfPairsEvaluator);

            TestHelper.AssertSequence(result);
        }