Um valor ex vlDebitosCreditos: 24.850,00 que seria minha diferença,
e uma determinada lista de lançamentos, cada lançamento conténdo um valor.
ex 7.850,00; 4.183,83 e 17.000,00
A soma de alguns lançamentos pode bater com o vlDebitosCreditos, zerando a diferença.
no caso 17.000,00 + 7.850,00 = 24.850,00.
Como fazer para descobrir quais valores somados zeram a diferença?
Você disse que a ordem dos lançamentos altera.
Isso quer dizer que você precisaria pegar todos os valores de lançamentos, e ir somando de dois em dois, de três em três… até achar o tal valor desejado (24.850,00)?
Não entendi mesmo qual é o seu problema.
Aha, esse é o problema de 1 milhão de dólares. Se a lista for pequena, ainda dá para você tentar todas as combinações dos valores e tentar somar, mas se a lista for grande, você tem de usar algo mais poderoso.
O método recursivo abaixo que desenvolvi especialmente pra você resolve o problema.
Ele retorna um HashSet contendo todos as combinações possíveis de Vectors com os valores que combinados dão a soma.
Abaixo, também forneço um exemplo de uso do método.
[b]ATENÇÃO.
Na chamada inicial da função o vetor A deve estar vazio e o vetor B deve conter todos os elementos.
[/b]
public static HashSet<Vector<Double>> achaSoma(Vector<Double> A, Vector<Double> B, double soma) {
HashSet<Vector<Double>> poss = new HashSet<Vector<Double>>();
Vector<Double> myVector = new Vector<Double>();
double somaA = 0;
for (Double y: A) {
somaA += y;
}
if (somaA == soma) {
for (Double y: A) {
myVector.add(y);
}
Collections.sort(myVector);
poss.add(myVector);
}
for (Double x: B) {
Vector<Double> C = new Vector<Double>(A);
C.add(x);
Vector<Double> D = new Vector<Double>(B);
D.remove(x);
poss.addAll(achaSoma(C,D, soma));
}
return(poss);
}
public static void main(String[] args) {
Vector<Double> nval = new Vector<Double>();
Vector<Double> valores = new Vector<Double>();
HashSet<Vector<Double>> possibilidades = new HashSet<Vector<Double>>();
valores.add(1.0);
valores.add(2.0);
valores.add(3.0);
valores.add(4.0);
valores.add(5.0);
valores.add(6.0);
possibilidades = achaSoma(nval, valores, 10);
for (Vector<Double> X: possibilidades) {
for (Double y: X) {
System.out.print(y);
System.out.print(" ");
}
System.out.println("");
}
}
Sim, como se trata de um problema NP-Completo, a demora é exponencial.
Se os dados forem tratados antes de entrarem no método, você pode conseguir algum ganho.
Por exemplo, removendo todos os números maiores que o resultado esperado, caso não tenha valores negativos na lista.
Cabe ainda otimização no método. Hoje ele está comparando todas as combinações possíveis, com isso ele compara A B C, A C B, B A C, B C A, C A B e C B A. Que no seu caso, são a mesma coisa, pois a ordem não importa.
Ele só elimina essas combinações na hora de jogar o resultado ordenado no HashSet.
De qualquer forma, caso não tenha urgência em receber a reposta e o resultado seja realmente algo muito importante, não custa nada deixar o PC ligado uma noite fazendo os cálculos.