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 keyboard as keyboard
|
||||||
|
|
||||||
import field as F
|
import field as F
|
||||||
@ -11,7 +9,7 @@ from src import mapschema as maps
|
|||||||
def genetic_algorithm_setup(field):
|
def genetic_algorithm_setup(field):
|
||||||
population_units = ["", "w", "p", "s"]
|
population_units = ["", "w", "p", "s"]
|
||||||
|
|
||||||
# new_population to be
|
# TODO REPREZENTACJA OSOBNIKA - MACIERZ ROZKłADU PLONÓW
|
||||||
population_text = []
|
population_text = []
|
||||||
population_text_single = []
|
population_text_single = []
|
||||||
|
|
||||||
@ -55,7 +53,9 @@ def genetic_algorithm_setup(field):
|
|||||||
|
|
||||||
# population Fitness
|
# population Fitness
|
||||||
fitness = []
|
fitness = []
|
||||||
|
|
||||||
for i in range(0, population_size):
|
for i in range(0, population_size):
|
||||||
|
print(len(population_text), i)
|
||||||
fitness.append((i, population_fitness(population_text[i], field, population_size)))
|
fitness.append((i, population_fitness(population_text[i], field, population_size)))
|
||||||
|
|
||||||
print("Fitness")
|
print("Fitness")
|
||||||
@ -73,33 +73,52 @@ def genetic_algorithm_setup(field):
|
|||||||
# Selecting the best parents in the population for mating.
|
# Selecting the best parents in the population for mating.
|
||||||
parents = [population_text[i[0]] for i in best]
|
parents = [population_text[i[0]] for i in best]
|
||||||
print("Parents")
|
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.
|
# Generating next generation using crossover.
|
||||||
offspring_x = random.randint(1, D.GSIZE - 2)
|
offspring_x = random.randint(1, D.GSIZE - 2)
|
||||||
offspring_y = 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("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.
|
# 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("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.
|
# Creating next generation
|
||||||
new_population[0:parents.shape[0], :] = parents
|
population_text = []
|
||||||
new_population[parents.shape[0]:, :] = offspring_mutation
|
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.
|
# final Fitness
|
||||||
# At first, the fitness is calculated for each solution in the final generation.
|
fitness = []
|
||||||
fitness = cal_pop_fitness(new_population)
|
for i in range(0, population_size):
|
||||||
# Then return the index of that solution corresponding to the best fitness.
|
fitness.append((i, population_fitness(population_text[i], field, population_size)))
|
||||||
best_match_idx = numpy.where(fitness == numpy.max(fitness))
|
|
||||||
|
|
||||||
print("Best solution : ", new_population[best_match_idx, :])
|
print("Final Fitness")
|
||||||
print("Best solution fitness : ", fitness[best_match_idx])
|
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)
|
pretty_printer(best_outputs)
|
||||||
|
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
import copy
|
||||||
|
import random
|
||||||
|
|
||||||
import matplotlib
|
import matplotlib
|
||||||
import numpy
|
import numpy
|
||||||
|
|
||||||
@ -25,6 +28,7 @@ def local_fitness(field, x, y, plants_case):
|
|||||||
plant_value = 1
|
plant_value = 1
|
||||||
|
|
||||||
neighbour_bonus = 1
|
neighbour_bonus = 1
|
||||||
|
print(x, y)
|
||||||
if x - 1 >= 0:
|
if x - 1 >= 0:
|
||||||
if plants_case[x][y] == plants_case[x - 1][y]:
|
if plants_case[x][y] == plants_case[x - 1][y]:
|
||||||
neighbour_bonus += 1
|
neighbour_bonus += 1
|
||||||
@ -64,36 +68,39 @@ def population_fitness(population_text, field, population_size):
|
|||||||
return fitness
|
return fitness
|
||||||
|
|
||||||
|
|
||||||
def crossover(parents, offspring_size):
|
def crossover(parents):
|
||||||
current_parrent = parents[0]
|
ret = []
|
||||||
new_part = []
|
for i in range(0, len(parents)):
|
||||||
|
child = copy.deepcopy(parents[i])
|
||||||
offspring = numpy.empty(offspring_size)
|
# Vertical randomization
|
||||||
# The point at which crossover takes place between two parents. Usually, it is at the center.
|
width = random.randint(1, D.GSIZE / len(parents)) # width of stripes
|
||||||
crossover_point = numpy.uint8(offspring_size[1] / 2)
|
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 k in range(offspring_size[0]):
|
for x in indexes_parents:
|
||||||
# Index of the first parent to mate.
|
child[beginning:beginning + width] = parents[x][beginning:beginning + width]
|
||||||
parent1_idx = k % parents.shape[0]
|
beginning += width
|
||||||
# Index of the second parent to mate.
|
ret.append(child)
|
||||||
parent2_idx = (k + 1) % parents.shape[0]
|
return ret
|
||||||
# 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 mutation(offspring_crossover, num_mutations=1):
|
def mutation(population_units, offspring_crossover, num_mutants, num_mutations=10):
|
||||||
mutations_counter = numpy.uint8(offspring_crossover.shape[1] / num_mutations)
|
for case in range(0, len(offspring_crossover)):
|
||||||
# Mutation changes a number of genes as defined by the num_mutations argument. The changes are random.
|
for mutation in range(0, num_mutations):
|
||||||
for idx in range(offspring_crossover.shape[0]):
|
mutation_x = random.randint(0, D.GSIZE - 1)
|
||||||
gene_idx = mutations_counter - 1
|
mutation_y = random.randint(0, D.GSIZE - 1)
|
||||||
for mutation_num in range(num_mutations):
|
mutation_value = random.choice(population_units)
|
||||||
# The random value to be added to the gene.
|
offspring_crossover[case][mutation_x][mutation_y] = mutation_value
|
||||||
random_value = numpy.random.uniform(-1.0, 1.0, 1)
|
num_mutants -= 1
|
||||||
offspring_crossover[idx, gene_idx] = offspring_crossover[idx, gene_idx] + random_value
|
|
||||||
gene_idx = gene_idx + mutations_counter
|
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
|
return offspring_crossover
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user