Comparar soma de valores de uma lista com um determinado valor

Boa tarde, tenho a seguinte situação.

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?

Eu fiz algo ± assim:

for (LancGerado lancGeradoAcerto : listAcerto) {
	vlAcerto += lancGeradoAcerto.getVlContabil();
	if(NumberUtils.round(vlDebitosCreditos) == NumberUtils.round(vlAcerto)){
		//faz tratamento
	}
}
public static double round(double numero) {		
	return round(numero, 2, BigDecimal.ROUND_HALF_UP);
}

so que isso pode não funcionar, pois a ordem dos lançamentos(valores) influencia

Espero ter sido claro no problema.

Como você faria isso no Excel?

ixi, nao manjo nd de excel

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.

pois então, como eu devo fazer para localizar os valores q somados irão zerar minha diferença? esse é o problema. fiquei meio travado nisso.

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 seguinte meu chapa.

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("");
		}
		
	}

vlw, vou dar uma testada.

pablosaraiva, o metodo resolveu o problema, porém em alguns casos o processamento é muito demorado.
Vlw de qq forma.

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. :slight_smile:

Um abraço, boa sorte.

como eu poderia otimizar este calculo?