This is a typical linear programming problem and there are several algorithms to solve it. You could use, for example, a Simplex Maximization algorithm.
Many people prefer to use Excel to solve this kind of problem because it already comes with tools such as the Hypothesis Testing and Solver , which implement some linear programming algorithms.
In particular, I consider the implementation of these algorithms complex. After my Operational Research classes (and this is a long time ago!), I never needed to implement one again. Of the few times that I came across such a problem, I used Excel myself.
Solution 1
For a robust and efficient solution, I suggest you implement a linear programming algorithm . You can find an implementation of the Simplex Maximization method in Simplex maximization algorithm in C # .
Solution 2
For a much simpler solution, you can mount a hypothesis testing loop until you find the most appropriate value.
Since you want to find the value of
dbi
that results in the highest possible value for
valorFaturamentoPrevistoObra
, the algorithm below loops to test hypotheses of the billing value until you find the maximized value (the detailed explanation is in the comments ).
Taxa taxa = new Taxa();
var listaTaxas = taxa.ListaTaxaOrcamento(orcamento_id);
//Crie uma varíavel para determinar o menor valor possível do faturamento
decimal faturamentoMinimo = (subtotalGrupo1 + subtotalGrupo2 + valorDespesasEspecificas);
//Crie uma variável para testar hipóteses de valor do faturamento
//Como se quer um valor maximizado, inicie o valor da hipoótese com um valor bem alto
//Estou sugerindo aqui que seja 3 vezes o faturamento mínimo mas pode ser maior ou menor
//Lembrando que, quanto maior, mais lenta será a execução
decimal hipoteseFaturamento = 3 * faturamentoMinimo;
//Faça um loop para testar o valor da hipótese até o limite mínmo
while (hipoteseFaturamento > faturamentoMinimo)
{
//calcule a taxa de rateio com base no valor da hipótese
taxaRateioAdmCentral = (valorAdmCentralPeriodo * (hipoteseFaturamento / (valorFaturamentoPeriodo + hipoteseFaturamento)) / (subtotalGrupo1 + subtotalGrupo2)) * 100;
//Calcule o bdi
bdi = CalculaBDI(orcamento_id, listaTaxas, valorDespesasEspecificas, taxaRateioAdmCentral);
//Calcule o faturamento previsto
valorFaturamentoPrevistoObra = ((subtotalGrupo1 + subtotalGrupo2) + valorDespesasEspecificas) * (1 + bdi);
//Verifique se o faturamento previsto é igual à hipótese,
//se for igual, você encontrou o bdi desejado
//se não for, diminua o valor da hipótese e calcule novamente
if (hipoteseFaturamento == valorFaturamentoPrevistoObra)
break;
else
hipoteseFaturamento -= 1;
}