| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 13/11/2009 10:57:33
|
tnaires
GUJ Master
![[Avatar]](/images/avatar/5f6371c9126149517d9ba475def53139.png)
Membro desde: 22/12/2003 08:05:58
Mensagens: 1678
Localização: Porto Alegre/RS - Natal/RN
Offline
|
Bom dia pessoal.
Estou implementando o algoritmo simulated annealing para resolver o problema do caixeiro viajante - sim, é trabalho de faculdade - e, se possível, gostaria de colher opiniões sobre uma questão.
Estou usando double para armazenar o valor da temperatura do sistema, e uma das condições de parada do algoritmo é quando a temperatura chega a (ou se aproxima de) zero. No meu caso estou implementando o laço da seguinte forma:
Porém o algoritmo às vezes não finaliza sua execução por causa da imprecisão do tipo de dados double. Eu tenho duas opções:
1) Usar BigDecimal, que é preciso mas é mais custoso. Tenho dúvidas se seria uma boa opção por causa da performance, uma vez que as instâncias do caixeiro viajante podem possuir dezenas de milhares de cidades;
2) Mudar a comparação para tolerar uma temperatura próxima de zero ao invés de exatamente igual. Nesse caso, qual seria o valor ideal?
Desde já agradeço a atenção de todos. Abraços
|
Tarso Nunes Aires
Blog - http://cabritin.wordpress.com/
Delicious - http://delicious.com/tnaires
Twitter - @tnaires
 |
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 13/11/2009 13:36:48
|
entanglement
GUJ Hacker
Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline
|
Algoritmos de cálculo numérico não devem usar esse tipo de comparação contra um valor exato. (
) .
Pra começar, Double.compare (t1, t2) <= 0 é um desperdício de tempo; use t1 <= t2.
Eles SEMPRE devem usar tolerâncias. Ou seja, o correto é usar, no seu caso,
onde eps é um valor que você deve configurar. Digamos que seja 1E-5, mas não conheço seu algoritmo tão detalhadamente que possa saber se 1E-5 é um valor muito baixo ou alto demais.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 13/11/2009 15:28:29
|
clone_zealot
JavaEvangelist
Membro desde: 21/11/2004 16:40:00
Mensagens: 424
Offline
|
Isso é um trabalho de faculdade, correto?
Pois bem, existe necessidade de vc se preocupar com performance? Ainda mais que estamos falando de caixeiro-viajante, que é um problema complexo...
Não estou falando que foi ruim vc ter pensado nisso. Muito pelo contrário!!! É ótimo ver que vc se preocupa com esse tipo de coisa. Mostra que vc é/será um bom desenvolvedor, mas talvez o que realmente importa seja a lógica do algoritmo, e não esse tipo de coisa.
Estou te incentivando a manter o foco no problema, e não na solução. Se, para esse trabalho, o professor exigir que o algoritmo rode num tempo y, OK, você deve se preocupar com isso. Com contrário, se preocupe com o objetivo.
E outra coisa: pq vc não transforma esses valores decimais em valores inteiros? Tipo, vc sabe qual o menor valor que será de entrada?
Digamos que seja 0,0001 grau. Bastaria vc multiplicar TODOS os valores de temperatura por 10.000 e vc só precisará trabalhar com inteiros. Dai vc não precisar se preocupar com a aritmética de ponto flutuante do Java.
|
"Não amo a espada por sua agudez,
não amo a flecha por sua rapidez,
não amo o homem por sua glória,
amo sim, tudo o que eles defendem"
Faramir, Príncipe de Ithilien |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 13/11/2009 15:28:54
|
tnaires
GUJ Master
![[Avatar]](/images/avatar/5f6371c9126149517d9ba475def53139.png)
Membro desde: 22/12/2003 08:05:58
Mensagens: 1678
Localização: Porto Alegre/RS - Natal/RN
Offline
|
entanglement, obrigado pelas recomendações, ajudaram bastante.
Eu queria realmente saber qual o valor exato pra usar como tolerância; acho que vou ter que descobrir empiricamente.
This message was edited 1 time. Last update was at 13/11/2009 15:29:36
|
Tarso Nunes Aires
Blog - http://cabritin.wordpress.com/
Delicious - http://delicious.com/tnaires
Twitter - @tnaires
 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 13/11/2009 15:38:28
|
tnaires
GUJ Master
![[Avatar]](/images/avatar/5f6371c9126149517d9ba475def53139.png)
Membro desde: 22/12/2003 08:05:58
Mensagens: 1678
Localização: Porto Alegre/RS - Natal/RN
Offline
|
Olá clone_zealot, obrigado pelos comentários.
clone_zealot wrote:Isso é um trabalho de faculdade, correto?
Pois bem, existe necessidade de vc se preocupar com performance? Ainda mais que estamos falando de caixeiro-viajante, que é um problema complexo...
Não estou falando que foi ruim vc ter pensado nisso. Muito pelo contrário!!! É ótimo ver que vc se preocupa com esse tipo de coisa. Mostra que vc é/será um bom desenvolvedor, mas talvez o que realmente importa seja a lógica do algoritmo, e não esse tipo de coisa.
Estou te incentivando a manter o foco no problema, e não na solução. Se, para esse trabalho, o professor exigir que o algoritmo rode num tempo y, OK, você deve se preocupar com isso. Com contrário, se preocupe com o objetivo.
Preciso me preocupar com performance porque meu trabalho é justamente uma análise de desempenho de diferentes algoritmos de busca na resolução do problema do caixeiro viajante, entre eles simulated annealing. Não é um trabalho qualquer na verdade, trata-se da minha monografia. Além do mais, como já falei antes, terei instâncias do problema que poderão conter dezenas de milhares de cidades - o algoritmo genético, por exemplo, passa umas duas horas rodando - e usar BigDecimal pode influenciar. Queria justamente saber se alguém já implementou o simulated annealing alguma vez pra me responder se essa preocupação é relevante ou não.
clone_zealot wrote:E outra coisa: pq vc não transforma esses valores decimais em valores inteiros? Tipo, vc sabe qual o menor valor que será de entrada?
Digamos que seja 0,0001 grau. Bastaria vc multiplicar TODOS os valores de temperatura por 10.000 e vc só precisará trabalhar com inteiros. Dai vc não precisar se preocupar com a aritmética de ponto flutuante do Java.
Ótima sugestão. No entanto o uso de números de ponto flutuante é mais cômodo de fato pois há uma fórmula do algoritmo que utiliza a constante de Boltzmann, e trabalhar com cálculos inteiros usando essa constante vai render um trabalho extra que eu não quero ter. A performance é importante sim, mas não a esse ponto, creio.
|
Tarso Nunes Aires
Blog - http://cabritin.wordpress.com/
Delicious - http://delicious.com/tnaires
Twitter - @tnaires
 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/11/2009 13:12:11
|
entanglement
GUJ Hacker
Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline
|
Se você vai usar uma máquina como um Core 2 Duo ou um Phenom ou mesmo um Pentium antigão, usar aritmética de ponto flutuante é muito, muito mais rápido que usar BigDecimal, porque o próprio processador implementa a aritmética de ponto flutuante (ou via "coprocessador", ou via SSE2 ou SSE3).
Se não me engano, é mais rápido fazer uma multiplicação de ponto flutuante em vários desses processadores que fazer uma multiplicação inteira. Mas é questão de testar.
Usar BigDecimal ou BigInteger deve ser relegado a casos especiais.
|
|
|
 |
|
|
|
|