forked from lilspikey/TSP
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsa.py
62 lines (48 loc) · 1.79 KB
/
sa.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
from optimise import ObjectiveFunction
import random
import math
import logging
def P(prev_score, next_score, temperature):
if next_score > prev_score:
return 1.0
else:
return math.exp(-abs(next_score - prev_score) / temperature)
def kirkpatrick_cooling(start_temp, alpha):
T = start_temp
while True:
yield T
T *= alpha
def anneal(init_function, move_operator,
objective_function, max_evaluations, start_temp, alpha):
# wrap the objective function (so we record the best)
objective_function = ObjectiveFunction(objective_function)
current = init_function()
current_score = objective_function(current)
num_evaluations = 1
cooling_schedule = kirkpatrick_cooling(start_temp, alpha)
logging.info('anneal started: score=%f', current_score)
for temperature in cooling_schedule:
done = False
# examine moves around our current position
for next in move_operator(current):
if num_evaluations >= max_evaluations:
done = True
break
next_score = objective_function(next)
num_evaluations += 1
# probablistically accept this solution
# always accepting better solutions
p = P(current_score, next_score, temperature)
if random.random() < p:
current=next
current_score=next_score
break
# see if completely finished
if done:
break
best_score = objective_function.best_score
best = objective_function.best
logging.info('final temperature: %f', temperature)
logging.info('anneal finished: num_evaluations=%d, best_score=%f',
num_evaluations, best_score)
return num_evaluations, best_score, best