/// <summary>
        /// Obtém a matriz de compatiblidade através dos custos.
        /// </summary>
        /// <param name="costsMatrix">A matriz dos custos.</param>
        /// <param name="sortedElements">
        /// O contentor para o conjunto de elementos ordenados por custo.
        /// </param>
        /// <returns>
        /// A matriz de compatibilidade ordenada de acordo como os elementos se encontram na matriz.
        /// </returns>
        private BitArraySymmetricMatrix GetCompatibilityMatrix(
            ILongSparseMathMatrix <CostsType> costsMatrix,
            InsertionSortedCollection <CoordsElement> sortedElements)
        {
            // Efectua a contagem de elementos atribuídos na matriz.
            var elementsNumber = 0;

            foreach (var line in costsMatrix.GetLines())
            {
                foreach (var column in line.Value)
                {
                    ++elementsNumber;
                }
            }

            var result           = new BitArraySymmetricMatrix(elementsNumber, elementsNumber, false);
            var processedColumns = new List <CoordsElement> [costsMatrix.GetLength(0)];

            for (int i = 0; i < processedColumns.Length; ++i)
            {
                processedColumns[i] = new List <CoordsElement>();
            }

            var currentIndex = 0;

            foreach (var line in costsMatrix.GetLines())
            {
                foreach (var column in line.Value)
                {
                    if (column.Key != line.Key)
                    {
                        var element = new CoordsElement(line.Key, column.Key, currentIndex, column.Value);
                        sortedElements.Add(element);
                        var processedColumn = processedColumns[column.Key];
                        foreach (var processed in processedColumn)
                        {
                            result[processed.CompatibilityIndex, currentIndex] = true;
                        }

                        processedColumn.Add(element);

                        // Processa o pivor
                        processedColumn = processedColumns[line.Key];
                        foreach (var processed in processedColumn)
                        {
                            result[processed.CompatibilityIndex, currentIndex] = true;
                        }

                        ++currentIndex;
                    }
                }
            }


            return(result);
        }
        /// <summary>
        /// Permite obter a próxima variável não compatível associada à matriz de compatibilidade.
        /// </summary>
        /// <param name="last">A última variável a ser escolhida.</param>
        /// <param name="board">A intersecção de todas as linhas de compatibilidade.</param>
        /// <param name="compatibility">A matriz de compatibilidade.</param>
        /// <returns>O índice da próxima variável e -1 caso não seja possível obtê-lo.</returns>
        private int GetNextVariableIndex(
            int last,
            InsertionSortedCollection <CoordsElement> orderedCosts,
            BitArray board,
            BitArraySymmetricMatrix compatibility)
        {
            var result = -1;
            var length = compatibility.GetLength(0);

            for (int i = last + 1; i < length; ++i)
            {
                var lineIndex       = orderedCosts[i].CompatibilityIndex;
                var isNotCompatible = true;
                for (int j = 0; j < i; ++j)
                {
                    var columnIndex       = orderedCosts[j].CompatibilityIndex;
                    var compatibilityItem = compatibility[lineIndex, columnIndex];
                    if (compatibilityItem && board[columnIndex])
                    {
                        isNotCompatible = false;
                        j = i;
                    }
                }

                if (isNotCompatible)
                {
                    for (int j = i + 1; j < length; ++j)
                    {
                        var columnIndex       = orderedCosts[j].CompatibilityIndex;
                        var compatibilityItem = compatibility[lineIndex, columnIndex];
                        if (compatibilityItem && board[j])
                        {
                            isNotCompatible = false;
                            j = length;
                        }
                    }

                    if (isNotCompatible)
                    {
                        result = i;
                        board[orderedCosts[i].CompatibilityIndex] = true;
                        i = length;
                    }
                }
            }

            return(result);
        }