-
Notifications
You must be signed in to change notification settings - Fork 1
/
simulatedAnnealingFinal.py
158 lines (127 loc) · 4.16 KB
/
simulatedAnnealingFinal.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import matplotlib.pyplot as plt
import random
import math
import numpy as np
import time
INF = 10000
alpha = 0.999
threshold = 0.01
# we want to initialize the structure
# i.e. place the k-elements on the N X N grid
def initialize(k, N, grid):
for element in xrange(1,k+1):
assigned = False
while(not assigned):
i = np.random.randint(N)
j = np.random.randint(N)
if(grid[i,j]==0):
grid[i,j] = element
assigned = True
return grid
# Suppose you are in any state say S, then you can go to
# some other state S'
def findNeighbourState(N, k, grid):
# We will follow these two protocols, each 50% of time
# 1. swap positions of any two elements
# 2. Move any element to a new position in the grid
tempGrid = np.array(grid)
if(np.random.random()<0.5):
element1 = np.random.randint(1, k+1)
element2 = np.random.randint(1, k+1)
# to ensure element2 != element1
while(element2==element1):
element2 = np.random.randint(1, k+1)
(x1,y1) = zip(*np.where(tempGrid == element1))[0]
(x2,y2) = zip(*np.where(tempGrid == element2))[0]
tempGrid[x1, y1] = element2
tempGrid[x2, y2] = element1
else:
element1 = np.random.randint(1, k+1)
(x1,y1) = zip(*np.where(tempGrid == element1))[0]
# find an empty place
temp = zip(*np.where(tempGrid == 0))
(x2,y2) = temp[np.random.randint(len(temp))]
tempGrid[x1, y1] = 0
tempGrid[x2, y2] = element1
return tempGrid
# This will return the updated temperature
# according to some annealing schedule
def updateTemp(T):
return alpha*T
# This function finds the total wirelength
def cost(k, grid, connections):
distance = 0
for element in xrange(1,k+1):
(x1,y1) = zip(*np.where(grid == element))[0]
for nextElement in range(element+1,k+1):
if(connections[element,nextElement]):
(x2,y2) = zip(*np.where(grid == nextElement))[0]
distance += np.absolute(x2-x1) + np.absolute(y2-y1)
return distance
def annealing(N, k, grid, connections):
T = INF
# We initialize the grid
grid = initialize(k, N, grid)
minCost = cost(k, grid, connections)
print "Initial Cost",minCost
print "Initial Grid"
print grid
printgrid(grid)
tic = time.clock()
# No. of interation at each temperature
# No. of temperature points to try
while(T > threshold):
tempGrid = findNeighbourState(N, k, grid)
tempCost = cost(k, tempGrid, connections)
delta = tempCost - minCost
if (delta<0):
grid = tempGrid
minCost = tempCost
else:
p = np.exp(-delta / T)
if(np.random.random()<p):
grid = tempGrid
minCost = tempCost
T = updateTemp(T)
return grid,minCost, tic
def printgrid(grid):
plt.imshow(grid,interpolation='None', aspect = "auto")
for (j,i),label in np.ndenumerate(grid):
plt.text(i,j,label,ha='center',va='center')
plt.show()
def create(k) :
# Assuming that each element can have two input and one output.
# Initially we only know who is connected with whom. We use 2-d
# array 1 will represent there is connection between i and j,
# 0 otherwise
#filling the values in only upper triangular matrix
connections = np.zeros([k+1,k+1])
ii = 0
while ii < k+1:
i = int(random.randint(1,k))
j = int(random.randint(1,k))
if (i > j )& (connections[j,i] ==0):
connections[j,i] = 1
ii = ii+1
print (j,i)
if (i < j) & (connections[i,j] ==0):
connections[i,j] = 1
ii = ii+1
print (i,j)
return connections
def mainrun(N,k):
# For simplicty, assume that the element to be paced is point sized.
# And we have to place these k-point sized element on N X N grid.
#N = 10
#k = 12
# We will store the positions of the elements in the N X N grid
grid = np.zeros([N,N])
connections = create(k)
finalGrid,cost,tic = annealing(N, k, grid, connections)
toc = time.clock()
tim = toc - tic
print "time taken ", tim
print "Final Cost", cost
print "Final Grid"
print finalGrid
printgrid(finalGrid)