Desafio matematico

Off Topic

01/09/2004

Como faz tempo que não tem isso, aqui vai um facim, facim


Um fabricante de caixas de papelão deseja fazer caixas abertas de pedaços de papelão de 12 cm quadrados, cortando quadrados iguais nos quatros cantos e dobrando os lados. Encontre o comprimento do lado do quadrado que se deve cortar para obter uma caixa cujo volume seja o maior possivel.



Abaixo um ilustração para melhor entendimento



Chico Gois

Chico Gois

Curtidas 0

Respostas

Motta

Motta

01/09/2004

Na faculdade qdo aprendi, cálculo diferencial, vi este problema é um clássico, não lembro a solução mas

V = (12-x)^2 * x

ai é calcular os minimos e maximos (derivando...)


GOSTEI 0
Chico Gois

Chico Gois

01/09/2004

yes!

Realmente é classico esse exercicio, tanto que faz uns 25 anos que vi calculo e não esqueci dele....... :lol:


GOSTEI 0
Beppe

Beppe

01/09/2004

Achei ele no meu livro de cálculo também...só que o livro só tem as respostas dos exercícios de números ímpares...grrrrr...acho que vou ter que fazer... :oops:


GOSTEI 0
Chico Gois

Chico Gois

01/09/2004

Risos.....

Tenta ai, caso não consiga eu posto o resultado comentado.

Mas cuidado pra não se atrapalhar pra calcular volume........ :twisted:


GOSTEI 0
Beppe

Beppe

01/09/2004

Risos..... Tenta ai, caso não consiga eu posto o resultado comentado. Mas cuidado pra não se atrapalhar pra calcular volume........ :twisted:

Eu, me atrapalhar? Sou praticamente um Gottfried Leibniz... :roll:


GOSTEI 0
Beppe

Beppe

01/09/2004

Bah, eu sabia fazer essa com dimensões 16 x 30...(como tá no meu livro... :oops: )

Enfim, como matemático, sou um ótimo programador! 8)

Solução:

X = 2; V = 128

procedure MaximizeVolume(SideX, SideY: Double; out X, Volume: Double);

  procedure V(X: Double; out Result: Double);
  begin
    Result := X * (SideX - 2 * X) * (SideY - 2 * X);
  end;

  procedure F(const X: array of Double; out Result: Double);
  var
    H, I: Integer;
    S: array of Double;
  begin
    if not SameValue(X[Low(X)], X[High(X)]) then
    begin
      H := Low(X);
      SetLength(S, Length(X));
      for I := Low(X) to High(X) do
        V(X[I], S[I]);

      for I := Low(X) + 1 to High(X) do
        if S[I] > S[H] then
          H := I;
      F([X[H - 1], (X[H - 1] + X[H]) / 2, X[H], (X[H] + X[H + 1]) / 2, X[H + 1]],
        Result);
    end else
      Result := X[Low(X)];
  end;

var
  MinorSide: Double;
begin
  if SideX < SideY then
    MinorSide := SideX
  else
    MinorSide := SideY;
  F([0, MinorSide * 0.125, MinorSide * 0.25, MinorSide * 0.375, MinorSide * 0.5], X);
  V(X, Volume);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  X, V: Double;
begin
  MaximizeVolume(12, 12, X, V);
  Label1.Caption := Format(´X = ¬f; Volume = ¬f´, [X, V]);
end;



GOSTEI 0
Cebikyn

Cebikyn

01/09/2004

Ae Beppe, num tem como rola uns comentários no código?


GOSTEI 0
Motta

Motta

01/09/2004

O Beppe é daqueles que não conhece o // nem o {}
:)


GOSTEI 0
Chico Gois

Chico Gois

01/09/2004

Bah, eu sabia fazer essa com dimensões 16 x 30...(como tá no meu livro... :oops: ) Enfim, como matemático, sou um ótimo programador! 8) Solução: [quote:97d21e5015]X = 2; V = 128

procedure MaximizeVolume(SideX, SideY: Double; out X, Volume: Double);

  procedure V(X: Double; out Result: Double);
  begin
    Result := X * (SideX - 2 * X) * (SideY - 2 * X);
  end;

  procedure F(const X: array of Double; out Result: Double);
  var
    H, I: Integer;
    S: array of Double;
  begin
    if not SameValue(X[Low(X)], X[High(X)]) then
    begin
      H := Low(X);
      SetLength(S, Length(X));
      for I := Low(X) to High(X) do
        V(X[I], S[I]);

      for I := Low(X) + 1 to High(X) do
        if S[I] > S[H] then
          H := I;
      F([X[H - 1], (X[H - 1] + X[H]) / 2, X[H], (X[H] + X[H + 1]) / 2, X[H + 1]],
        Result);
    end else
      Result := X[Low(X)];
  end;

var
  MinorSide: Double;
