Desafio matematico
01/09/2004
0
Abaixo um ilustração para melhor entendimento
[img:70f92becb9]http://www.idw.kit.net/teste.jpg[/img:70f92becb9]
Chico Gois
Posts
02/09/2004
Motta
V = (12-x)^2 * x
ai é calcular os minimos e maximos (derivando...)
02/09/2004
Chico Gois
Realmente é classico esse exercicio, tanto que faz uns 25 anos que vi calculo e não esqueci dele....... :lol:
02/09/2004
Beppe
02/09/2004
Chico Gois
Tenta ai, caso não consiga eu posto o resultado comentado.
Mas cuidado pra não se atrapalhar pra calcular volume........ :twisted:
02/09/2004
Beppe
Eu, me atrapalhar? Sou praticamente um Gottfried Leibniz... :roll:
04/09/2004
Beppe
Enfim, como matemático, sou um ótimo programador! 8)
Solução:
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;
06/09/2004
Chico Gois
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;
:shock:
Esse é o meu garoto..... :lol:
06/09/2004
Beppe
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
07/09/2004
Cebikyn
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!
08/09/2004
Motta
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 :)
08/09/2004
Beppe
Eu trabalho em grupo, mas isoladamente! :)
Assim é melhor, ninguém se mete.
Clique aqui para fazer login e interagir na Comunidade :)