/// <summary> /// Executa o algoritmo do simplex habitual sobre os dados de entrada. /// </summary> /// <param name="data">Os dados de entrada.</param> /// <returns>O resultado da execução.</returns> /// <exception cref="ArgumentNullException"> /// Se os dados de entrada forem passados com um apontador nulo. /// </exception> public SimplexOutput <CoeffType> Run(SimplexInput <CoeffType, CoeffType> data) { if (data == null) { throw new ArgumentNullException("data"); } else { var hasSolution = true; var enteringVariable = this.GetNextEnteringVariable(data); var state = enteringVariable != -1; while (state) { var leavingVariable = this.GetNextLeavingVariable( enteringVariable, data.ConstraintsMatrix, data.ConstraintsVector); if (leavingVariable == -1) { hasSolution = false; state = false; } else { this.ProcessReduction( enteringVariable, leavingVariable, data.ConstraintsMatrix, data.ConstraintsVector); data.Cost = this.ProcessObjectiveFunction( enteringVariable, leavingVariable, data.BasicVariables, data.NonBasicVariables, data.Cost, data.ObjectiveFunction, data.ConstraintsMatrix, data.ConstraintsVector); enteringVariable = this.GetNextEnteringVariable(data); state = enteringVariable != -1; } } if (hasSolution) { return(this.BuildSolution( data.BasicVariables, data.NonBasicVariables, data.ConstraintsVector, data.Cost)); } else { return(new SimplexOutput <CoeffType>(null, default(CoeffType), false)); } } }
/// <summary> /// Obtém a próxima variável de entrada. /// </summary> /// <param name="data">Os dados de entrada.</param> /// <returns>A variável caso exista e -1 caso contrário.</returns> private int GetNextEnteringVariable(SimplexInput <CoeffType, CoeffType> data) { var result = -1; var value = this.coeffsField.AdditiveUnity; var length = data.ObjectiveFunction.Length; for (int i = 0; i < length; ++i) { var current = data.ObjectiveFunction[i]; if (this.coeffsComparer.Compare(current, this.coeffsField.AdditiveUnity) < 0) { if (this.coeffsComparer.Compare(current, value) < 0) { result = i; value = current; } } } return(result); }
/// <summary> /// Obtém a próxima variável de entrada. /// </summary> /// <param name="data">Os dados de entrada.</param> /// <returns>A variável caso exista e -1 caso contrário.</returns> private int GetNextEnteringVariable(SimplexInput <CoeffType, SimplexMaximumNumberField <CoeffType> > data) { var result = -1; var value = new SimplexMaximumNumberField <CoeffType>( this.coeffsField.AdditiveUnity, this.coeffsField.AdditiveUnity); var length = data.ObjectiveFunction.Length; for (int i = 0; i < length; ++i) { var current = data.ObjectiveFunction[i]; if (this.coeffsComparer.Compare(current.BigPart, this.coeffsField.AdditiveUnity) <= 0) { if (this.ComapareBigNumbers(current, value) < 0) { result = i; value = current; } } } return(result); }