fazer o programa encontrar valor ideal

04/02/2020

0

Olá senhores!
Estou com uma dúvida para encontrar um valor ideal ou otimizado para um sistema de vendas que precisa encontrar uma quantidade de produtos ideal para um valor:

exemplo: o usuario digita em um edit que precisa de 17 litros de oleo. Em um DBgrid existem varios modelos de um garrafas de oleos, cada uma com quantidades unicas, como:
-5 litros
-10 litros
-3 litros

como fazer o programa achar a quantidade de garrafas ideal para essa situação?

desde já agradeço muito!
Antonio Brandão

Antonio Brandão

Responder

Posts

10/02/2020

Emerson Nascimento

ideal não precisa ser exata, certo?
Responder

10/02/2020

Antonio Brandão

ideal não precisa ser exata, certo?
exatamente
Responder

12/02/2020

Emerson Nascimento

conseguiu resolver?
eu fiz uma função aqui... não ficou aqueeeela coisa, mas funciona...
Responder

12/02/2020

Antonio Brandão

conseguiu resolver?
eu fiz uma função aqui... não ficou aqueeeela coisa, mas funciona...
fiz um algoritmo semelhante a um algoritmo de "quantidade de moedas de troco em centavos" mas não funciona para encontrar valores aproximados.

pode postar o que você fez por favor?
Responder

13/02/2020

Emerson Nascimento


teste o programa e veja se é isso que espera:

https://www.4shared.com/rar/SgGQCYmCiq/Project6.html

ao descompactar, troque a extensão txt para exe



Responder

13/02/2020

Antonio Brandão


teste o programa e veja se é isso que espera:

https://www.4shared.com/rar/SgGQCYmCiq/Project6.html

ao descompactar, troque a extensão txt para exe





é muito parecido com isso, quais os comandos o programa faz?
Responder

13/02/2020

Emerson Nascimento

segue a função (em Delphi):
procedure CalcTroco( Valor: integer; Opcoes: TMoedas; var aResult: TRetornoCalc;
  lAceitaAproximado: boolean = False; lNaoEstourar: boolean = True );
var
  nInit, i, n, nMult: integer;
  nResto: integer;
  ValorCalc: integer;
begin
  TArray.Sort<integer>(Opcoes);

  ValorCalc := Valor;
  SetLength(aResult,Length(Opcoes));
  nInit := Low(aResult);
  for i := High(Opcoes) downto Low(Opcoes) do
  begin
    aResult[nInit,0] := Opcoes[i];
    aResult[nInit,1] := -1;
    Inc(nInit);
  end;

  nInit := Low(aResult);

  while (ValorCalc <> 0) do
  begin

    while (ValorCalc <> 0) and (nInit <= High(aResult)) do
    begin
      ValorCalc := Valor;
      for i := nInit to High(aResult) do
      begin
        if aResult[i,1] = -1 then
          aResult[i,1] := ValorCalc div aResult[i,0];
        ValorCalc := ValorCalc - (aResult[i,1] * aResult[i,0]);
        if ValorCalc = 0 then
          break;
      end;

      // se não conseguiu o cálculo exato
      if ValorCalc <> 0 then
      begin
        if aResult[nInit,1] > 0 then
          aResult[nInit,1] := aResult[nInit,1] - 1;
        for i := nInit+1 to High(aResult) do
          aResult[i,1] := -1;
        if aResult[nInit,1] = 0 then
          Inc(nInit);
      end;

    end;

    // se o valor não foi exato
    if ValorCalc <> 0 then
    begin
      if lAceitaAproximado then // verifico se pode ser valor aproximado
      begin
        if lNaoEstourar then
          Dec(Valor)
        else
          Inc(Valor);

        nInit := Low(aResult);
        for i := Low(aResult) to High(aResult) do
          aResult[i,1] := -1;
      end
      else
        ValorCalc := 0;
    end;

  end;

  // zero as quantidades que estiverem negativas
  for i := Low(aResult) to High(aResult) do
    if aResult[i,1] < 0 then
      aResult[i,1] := 0;

  // redistribui os valores, caso necessário
  for i := High(aResult) downto Low(aResult)+1 do
    if aResult[i,1] > 0 then
      for n := (i-1) downto Low(aResult) do
      begin
        nMult := (aResult[i,1] * aResult[i,0]) div aResult[n,0];
        nResto := (aResult[i,1] * aResult[i,0]) - (nMult * aResult[n,0]);
        if (nMult > 0) and ((nResto = 0) or ((nResto mod aResult[i,0])=0)) then
        begin
          aResult[i,1] := aResult[i,1] - ((nMult * aResult[n,0]) div aResult[i,0]);
          aResult[n,1] := aResult[n,1] + nMult;
        end;
      end;

end;

para trabalhar com a função no Delphi, criei dois tipos de dados para guardar tanto as opções possíveis, quanto o resultado:
type
  TRetornoCalc = array of array[0..1] of integer;
  TMoedas = TArray<integer>;

para utilizar você precisará passar para a função o valor que deseja distribuir, as opções que poderão ser utilizadas, a variável que receberá o resultado da distribuição, se aceita valor aproximado e, caso o valor possa ser aproximado, se será permitido 'estourar' o valor.
exemplo de uso:
procedure TForm3.Button4Click(Sender: TObject);
var
  i: integer;
  aRetorno: TRetornoCalc;
  aMoedas: TMoedas;
  strMensagem: string;
begin
  SetLength(aMoedas, 3);
  aMoedas[0] := 5;
  aMoedas[1] := 3;
  aMoedas[2] := 10;

  CalcTroco( 7, // valor desejado
             aMoedas, // opções disponíveis
             aRetorno, // retorno calculado
             True, // indica se aceita cálculo aproximado (se não conseguir exato)
             False ); // indica se calculo aproximado pode 'estourar' o valor

  strMensagem := '';
  for i := Low(aRetorno) to High(aRetorno) do
    strMensagem := strMensagem + FloatToStr(aRetorno[i,1])+' un de '+FloatToStr(aRetorno[i,0])+'l' + Chr(10) + Chr(13);
  ShowMessage(strMensagem);
end;

Responder

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar