-
Notifications
You must be signed in to change notification settings - Fork 0
/
simulated-annealing-tsp.py
68 lines (46 loc) · 1.26 KB
/
simulated-annealing-tsp.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
63
64
65
66
67
68
from math import sqrt, e
from random import random, shuffle
raw_G = '''
A
B
C D E
F
G
H
I
J
'''
G = {}
for i, line in enumerate(raw_G.split('\n')):
for j, c in enumerate(line):
if c != ' ':
G[c] = (j,i)
def dist(a,b):
dx = b[0] - a[0]
dy = b[1] - a[1]
return sqrt(dx**2 + dy**2)
def cost(pos):
return sum(dist(a,b) for a,b in zip(pos[:-1], pos[1:]))
def pos(sol):
return [G[x] for x in sol]
def P(t, c):
return e**(-c / t) if c > 0 else 1
def accept(t, dc):
return random() <= P(t,dc)
def swaps(sol):
for i in range(len(sol)):
for j in range(i+1, len(sol)):
sol_copy = [x for x in sol]
sol_copy[i], sol_copy[j] = sol_copy[j], sol_copy[i]
yield sol_copy
def dc(A, B):
return cost(pos(B)) - cost(pos(A))
if __name__ == '__main__':
sol = [key for key in G.keys()]
print('Initial:', sol, cost(pos(sol)))
for t in range(1000, 0, -1):
for swap in swaps(sol):
if accept(t, dc(sol, swap)):
sol = swap
continue
print('After SA:', sol, cost(pos(sol)))