private ElementType GetMinimumSum(
            IntegerSequence chosenReferences,
            SparseDictionaryMathMatrix <ElementType> currentMatrix,
            ElementType[] currentLineBoard,
            IEnumerable <KeyValuePair <int, ILongSparseMatrixLine <ElementType> > > lines,
            int chosenSolution)
        {
            var sum           = this.ring.AdditiveUnity;
            var solutionValue = chosenReferences[chosenSolution];
            var minimumCover  = GetMinimumCover(chosenReferences, lines, solutionValue);

            sum = this.ring.Add(sum, minimumCover);

            var columns = currentMatrix.GetColumns(solutionValue);

            foreach (var column in columns)
            {
                if (column.Key != solutionValue)
                {
                    var currentValue = currentMatrix[solutionValue, column.Key];
                    if (this.ring.Equals(currentValue, currentLineBoard[column.Key]))
                    {
                        minimumCover = this.GetMinimumCover(
                            chosenReferences,
                            lines,
                            column.Key);

                        minimumCover = this.ring.Add(minimumCover, this.ring.AdditiveInverse(currentValue));
                        sum          = this.ring.Add(sum, minimumCover);
                    }
                }
            }

            return(sum);
        }
        /// <summary>
        /// Escolhe a referência que minimiza a perda.
        /// </summary>
        /// <param name="chosenReferences">As referências escolhidas anteriormente.</param>
        /// <param name="currentMatrix">A matriz dos custos.</param>
        /// <param name="currentLineBoard">A linha que contém a condensação dos custos das linhas escolhidas.</param>
        /// <returns>O índice da linha correspondente à próxima referência bem como a perda respectiva.</returns>
        public Tuple <int, ElementType> Run(
            IntegerSequence chosenReferences,
            SparseDictionaryMathMatrix <ElementType> currentMatrix,
            ElementType[] currentLineBoard)
        {
            var result             = -1;
            var currentMinimumLost = default(ElementType);
            var lines = currentMatrix.GetLines();

            if (chosenReferences.Count > 2)
            {
                currentMinimumLost = this.GetMinimumSum(
                    chosenReferences,
                    currentMatrix,
                    currentLineBoard,
                    lines,
                    2);
                result = 2;
            }

            Parallel.For(2, chosenReferences.Count,
                         chosenSolution =>
            {
                var sum = this.GetMinimumSum(
                    chosenReferences,
                    currentMatrix,
                    currentLineBoard,
                    lines,
                    chosenSolution);

                lock (this.lockObject)
                {
                    if (this.comparer.Compare(sum, currentMinimumLost) < 0)
                    {
                        currentMinimumLost = sum;
                        result             = chosenSolution;
                    }
                }
            });

            if (result != -1)
            {
                var solutionValue = chosenReferences[result];
                var minimumCover  = this.GetMinimumCover(
                    chosenReferences,
                    lines,
                    solutionValue);

                currentLineBoard[solutionValue] = minimumCover;

                var columns = currentMatrix.GetColumns(solutionValue);
                foreach (var column in columns)
                {
                    if (column.Key != solutionValue)
                    {
                        var currentValue = currentMatrix[solutionValue, column.Key];
                        if (this.ring.Equals(currentValue, currentLineBoard[column.Key]))
                        {
                            minimumCover = this.GetMinimumCover(
                                chosenReferences,
                                lines,
                                solutionValue);

                            currentLineBoard[column.Key] = minimumCover;
                        }
                    }
                }
            }

            return(Tuple.Create(result, currentMinimumLost));
        }