Commit dc809607 authored by Grégoire Grzeczkowicz's avatar Grégoire Grzeczkowicz
Browse files

Genetic alogorithm

parent 4ee87a0f
......@@ -58,5 +58,28 @@ def simulated_annealing(func, init, neighb, temp, again):
i += 1
return best_val, best_sol
# TODO add a population-based stochastic heuristic template.
def genetic(func, init, crossover, neighb, population_size, again):
"""Iterative randomized genetic heuristic template."""
P_sol = [init() for i in range(population_size)]
P_val = [func(sol) for sol in P_sol]
best_sol = P_sol[np.argmax(P_val)]
best_val = P_val[np.argmax(P_val)]
i = 1
while again(i, best_val, best_sol):
new_sol = []
for j in range(5*population_size):
e1,e2 = np.random.randint(0,population_size,2)
sol = neighb(crossover(P_sol[e1],P_sol[e2]))
new_sol.append(sol)
new_val = [func(sol) for sol in new_sol]
P_i = np.random.choice(range(len(new_sol)), size = population_size, replace = False, p=[v/np.sum(new_val) for v in new_val])
P_sol = [new_sol[i] for i in P_i]
P_val = [new_val[i] for i in P_i]
if P_val[np.argmax(P_val)] > best_val:
best_sol = P_sol[np.argmax(P_val)]
best_val = P_val[np.argmax(P_val)]
i += 1
return best_val, best_sol
......@@ -135,3 +135,25 @@ def neighb_square(sol, scale, domain_width):
# else pass
return new
########################################################################
# Crossover
########################################################################
def crossover(sol1, sol2):
x = []
y = []
sol = sol1 + sol2
for i in range(len(sol)):
for j in range(len(sol[i])):
if sol[i][j] >= 1:
y.append(i)
x.append(j)
v = np.random.randint(0, len(x), len(to_sensors(sol1)))
domain = np.zeros( (len(sol),len(sol[0])) )
for i in v:
domain[y[i]][x[i]] = 1
return domain
......@@ -118,3 +118,17 @@ def neighb_square(sol, scale, domain_width):
new = sol + (np.random.random(len(sol)) * side - side/2)
return new
########################################################################
# Crossover
########################################################################
def crossover(sol1, sol2):
sol = np.concatenate((sol1, sol2))
v = np.random.randint(0, len(sol) // 2, len(sol1) // 2)
r = []
for i in v:
r.append(sol[2*i])
r.append(sol[2*i+1])
return r
......@@ -32,7 +32,7 @@ if __name__=="__main__":
can.add_argument("-s", "--seed", metavar="VAL", default=None, type=int,
help="Random pseudo-generator seed (none for current epoch)")
solvers = ["num_greedy","bit_greedy","num_simulated_annealing","bit_simulated_annealing"]
solvers = ["num_greedy","bit_greedy","num_simulated_annealing","bit_simulated_annealing","num_genetic","bit_genetic"]
can.add_argument("-m", "--solver", metavar="NAME", choices=solvers, default="num_greedy",
help="Solver to use, among: "+", ".join(solvers))
......@@ -54,6 +54,9 @@ if __name__=="__main__":
can.add_argument("-o", "--output-file", metavar="NAME", default=None, type=str,
help="Output file where log are put")
can.add_argument("-p", "--population-size", metavar="NB", default=10, type=int,
help="Size of the population for genetic algorithms")
the = can.parse_args()
# Minimum checks.
......@@ -165,6 +168,42 @@ if __name__=="__main__":
)
sensors = bit.to_sensors(sol)
elif the.solver == "num_genetic":
val,sol = algo.genetic(
make.func(num.cover_sum,
domain_width = the.domain_width,
sensor_range = the.sensor_range,
dim = d * the.nb_sensors),
make.init(num.rand,
dim = d * the.nb_sensors,
scale = the.domain_width),
num.crossover,
make.neig(num.neighb_square,
scale = the.variation_scale,
domain_width = the.domain_width),
the.population_size,
iters
)
sensors = num.to_sensors(sol)
elif the.solver == "bit_genetic":
val,sol = algo.genetic(
make.func(bit.cover_sum,
domain_width = the.domain_width,
sensor_range = the.sensor_range,
dim = d * the.nb_sensors),
make.init(bit.unif,
domain_width = the.domain_width,
nb_sensors = the.nb_sensors),
bit.crossover,
make.neig(bit.neighb_square,
scale = the.variation_scale,
domain_width = the.domain_width),
the.population_size,
iters
)
sensors = bit.to_sensors(sol)
# Fancy output.
print("\n{} : {}".format(val,sensors))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment