Código que testa posiveis combinações

Olá pessoal, estou tentando criar um código que iria facilitar o meu trabalho em muito, mas estou precisando de uma ajuda pois não sei como poderia desenvolver isso.

Vamos lá:
O Exemplo abaixo é apenas para facilitar o entendimento, pois a aplicação real seria para controle meu de uma seção de finanças na qual trabalho. Vamos lá então:

Suponhamos que eu tenha um banco de dados com os campos e dados abaixo

Numero_controle Empresa valor
1 MERCADO 1.320,00
2 PADARIA 230,00
3 FARMÁCIA 315,00
4 ALUGUÉL 450,00
5 LOJA 89,00
6 AÇOUGUE 144,00

Partindo disso, eu precisava desenvolver um código onde eu entraria como um valor tipo 1.550,00 e ele me retornasse em uma jtable os itens que poderia pagar com esse valor com a condição de não sobrar resto. Exemplo mercado 1.320,00
Padartia 230,00

O código teria de testar as diversas possibilidades de combinações possíveis com os itens do banco de dados de maneira que não sobrasse resto. Quando essa não encontrasse uma combinação válida de resto = 0,0, retornaria uma mensagem qualquer informando não ter encontrado nenhuma combinação de valores com resto = zero.

Você precisa uma regra mais específica além dessa…

Tua prioridade é pagar as contas com maiores valores ou o maior numero de contas? Não há prioridades? Você tem uma determinada conta com maior prioridade do que outras?

No mais é só você colocar os cálculos em loop e ir somando, guardando as variáveis que deram certo naquele cálculo.

Á COISA FUNCIONA ASSIM, TRABALHO EM UM SETOR DE CONTAS ONDE SOU RESP PELO PAGAMENTO DE DIVERSAS NOTAS FISCAIS, O VALOR QUE CAI NA CONTA É EXATO PARA PAGAR UM NR X DE NOTAS, NEN SEMPRE É PRA PAGAR TODAS, AÍ QUE TÁ O PROBLEMA, PARA REALIZAR OS PAGAMENTOS EU TENHO QUE IR SOMANDO UMA A UMA ATÉ ACHAR UMA COMBINAÇÃO DE NOTAS QUE ME PERMITA PAGAR SEM SOBRAR RESTO NA CONTA E ISSO É BASTANTE DEMORADO QUANTO SE TRATA DE 70 OU 80 NOTAS. SE PODER ME AJUDAR ESBOÇE UM CÓDIGO PARA QUE EU TENHA IDÉIA DE COMO FAZER SE POSSIVEL O MAIS COMENTADO QUE VOCE PUDER…AGRADEÇO

Cara, eu entendo sua aflição, mas tenta não falar tudo em maiúsculo, não agradável para quem ler…

Bom, o seu problema é de Pesquisa Operacional (semelhante ao que é aplicado em logística, você tem mais dívidas do que dinheiro - é a mesma coisa de ter mais mercadorias do que caminhões para transportar), só tem uma coisa o que o Eltonk falou é muito válido, quais são as regras que você usa para pagar quando tem 80 notas? Você vai pele data de vencimento? Pelo valor da multa?

É exatamente com as respostas dessas pergunta que podemos te ajudar a construir um algoritmo para resolver o seu problema.

 [b]    Olá primeiramente desculpa pela letra maiuscula, não tinha me dado por conta quando escrevi...Bom quanto a prioridade de pagamento,  normalment os valores que  são depositados são semanais, ou seja todas notas que chegam ao longo da semana são pagos na semana seguinte, mas isso não é uma regra, as vezes além das notas da semana anterior vem valor para pagar uma ou mais notas da próxima semana, como esses valores não vem  declarados e sim num bolo todo, tenho que ir somando as diversas notas até achar uma combinação que o valor de exato (sem sobrar nada). não existe uma regra certa para o pagamento, dento do possivel eu pago as que estão a mais tempo esperando, no entando o unico critério que tenho de seguir sempre é que não sobre nada na conta ao final de cada pagamento. por isso o código deverá testar todas as possiveis combinações independentes da data da NF.......Agradeço.... [/b]

Pelo o que eu entendi, o código abaixo faz a tarefa. O resultado é o seguinte (usei os dados do exemplo).

Valor: R$ 1550,00
2 PADARIA 230.0
1 MERCADO 1320.0
Valor: R$ 769,00
5 LOJA 89.0
4 ALUGUEL 450.0
2 PADARIA 230.0
Valor: R$ 800,00
Não foi encontrado nada

