Array
(
)

Desafio matematico

Chico Gois
   - 01 set 2004

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



Citação:


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

[img:70f92becb9]http://www.idw.kit.net/teste.jpg[/img:70f92becb9]


Motta
   - 02 set 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...)


Chico Gois
   - 02 set 2004

yes!

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


Beppe
   - 02 set 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:


Chico Gois
   - 02 set 2004

Risos.....

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

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


Beppe
   - 02 set 2004


Citação:
Risos.....

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

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

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


Beppe
   - 04 set 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:


Citação:
X = 2; V = 128

#Código

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;

#Código
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;



Cebikyn
   - 06 set 2004

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


Motta
   - 06 set 2004

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


Chico Gois
   - 06 set 2004


Citação:
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:


Citação:
X = 2; V = 128

#Código

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;

#Código
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;



:shock:

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


Beppe
   - 06 set 2004


Citação:
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 MinorSide, 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.

#Código

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


Cebikyn
   - 07 set 2004


Citação:
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!


Motta
   - 08 set 2004


Citação:

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 :)


Beppe
   - 08 set 2004


Citação:
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.