/// <summary> /// Obtém um vector cujas entradas são nulas. /// </summary> /// <param name="integerDomain"> /// O objecto responsável pelas operações sobre os números inteiros. /// </param> /// <returns>O vector.</returns> private ArrayMathMatrix <Fraction <int> > GetZeroFilledVector( IntegerDomain integerDomain) { var result = new ArrayMathMatrix <Fraction <int> >( 6, 1, new Fraction <int>(0, 1, integerDomain)); return(result); }
/// <summary> /// Obtém o vector independente para tetar a matriz geral. /// </summary> /// <param name="domain">O objecto responsável pelas operações sobre inteiros.</param> private ArrayMathMatrix <Fraction <int> > GetIndVectorForGenMatrix( IntegerDomain domain) { var result = new ArrayMathMatrix <Fraction <int> >(2, 1); result[0, 0] = new Fraction <int>(2, 1, domain); result[1, 0] = new Fraction <int>(5, 1, domain); return(result); }
/// <summary> /// Obtém o vector independente para utilizar com a matriz singular. /// </summary> /// <param name="domain">O objecto responsável pelas operações sobre os números inteiros.</param> /// <returns>O vector.</returns> private ArrayMathMatrix <Fraction <int> > GetIndtVectorForSingularMatrix( IntegerDomain domain) { var result = new ArrayMathMatrix <Fraction <int> >(6, 1); result[0, 0] = new Fraction <int>(3, 1, domain); result[1, 0] = new Fraction <int>(-3, 1, domain); result[2, 0] = new Fraction <int>(-8, 1, domain); result[3, 0] = new Fraction <int>(-5, 1, domain); result[4, 0] = new Fraction <int>(-5, 1, domain); result[5, 0] = new Fraction <int>(8, 1, domain); return(result); }
/// <summary> /// Obtém uma matriz para testar o sistema de equações geral. /// </summary> /// <param name="integerDomain"> /// O objecto responsável pelas operações sobre inteiros. /// </param> /// <returns>A matriz de teste.</returns> private ArrayMathMatrix <Fraction <int> > GetGeneralMatrix( IntegerDomain integerDomain) { var result = new ArrayMathMatrix <Fraction <int> >(2, 3); result[0, 0] = new Fraction <int>(1, 1, integerDomain); result[0, 1] = new Fraction <int>(0, 1, integerDomain); result[0, 2] = new Fraction <int>(1, 1, integerDomain); result[1, 0] = new Fraction <int>(2, 1, integerDomain); result[1, 1] = new Fraction <int>(1, 1, integerDomain); result[1, 2] = new Fraction <int>(1, 1, integerDomain); return(result); }
public void Run_TriangDiagSymmDecompNoInverse() { // Definição dos domínios e fábricas. var integerDomain = new IntegerDomain(); var fractionField = new FractionField <int>(integerDomain); // Definição dos algoritmos. var target = new TriangDiagSymmDecompInverseAlg <Fraction <int> >(); var triangDecomp = new ParallelTriangDiagSymmMatrixDecomp <Fraction <int> >(fractionField); var arraySquareMatrixFactory = new ArraySquareMatrixFactory <Fraction <int> >(); var arrayMatrixFactory = new ArrayMathMatrixFactory <Fraction <int> >(); // A matriz var matrix = this.GetSingularMatrix(integerDomain); // Cálculos var triangDiagDecomp = triangDecomp.Run( matrix); var inverseMatrix = target.Run( triangDiagDecomp, arraySquareMatrixFactory, fractionField); // Verificação dos valores. var expected = ArrayMathMatrix <Fraction <int> > .GetIdentity(3, fractionField); var matrixMultiplication = new MatrixMultiplicationOperation <Fraction <int> >( arrayMatrixFactory, fractionField, fractionField); var actual = matrixMultiplication.Multiply(inverseMatrix, matrix); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { Assert.AreEqual(expected[i, j], actual[i, j]); } } }
/// <summary> /// Aplica o algoritmo sobre a matriz dos custos. /// </summary> /// <param name="costs">A matriz dos custos.</param> /// <param name="numberOfMedians">O número de medianas a serem escolhidas.</param> /// <returns>O resultado da relaxação.</returns> public CoeffType[] Run(SparseDictionaryMathMatrix <CoeffType> costs, int numberOfMedians) { if (costs == null) { throw new ArgumentNullException("costs"); } else { var numberOfVertices = costs.GetLength(1); var objectiveFunction = new List <SimplexMaximumNumberField <CoeffType> >(); // A mediana que cobre todas as outras é ligeiramente diferente objectiveFunction.Add(new SimplexMaximumNumberField <CoeffType>( this.coeffsField.AdditiveUnity, this.coeffsField.AdditiveInverse(this.coeffsField.MultiplicativeUnity))); for (int i = 1; i < numberOfVertices; ++i) { objectiveFunction.Add(new SimplexMaximumNumberField <CoeffType>( this.coeffsField.AdditiveUnity, this.coeffsField.AddRepeated( this.coeffsField.AdditiveInverse(this.coeffsField.MultiplicativeUnity), 2))); } // Adiciona as variáveis x à função objectivo. var numberXVars = 0; foreach (var line in costs.GetLines()) { foreach (var column in line.Value.GetColumns()) { if (line.Key != column.Key) { ++numberXVars; var valueToAdd = new SimplexMaximumNumberField <CoeffType>( column.Value, this.coeffsField.AdditiveInverse(this.coeffsField.MultiplicativeUnity)); objectiveFunction.Add(valueToAdd); } } } // Cria a matriz das restrições e preenche-a com os valores correctos var constraintsNumber = numberXVars + numberOfVertices; var nonBasicVariables = new int[objectiveFunction.Count]; var basicVariables = new int[constraintsNumber]; var linesLength = nonBasicVariables.Length + basicVariables.Length; // Preence os vectores que permitem seleccionar as variáveis. this.FillVariablesSelectors(nonBasicVariables, basicVariables, linesLength); // Preencimento da matriz das restrições var constraintsMatrix = new ArrayMathMatrix <CoeffType>( constraintsNumber, constraintsNumber, this.coeffsField.AdditiveUnity); var constraintLineNumber = 0; var constraintXYLineNumber = 0; var unity = this.coeffsField.MultiplicativeUnity; var inverseAdditive = this.coeffsField.AdditiveInverse(unity); foreach (var line in costs.GetLines()) { foreach (var column in line.Value.GetColumns()) { if (line.Key != column.Key) { constraintsMatrix[constraintXYLineNumber, constraintLineNumber] = inverseAdditive; constraintsMatrix[constraintXYLineNumber, constraintXYLineNumber + numberOfVertices] = unity; ++constraintXYLineNumber; } } ++constraintLineNumber; } var lastLine = constraintsNumber - 1; constraintsMatrix[lastLine, 0] = unity; constraintLineNumber = numberXVars; for (int i = 1; i < numberOfVertices; ++i) { constraintsMatrix[constraintLineNumber, i] = unity; constraintsMatrix[lastLine, i] = unity; constraintXYLineNumber = numberOfVertices; foreach (var lines in costs.GetLines()) { foreach (var column in lines.Value.GetColumns()) { if (lines.Key != column.Key) { if (column.Key == i) { constraintsMatrix[constraintLineNumber, constraintXYLineNumber] = unity; } ++constraintXYLineNumber; } } } ++constraintLineNumber; } // Preenchimento do vector independente das restrições var vector = new ArrayMathVector <CoeffType>(constraintsNumber, this.coeffsField.AdditiveUnity); lastLine = constraintsNumber - 1; for (int i = numberXVars; i < lastLine; ++i) { vector[i] = unity; } vector[lastLine] = this.conversion.InverseConversion(numberOfMedians); var sumVector = this.coeffsField.AdditiveUnity; for (int i = 0; i < vector.Length; ++i) { sumVector = this.coeffsField.Add(sumVector, vector[i]); } sumVector = this.coeffsField.AdditiveInverse(sumVector); var simplexInput = new SimplexInput <CoeffType, SimplexMaximumNumberField <CoeffType> >( basicVariables, nonBasicVariables, new ArrayMathVector <SimplexMaximumNumberField <CoeffType> >(objectiveFunction.ToArray()), new SimplexMaximumNumberField <CoeffType>(this.coeffsField.AdditiveUnity, sumVector), constraintsMatrix, vector); var resultSimplexSol = this.simplexAlg.Run(simplexInput); var result = new CoeffType[numberOfVertices]; Array.Copy(resultSimplexSol.Solution, result, numberOfVertices); return(result); } }