Eu uso recursividade no programa, isto é, uma função que chama ela mesma. Por esse motivo os itens são incluídos no vetor de trás para frente. Para quem não está acostumado, é difícil entender a primeira vista. Eu testo as combinações. Há três condições de parada:

  1. Eu achei uma sequência de notas cuja soma é igual ao total fornecido
  2. A soma da minha sequência de notas ultrapassou o total
  3. Verifiquei todas as combinações

As funções main e imprime é só para mostrar como a classe Pagamento funciona. Eu uso o tipo long internamente na classe Pagamento para fazer os cálculo porque a representação de ponto flutuante (número com casas decimais) pode dar problemas, principalmente em comparações, pois o computador não consegue armazenar internamente de forma exata o número 2,19, por exemplo.

Espero que ajude.
Leila

[code]import java.util.ArrayList;

public class Pagamento {

private ArrayList<Item> _meusItens = new ArrayList<Item>();

/**
 * Adiciona um novo item à lista
 * @param numeroControle
 * @param empresa
 * @param valor
 */
public void adicionaItem(int numeroControle, String empresa, float valor){
    Item item = new Item(numeroControle, empresa, valor);
    _meusItens.add(item);
}

/**
 * Retorna o vetor com todos os itens que possuem a dada soma,
 * se não haver nenhuma situação, o vetor possui tamanho 0
 * @param soma a soma que precisa ser encontrada
 * @return o vetor com todos os itens que possuem a dada soma
 */
public Item[] encontraItens(float total) {
    long l_total = (long)(total * 100 + 0.5);
    ArrayList<Item> listaItens = new ArrayList<Item>();
    encontraItens (0, l_total, 0, listaItens);
    listaItens.toArray(new Item[0]);
    return listaItens.toArray(new Item[0]);
}

private boolean encontraItens (long soma, long total, int posicao, ArrayList<Item> itens) {
    boolean encontrou = false;
    for (int i=posicao; i < _meusItens.size() && !encontrou; i++) {
        if (soma + _meusItens.get(i).getLValor() == total) {
            itens.add(_meusItens.get(i));
            encontrou = true; // encontrei a soma !!!
        } else if (soma + _meusItens.get(i).getLValor() < total) {
            encontrou = encontraItens (soma + _meusItens.get(i).getLValor(),
                                       total, i+1, itens);
            if (encontrou) {
                //adiciona o item só se a soma for encontrada
                itens.add(_meusItens.get(i));
            }
        }
    }
    return encontrou;
}
/**
 * Representa um Item
 */
public class Item {
    private int _numeroControle;
    private String _empresa;
    private long _valor;

    public Item(int numeroControle, String empresa, float valor){
        _numeroControle = numeroControle;
        _empresa = empresa;
        _valor = (long)(valor*100+0.5); //evita erros de arrendodamento
    }

    /**
     * @return the _numeroControle
     */
    public int getNumeroControle() {
        return _numeroControle;
    }

    /**
     * @return the _empresa
     */
    public String getEmpresa() {
        return _empresa;
    }

    /**
     * @return the _valor
     */
    public long getLValor() {
        return _valor;
    }

    public float getValor() {
        return _valor / 100.0f;
    }
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    Pagamento pag = new Pagamento();
    Pagamento.Item itens[];
    pag.adicionaItem (1,"MERCADO",1320);
    pag.adicionaItem (2,"PADARIA",230);
    pag.adicionaItem (3,"FARMACIA",315);
    pag.adicionaItem (4,"ALUGUEL",450);
    pag.adicionaItem (5,"LOJA", 89);
    pag.adicionaItem (6,"AÇOUGUE",144);

    itens = pag.encontraItens(1550);
    System.out.println("Valor: R$ 1550,00 ");
    imprime(itens);
    itens = pag.encontraItens(769);
    System.out.println("Valor: R$ 769,00 ");
    imprime(itens);
    itens = pag.encontraItens(800);
    System.out.println("Valor: R$ 800,00 ");
    imprime(itens);

}

public static void imprime(Pagamento.Item itens[]) {
    if (itens.length==0) {
        System.out.println("Não foi encontrado nada");
    }else {
        for (int i=0; i < itens.length; i++) {
            System.out.println(itens[i].getNumeroControle()+" "+itens[i].getEmpresa()+" "+itens[i].getValor());
        }
    }

}

}
[/code]

Primeiramente que agradecer pela ajuda que estou tendo no forum, testei o código do lalgarve e funcionou legal, só que a minha base de dados esta em uma tabela do acess (dados_notas). a conecção com o banco eu já fiz estou até inserindo novos dados diretamente de um jpainel. Minha duvida está em como fazer para que ele faça a pesquisa diretamente nos dados da tabela e em retorne em uma grade. Estou tentando resolver por aqui mas por enquanto sem sucesso… mais uma vez obrigado…