Commits (2)
......@@ -38,20 +38,23 @@ def greedy(func, init, neighb, again):
def simulated_annealing(func, init, neighb, temp, again):
"""Iterative randomized simulated-annealing template."""
best_sol = init()
best_val = func(best_sol)
val,sol = best_val,best_sol
old_sol = init()
old_val = func(old_sol)
best_val,best_sol = old_val,old_sol
i = 1
while again(i, best_val, best_sol):
sol = neighb(best_sol)
val = func(sol)
while again(i, old_val, old_sol):
new_sol = neighb(old_sol)
new_val = func(new_sol)
# Use >= and not >, so as to avoid random walk on plateus.
if val >= best_val:
best_val = val
best_sol = sol
elif np.random.random() < np.exp(-(best_val-val)/temp(i, best_val, best_sol)):
best_val = val
best_sol = sol
if new_val >= old_val:
old_val = new_val
old_sol = new_sol
elif np.random.random() < np.exp(-(old_val-new_val)/temp(i, old_val, old_sol)):
old_val = new_val
old_sol = new_sol
if new_val >= best_val:
best_val = new_val
best_sol = new_sol
i += 1
return best_val, best_sol
......
......@@ -50,6 +50,63 @@ def rand(domain_width, nb_sensors):
return domain
def unif(domain_width, nb_sensors):
""""Draw a uniform domain containing nb_sensors ones."""
domain = np.zeros( (domain_width,domain_width) )
c = np.sqrt(2*nb_sensors/np.sqrt(3))
elem = [
np.abs(np.trunc(c) * np.trunc(np.sqrt(3)*c) / 2- nb_sensors),
np.abs(np.trunc(c) * np.ceil(np.sqrt(3)*c) / 2 - nb_sensors),
np.abs(np.ceil(c) * np.trunc(np.sqrt(3)*c) / 2 - nb_sensors),
np.abs(np.ceil(c) * np.ceil(np.sqrt(3)*c) / 2 - nb_sensors)
]
if (np.argmin(elem) == 0):
c = np.trunc(c)
l = np.trunc(np.sqrt(3)*c)
elif (np.argmin(elem) == 1):
c = np.trunc(c)
l = np.ceil(np.sqrt(3)*c)
elif (np.argmin(elem) == 2):
c = np.ceil(c)
l = np.trunc(np.sqrt(3)*c)
elif (np.argmin(elem) == 3):
c = np.ceil(c)
l = np.ceil(np.sqrt(3)*c)
n = 0
for i in range(int(l)):
for j in range(int(c)):
if n < nb_sensors:
if (i % 2 == 0 and j % 2 == 0) or (i % 2 == 1 and j % 2 == 1):
domain[int((i+0.5)*domain_width/l)][int((j+0.5)*domain_width/c)] = 1
n += 1
if n < nb_sensors:
for i in range(int(l)):
if n < nb_sensors:
if (i % 2 == 1 and c % 2 == 0) or (i % 2 == 0 and c % 2 == 1):
domain[int((i+0.5)*domain_width/l)][int((c-0.5)*domain_width/c)] = 1
n += 1
if n < nb_sensors:
for j in range(int(c)):
if n < nb_sensors:
if (l % 2 == 0 and j % 2 == 1) or (l % 2 == 1 and j % 2 == 0):
domain[int((l-0.5)*domain_width/l)][int((j+0.5)*domain_width/c)] = 1
n += 1
while n < nb_sensors :
i,j = np.random.randint(0, domain_width, 2)
if domain[i][j] == 0:
domain[i][j] = 1
n += 1
return domain
########################################################################
# Neighborhood
########################################################################
......
......@@ -43,6 +43,61 @@ def rand(dim, scale):
"""Draw a random vector in [0,scale]**dim."""
return np.random.random(dim) * scale
def unif(dim, scale):
""""Draw a uniform domain containing nb_sensors ones."""
nb_sensors = dim/2
domain_width = scale
sensors = []
c = np.sqrt(2*nb_sensors/np.sqrt(3))
elem = [
np.abs(np.trunc(c) * np.trunc(np.sqrt(3)*c) / 2- nb_sensors),
np.abs(np.trunc(c) * np.ceil(np.sqrt(3)*c) / 2 - nb_sensors),
np.abs(np.ceil(c) * np.trunc(np.sqrt(3)*c) / 2 - nb_sensors),
np.abs(np.ceil(c) * np.ceil(np.sqrt(3)*c) / 2 - nb_sensors)
]
if (np.argmin(elem) == 0):
c = np.trunc(c)
l = np.trunc(np.sqrt(3)*c)
elif (np.argmin(elem) == 1):
c = np.trunc(c)
l = np.ceil(np.sqrt(3)*c)
elif (np.argmin(elem) == 2):
c = np.ceil(c)
l = np.trunc(np.sqrt(3)*c)
elif (np.argmin(elem) == 3):
c = np.ceil(c)
l = np.ceil(np.sqrt(3)*c)
for i in range(int(l)):
for j in range(int(c)):
if len(sensors) < dim:
if (i % 2 == 0 and j % 2 == 0) or (i % 2 == 1 and j % 2 == 1):
sensors.append((i+0.5)*domain_width/l)
sensors.append((j+0.5)*domain_width/c)
if len(sensors) < dim:
for i in range(int(l)):
if len(sensors) < dim:
if (i % 2 == 1 and c % 2 == 0) or (i % 2 == 0 and c % 2 == 1):
sensors.append((i+0.5)*domain_width/l)
sensors.append((c-0.5)*domain_width/c)
if len(sensors) < dim:
for j in range(int(c)):
if len(sensors) < dim:
if (l % 2 == 0 and j % 2 == 1) or (l % 2 == 1 and j % 2 == 0):
sensors.append((l-0.5)*domain_width/l)
sensors.append((j+0.5)*domain_width/c)
if len(sensors) < dim:
sensors += np.random.random(dim-len(sensors)) * scale
return sensors
########################################################################
# Neighborhood
......
......@@ -105,7 +105,7 @@ if __name__=="__main__":
domain_width = the.domain_width,
sensor_range = the.sensor_range,
dim = d * the.nb_sensors),
make.init(num.rand,
make.init(num.unif,
dim = d * the.nb_sensors,
scale = the.domain_width),
make.neig(num.neighb_square,
......@@ -121,7 +121,7 @@ if __name__=="__main__":
domain_width = the.domain_width,
sensor_range = the.sensor_range,
dim = d * the.nb_sensors),
make.init(bit.rand,
make.init(bit.unif,
domain_width = the.domain_width,
nb_sensors = the.nb_sensors),
make.neig(bit.neighb_square,
......@@ -137,7 +137,7 @@ if __name__=="__main__":
domain_width = the.domain_width,
sensor_range = the.sensor_range,
dim = d * the.nb_sensors),
make.init(num.rand,
make.init(num.unif,
dim = d * the.nb_sensors,
scale = the.domain_width),
make.neig(num.neighb_square,
......@@ -154,7 +154,7 @@ if __name__=="__main__":
domain_width = the.domain_width,
sensor_range = the.sensor_range,
dim = d * the.nb_sensors),
make.init(bit.rand,
make.init(bit.unif,
domain_width = the.domain_width,
nb_sensors = the.nb_sensors),
make.neig(bit.neighb_square,
......