GA implementation
- ADD crossover - ADD mutation - ADD next_gen preparation - Project completed (with errors) with Michał Malinowski
This commit is contained in:
parent
7a14078390
commit
288d3cf30a
@ -1,5 +1,3 @@
|
||||
import random
|
||||
|
||||
import keyboard as keyboard
|
||||
|
||||
import field as F
|
||||
@ -11,7 +9,7 @@ from src import mapschema as maps
|
||||
def genetic_algorithm_setup(field):
|
||||
population_units = ["", "w", "p", "s"]
|
||||
|
||||
# new_population to be
|
||||
# TODO REPREZENTACJA OSOBNIKA - MACIERZ ROZKłADU PLONÓW
|
||||
population_text = []
|
||||
population_text_single = []
|
||||
|
||||
@ -55,7 +53,9 @@ def genetic_algorithm_setup(field):
|
||||
|
||||
# population Fitness
|
||||
fitness = []
|
||||
|
||||
for i in range(0, population_size):
|
||||
print(len(population_text), i)
|
||||
fitness.append((i, population_fitness(population_text[i], field, population_size)))
|
||||
|
||||
print("Fitness")
|
||||
@ -73,33 +73,52 @@ def genetic_algorithm_setup(field):
|
||||
# Selecting the best parents in the population for mating.
|
||||
parents = [population_text[i[0]] for i in best]
|
||||
print("Parents")
|
||||
print(parents)
|
||||
for i in range(0, len(parents)):
|
||||
print('\n'.join([''.join(['{:4}'.format(item) for item in row])
|
||||
for row in parents[i]]))
|
||||
print("")
|
||||
|
||||
# Generating next generation using crossover.
|
||||
offspring_x = random.randint(1, D.GSIZE - 2)
|
||||
offspring_y = random.randint(1, D.GSIZE - 2)
|
||||
|
||||
offspring_crossover = crossover(parents, offspring_size=(pop_size[0] - parents.shape[0], num_weights))
|
||||
offspring_crossover = crossover(parents)
|
||||
print("Crossover")
|
||||
print(offspring_crossover)
|
||||
for i in range(0, len(offspring_crossover)):
|
||||
print('\n'.join([''.join(['{:4}'.format(item) for item in row])
|
||||
for row in offspring_crossover[i]]))
|
||||
print("")
|
||||
|
||||
# Adding some variations to the offspring using mutation.
|
||||
offspring_mutation = mutation(offspring_crossover, num_mutations=2)
|
||||
offspring_mutation = mutation(population_units, offspring_crossover, population_size - num_parents,
|
||||
num_mutations=10)
|
||||
print("Mutation")
|
||||
print(offspring_mutation)
|
||||
for i in range(0, len(offspring_mutation)):
|
||||
print('\n'.join([''.join(['{:4}'.format(item) for item in row])
|
||||
for row in offspring_mutation[i]]))
|
||||
print("")
|
||||
|
||||
# Creating the new population based on the parents and offspring.
|
||||
new_population[0:parents.shape[0], :] = parents
|
||||
new_population[parents.shape[0]:, :] = offspring_mutation
|
||||
# Creating next generation
|
||||
population_text = []
|
||||
for k in range(0, len(parents)):
|
||||
population_text.append(parents)
|
||||
for k in range(0, len(offspring_mutation)):
|
||||
population_text.append(offspring_mutation[k])
|
||||
|
||||
# Getting the best solution after iterating finishing all generations.
|
||||
# At first, the fitness is calculated for each solution in the final generation.
|
||||
fitness = cal_pop_fitness(new_population)
|
||||
# Then return the index of that solution corresponding to the best fitness.
|
||||
best_match_idx = numpy.where(fitness == numpy.max(fitness))
|
||||
# final Fitness
|
||||
fitness = []
|
||||
for i in range(0, population_size):
|
||||
fitness.append((i, population_fitness(population_text[i], field, population_size)))
|
||||
|
||||
print("Best solution : ", new_population[best_match_idx, :])
|
||||
print("Best solution fitness : ", fitness[best_match_idx])
|
||||
print("Final Fitness")
|
||||
print(fitness)
|
||||
|
||||
best = sorted(fitness, key=lambda tup: tup[1])[0:num_parents]
|
||||
|
||||
print("Best solution : ", )
|
||||
for i in range(0, D.GSIZE):
|
||||
print(population_text[best[0][0]][i])
|
||||
print("Best solution fitness : ", best[0][1])
|
||||
|
||||
pretty_printer(best_outputs)
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
import copy
|
||||
import random
|
||||
|
||||
import matplotlib
|
||||
import numpy
|
||||
|
||||
@ -25,6 +28,7 @@ def local_fitness(field, x, y, plants_case):
|
||||
plant_value = 1
|
||||
|
||||
neighbour_bonus = 1
|
||||
print(x, y)
|
||||
if x - 1 >= 0:
|
||||
if plants_case[x][y] == plants_case[x - 1][y]:
|
||||
neighbour_bonus += 1
|
||||
@ -64,36 +68,39 @@ def population_fitness(population_text, field, population_size):
|
||||
return fitness
|
||||
|
||||
|
||||
def crossover(parents, offspring_size):
|
||||
current_parrent = parents[0]
|
||||
new_part = []
|
||||
|
||||
offspring = numpy.empty(offspring_size)
|
||||
# The point at which crossover takes place between two parents. Usually, it is at the center.
|
||||
crossover_point = numpy.uint8(offspring_size[1] / 2)
|
||||
|
||||
for k in range(offspring_size[0]):
|
||||
# Index of the first parent to mate.
|
||||
parent1_idx = k % parents.shape[0]
|
||||
# Index of the second parent to mate.
|
||||
parent2_idx = (k + 1) % parents.shape[0]
|
||||
# The new offspring will have its first half of its genes taken from the first parent.
|
||||
offspring[k, 0:crossover_point] = parents[parent1_idx, 0:crossover_point]
|
||||
# The new offspring will have its second half of its genes taken from the second parent.
|
||||
offspring[k, crossover_point:] = parents[parent2_idx, crossover_point:]
|
||||
return offspring
|
||||
def crossover(parents):
|
||||
ret = []
|
||||
for i in range(0, len(parents)):
|
||||
child = copy.deepcopy(parents[i])
|
||||
# Vertical randomization
|
||||
width = random.randint(1, D.GSIZE / len(parents)) # width of stripes
|
||||
indexes_parents = numpy.random.permutation(range(0, len(parents))) # sorting of stripes
|
||||
beginning = random.randint(0, len(parents[0]) - width * len(parents)) # point we start putting the stripes from
|
||||
for x in indexes_parents:
|
||||
child[beginning:beginning + width] = parents[x][beginning:beginning + width]
|
||||
beginning += width
|
||||
ret.append(child)
|
||||
return ret
|
||||
|
||||
|
||||
def mutation(offspring_crossover, num_mutations=1):
|
||||
mutations_counter = numpy.uint8(offspring_crossover.shape[1] / num_mutations)
|
||||
# Mutation changes a number of genes as defined by the num_mutations argument. The changes are random.
|
||||
for idx in range(offspring_crossover.shape[0]):
|
||||
gene_idx = mutations_counter - 1
|
||||
for mutation_num in range(num_mutations):
|
||||
# The random value to be added to the gene.
|
||||
random_value = numpy.random.uniform(-1.0, 1.0, 1)
|
||||
offspring_crossover[idx, gene_idx] = offspring_crossover[idx, gene_idx] + random_value
|
||||
gene_idx = gene_idx + mutations_counter
|
||||
def mutation(population_units, offspring_crossover, num_mutants, num_mutations=10):
|
||||
for case in range(0, len(offspring_crossover)):
|
||||
for mutation in range(0, num_mutations):
|
||||
mutation_x = random.randint(0, D.GSIZE - 1)
|
||||
mutation_y = random.randint(0, D.GSIZE - 1)
|
||||
mutation_value = random.choice(population_units)
|
||||
offspring_crossover[case][mutation_x][mutation_y] = mutation_value
|
||||
num_mutants -= 1
|
||||
|
||||
while num_mutants > 0:
|
||||
case = random.randint(0, len(offspring_crossover))
|
||||
for mutation in range(0, num_mutations):
|
||||
mutation_x = random.randint(0, D.GSIZE - 1)
|
||||
mutation_y = random.randint(0, D.GSIZE - 1)
|
||||
mutation_value = random.choice(population_units)
|
||||
offspring_crossover[case][mutation_x][mutation_y] = mutation_value
|
||||
num_mutants -= 1
|
||||
|
||||
return offspring_crossover
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user