||
import random, math
def annealing(init_state, eval_func, random_jump,accept_prob_func, t0,t1, total_steps ):
assert t0 > 0
assert t1 > 0
state = init_state
val = eval_func(state )
# temperature = t0
min_state = state
min_val = val
for i in range(total_steps):
temperature = t0 + (t1-t0 ) * i / total_steps
new_state = random_jump(state)
new_val = eval_func(new_state)
## if new val is smaller, you should accept it.
accept_prob = accept_prob_func(val, new_val, temperature)
if random.random() <= accept_prob :
#accept
state = new_state
val = new_val
if min_val > val:
min_val=val
min_state = state
return (state, val, min_state , min_val )
### here's a simple example for annealing
def rosenbrock(state ,a=1,b=100):
## typical testing func for optimization tasks
(x,y) = state
## try to find its minimum!
return (a-x)**2 + b * (y-x*x)**2
def random_within(ep):
return (random.random()* 2 -1) * ep
def vector_random_purtabation( state, ep=0.1 ):
#state is a vector
#change each coordiante by a random var within [-ep, ep]
return [x + random_within(ep) for x in state ]
def metropolis_acceptance(old_val, new_val, temperature):
# if new val is smaller, return 1+ for certain acceptance.
if new_val < old_val:
return 1
else:
badness = new_val-old_val ## pos
return math.exp(-badness/ temperature )
if __name__ == "__main__":
init_state = (random_within(5), random_within(5))
for _ in range(10):
(s,v,ss,vv) = annealing(init_state, rosenbrock, vector_random_purtabation,metropolis_acceptance,1,1,1000)
print(v,vv )
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-9-27 08:53
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社