Use variable value not yet declared. Circular Reference in C #

2

I know the question seems absurd but a client of mine passed me an excel spreadsheet that has a variable that is used before having its calculation defined. In excel this calls Circular Reference.

I need to do this in my code.

Here's the part where I need it:

decimal valorFaturamentoPrevistoObra = ((subtotalGrupo1 + subtotalGrupo2) + valorDespesasEspecificas) * (1 + bdi);

decimal taxaRateioAdmCentral = (valorAdmCentralPeriodo * (valorFaturamentoPrevistoObra / (valorFaturamentoPeriodo + valorFaturamentoPrevistoObra)) / (subtotalGrupo1 + subtotalGrupo2)) * 100;

Taxa taxa = new Taxa();
var listaTaxas = taxa.ListaTaxaOrcamento(orcamento_id);

bdi = CalculaBDI(orcamento_id, listaTaxas, valorDespesasEspecificas, taxaRateioAdmCentral);

Notice that I need the variable "bdi" in the first line but that the calculation is only made lower. And that to make the calculation of it I need the value of the first line.

Does anyone have any idea how to solve this? It can be any solution.

Circular Reference in C #

    
asked by anonymous 20.12.2017 / 17:20

1 answer

2

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;                       
}
    
20.12.2017 / 23:02