/// <summary>
        ///     This method finds the smallest value in the given distance array.  If the smallest value appears more than once,
        ///     then the lower index is returned.
        /// </summary>
        /// <param name="distances">The pre-calculated distance matrix.</param>
        /// <returns>The first smallest distance index.</returns>
        public static int[] FirstSmallestDistanceIndex(decimal[,] distances)
        {
            if (ParameterValidation.IsDecimalArrayNullOrEmpty(distances))
            {
                return(null);
            }

            var indexSmallest = new[] { 0, 0 };

            //var indexSmallestA = 0;
            //var indexSmallestB = 0;

            for (int indexA = distances.GetLowerBound(0); indexA <= distances.GetUpperBound(0); indexA++)
            {
                for (int indexB = distances.GetLowerBound(1); indexB <= distances.GetUpperBound(1); indexB++)
                {
                    if ((indexA != indexB) && ((indexSmallest[0] == indexSmallest[1]) || (Math.Abs(distances[indexA, indexB]) < Math.Abs(distances[indexSmallest[0], indexSmallest[1]]))))
                    {
                        indexSmallest[0] = indexA;
                        indexSmallest[1] = indexB;
                    }
                }
            }

            return(indexSmallest); // new int[] { indexSmallestA, indexSmallestB };
        }
        /// <summary>
        ///     This method finds the next smallest value in the array, after the value found in the index specified.  If the same
        ///     value exists multiple times, the lower index is returned.
        /// </summary>
        /// <param name="distances">The pre-calculated distance matrix.</param>
        /// <param name="indexLast"></param>
        /// <returns>The next smallest distance index from the last indexes.</returns>
        public static int[] NextSmallestDistanceIndex(decimal[,] distances, int[] indexLast)
        {
            if (ParameterValidation.IsDecimalArrayNullOrEmpty(distances))
            {
                throw new ArgumentOutOfRangeException(nameof(distances));
            }

            if (ParameterValidation.IsIntArrayNullOrEmpty(indexLast))
            {
                throw new ArgumentOutOfRangeException(nameof(indexLast));
            }

            var indexBest = new[] { -1, -1 };

            //var indexBestA = -1;
            //var indexBestB = -1;

            if ((indexLast[0] == -1) || (indexLast[1] == -1))
            {
                return(FirstSmallestDistanceIndex(distances));
            }

            for (int indexA = distances.GetLowerBound(0); indexA <= distances.GetUpperBound(0); indexA++)
            {
                for (int indexB = distances.GetLowerBound(1); indexB <= distances.GetUpperBound(1); indexB++)
                {
                    if
                    //// Not the same object twice / no distance measurement ... zero.
                    ((indexA != indexB)
                     &&
                     //// Not the same indexes the other way around as last time (at least one value changed).
                     (indexLast[0] != indexB || indexLast[1] != indexA)
                     &&
                     //// Not the same indexes the same way around as last time (at least one value changed).
                     (indexLast[0] != indexA || indexLast[1] != indexB)
                     &&
                     //// Distance can be the same as the last one - if the index is higher.
                     ((Math.Abs(distances[indexA, indexB]) == Math.Abs(distances[indexLast[0], indexLast[1]]) && (indexA > indexLast[0] || (indexA >= indexLast[0] && indexB > indexLast[1])))
                      ||
                      //// Distance can be more, but only if it is less than the best found so far.
                      (Math.Abs(distances[indexA, indexB]) > Math.Abs(distances[indexLast[0], indexLast[1]]) && (indexBest[0] == -1 || indexBest[1] == -1 || Math.Abs(distances[indexA, indexB]) < Math.Abs(distances[indexBest[0], indexBest[1]])))))
                    {
                        indexBest[0] = indexA;
                        indexBest[1] = indexB;

                        if (distances[indexA, indexB] == distances[indexLast[0], indexLast[1]])
                        {
                            // If the distance is the same, then it is impossible to find a lower one, so break out, also, if no break, indexes may be skipped.
                            break;
                        }
                    }
                }
            }

            return(indexBest); //new int[] { indexBestA, indexBestB };
        }