max / min / smallest float value on Python 2.5

duncan smith buzzard at urubu.freeserve.co.uk
Sun Feb 7 21:45:59 CET 2010


Steven D'Aprano wrote:
> On Sun, 07 Feb 2010 03:02:05 +0000, duncan smith wrote:
> 
>> The precise issue is that I'm supplying a default value of
>> 2.2250738585072014e-308 for a parameter (finishing temperature for a
>> simulated annealing algorithm) in an application.  I develop on
>> Ubuntu64, but (I am told) it's too small a value when run on a Win32
>> server.  I assume it's being interpreted as zero and raising an
>> exception.  Thanks.
> 
> I'm trying to think of what sort of experiment would be able to measure 
> temperatures accurate to less than 3e-308 Kelvin, and my brain boiled.
> 
> Surely 1e-100 would be close enough to zero as to make no practical 
> difference? Or even 1e-30? Whatever you're simulating surely isn't going 
> to require 300+ decimal points of accuracy.
> 
> I must admit I'm not really familiar with simulated annealing, so I could 
> be completely out of line, but my copy of "Numerical Recipes ..." by 
> Press et al has an example, and they take the temperature down to about 
> 1e-6 before halting. Even a trillion times lower that that is 1e-15.
> 
> 

It depends on the optimisation problem, but I suppose the fitness 
functions could be tweaked.  I could paste the actual code if anyone's 
interested, but the following pseudo-python gives the idea.  For an 
exponential cooling schedule the temperatures are generated as below. 
The lower the final temperature the greater the number of iterations, 
and the longer the algorithm spends searching locally for an optimal 
solution (having already searched more widely for areas of high fitness 
at higher temperatures).  The probability of moving to a less fit 
solution is given by exp(dF/temp) where dF is a (negative) change in 
fitness and temp is the current temperature.  So I could scale the 
fitness function to cope with higher finishing temperatures.

I'm going to have to think about the point raised by Steve (Holden).

I also think I can probably improve on raising StopIteration if 
exp(dF/temp) overflows by yielding False instead (although if it does 
overflow it probably indicates a poor choice of cooling schedule for the 
given problem).  Stuff to think about.  Cheers.

Duncan


import random
import math

def temps(start, final, mult):
     t = start
     while t > final:
         yield t
         t *= mult

def sim_anneal(permuter, start, final, mult):
     rand = random.random
     exp = math.exp
     for temp in temps(start, final, mult):
         dF = permuter.next()
         if dF >= 0:
             yield True
         else:
             try:
                 yield rand() < exp(dF / temp)
             except OverflowError:
                 raise StopIteration

class Permuter(object):
     def __init__(self, obj):
         self.obj = obj
	self.proposed = None

     def run(self, start, final, mult):
         for decision in sim_anneal(self, start, final, mult):
             if decision:
                 # commit proposed change to self.obj

     def next():
         # propose a change to self.obj
         # calculate and return the change in fitness
         self.proposed = proposed
         return dF



More information about the Python-list mailing list