begin
  if SideX < SideY then
    MinorSide := SideX
  else
    MinorSide := SideY;
  F([0, MinorSide * 0.125, MinorSide * 0.25, MinorSide * 0.375, MinorSide * 0.5], X);
  V(X, Volume);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  X, V: Double;
begin
  MaximizeVolume(12, 12, X, V);
  Label1.Caption := Format(´X = ¬f; Volume = ¬f´, [X, V]);
end;
[/quote:97d21e5015]


:shock:

Esse é o meu garoto..... :lol:


GOSTEI 0
Beppe

Beppe

01/09/2004

O Beppe é daqueles que não conhece o // nem o {} :)

O // me parece que é um sinal de trânsito, já o {} eu não conheço não... :roll:

cebys, eu não costumo comentar meu código não, porque geralmente código é auto-explicativo. O melhor a fazer é descrever o algoritmo, e com comentários pra melhor se localizar.

- O procedimento MaximizeVolume calcula X e o volume para o problema, baseado em amostras que ele mesmo gera. As amostras geradas diretamente por ele são frações de [i:0d25b69be7]MinorSide[/i:0d25b69be7], igualmente separadas entre si, de 0/10 a 5/10. O motivo pela escolha de 5/10 é que em cada lado haverá dos cortes de largura X(0.5 * 2 = 1).

- A rotina aninhada F é uma função recursiva que recebe uma amostra, e chama a si mesmo com novas amostras, cada vez tendo reduzida a distância entre cada fração. É um algoritmo divida-e-conquiste, semelhante ao método que utilizamos para achar uma palavra no dicionário. A diferença é que o universo a ser pesquisado não é conhecido de antemão: novos valores são computados.

- Entre os valores de amostra computados por F estão o ´melhor´ X, o vizinho mais próximo de cada lado, e uma média aritmética entre si, totalizando 5 valores. Pela natureza contínua dos números flutuantes, o primeiro e o ultimo valor de amostra não são escolhidos como o ´melhor´, exceto no caso da busca ter acabado.

- As amostras passadas no array estão ordenadas não-decrescentemente, por natureza.

- SameValue é uma rotina de math no Delphi 7 que verifica se os valores passados são próximos, dada uma precisão.

procedure MaximizeVolume(SideX, SideY: Double; out X, Volume: Double);

  procedure V(X: Double; out Result: Double);
  begin
    // calcula o volume tendo um corte de X^2 em cada canto
    Result := X * (SideX - 2 * X) * (SideY - 2 * X);
  end;

  procedure F(const X: array of Double; out Result: Double);
  var
    H, I: Integer;
    S: array of Double;
  begin
    if not SameValue(X[Low(X)], X[High(X)]) then
    begin
      // memoriza o volume para os X´s passados como amostra
      H := Low(X);
      SetLength(S, Length(X));
      for I := Low(X) to High(X) do
        V(X[I], S[I]);

      // acha um X na amostra tal que a caixa tenha o volume maximizado
      for I := Low(X) + 1 to High(X) do
        if S[I] > S[H] then
          H := I;

      // recursiona a partir de novas amostras
      F([X[H - 1], (X[H - 1] + X[H]) / 2, X[H], (X[H] + X[H + 1]) / 2, X[H + 1]],
        Result);
    end else
      // se o menor e o maior valor na amostra forem suficientemente próximos, 
      // o algoritmo acabou
      Result := X[Low(X)];
  end;

var
  MinorSide: Double;
begin
  // calcula o tamanho máximo de X*2
  if SideX < SideY then
    MinorSide := SideX
  else
    MinorSide := SideY;

  // chama F com 5 valores de amostra
  F([0, MinorSide * 0.125, MinorSide * 0.25, MinorSide * 0.375, MinorSide * 0.5], X);

  // calcula o volume com X sendo conhecido
  V(X, Volume);
end;


Ufa, acho que é isto... :D


GOSTEI 0
Cebikyn

Cebikyn

01/09/2004

cebys, eu não costumo comentar meu código não, porque geralmente código é auto-explicativo. O melhor a fazer é descrever o algoritmo, e com comentários pra melhor se localizar.


Tanto faz, vc pode por a descrição do algoritmo como comentários dentro do código, pra isso servem os pares ´{´ - ´}´ e ´(*´ - ´*)´. :roll:

De qq forma, vlw a explicação!


GOSTEI 0
Motta

Motta

01/09/2004

cebys, eu não costumo comentar meu código não, porque geralmente código é auto-explicativo. O melhor a fazer é descrever o algoritmo, e com comentários pra melhor se localizar.



Quando se trabalha num projeto grande, a documentação é útil, pois nem todos da equipe tem o mesmo dominio da linguagem.

sinal de transito !! boa :)


GOSTEI 0
Beppe

Beppe

01/09/2004

Quando se trabalha num projeto grande, a documentação é útil, pois nem todos da equipe tem o mesmo dominio da linguagem.

Eu trabalho em grupo, mas isoladamente! :)
Assim é melhor, ninguém se mete.


GOSTEI 0
POSTAR