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)); }