2021-06-20 18:02:11 +02:00
|
|
|
import keyboard as keyboard
|
|
|
|
|
|
|
|
import field as F
|
|
|
|
from ga_methods import *
|
|
|
|
from src import mapschema as maps
|
2021-06-20 13:24:12 +02:00
|
|
|
|
|
|
|
|
|
|
|
# Genetic Algorithm
|
2021-06-20 18:02:11 +02:00
|
|
|
def genetic_algorithm_setup(field):
|
|
|
|
population_units = ["", "w", "p", "s"]
|
2021-06-20 13:24:12 +02:00
|
|
|
|
2021-06-21 03:24:07 +02:00
|
|
|
# TODO REPREZENTACJA OSOBNIKA - MACIERZ ROZKłADU PLONÓW
|
2021-06-20 18:02:11 +02:00
|
|
|
population_text = []
|
2021-06-20 23:43:57 +02:00
|
|
|
population_text_single = []
|
|
|
|
|
2021-06-21 00:38:56 +02:00
|
|
|
population_size = 10
|
2021-06-20 13:24:12 +02:00
|
|
|
|
2021-06-20 18:02:11 +02:00
|
|
|
# Populate the population_text array
|
2021-06-20 23:43:57 +02:00
|
|
|
for k in range(population_size):
|
|
|
|
population_text_single = []
|
|
|
|
for row in range(D.GSIZE):
|
|
|
|
population_text_single.append([])
|
|
|
|
for column in range(D.GSIZE):
|
|
|
|
population_text_single[row].append(random.choice(population_units))
|
|
|
|
population_text.append(population_text_single)
|
2021-06-20 13:24:12 +02:00
|
|
|
|
|
|
|
"""
|
|
|
|
Genetic algorithm parameters:
|
|
|
|
Mating pool size
|
|
|
|
Population size
|
|
|
|
"""
|
2021-06-20 18:02:11 +02:00
|
|
|
|
|
|
|
# units per population in generation
|
2021-06-20 13:24:12 +02:00
|
|
|
best_outputs = []
|
2021-06-20 18:02:11 +02:00
|
|
|
num_generations = 10
|
2021-06-21 04:04:26 +02:00
|
|
|
num_parents = 4
|
2021-06-20 18:02:11 +02:00
|
|
|
|
2021-06-21 00:38:56 +02:00
|
|
|
# iterative var
|
2021-06-20 18:02:11 +02:00
|
|
|
generation = 0
|
2021-06-21 04:04:26 +02:00
|
|
|
stop = 0
|
2021-06-21 03:38:21 +02:00
|
|
|
# TODO WARUNEK STOPU
|
|
|
|
while generation < num_generations and stop < 3:
|
2021-06-20 18:02:11 +02:00
|
|
|
if keyboard.is_pressed('space'):
|
|
|
|
generation += 1
|
|
|
|
|
|
|
|
print("Generation : ", generation)
|
|
|
|
# Measuring the fitness of each chromosome in the population.
|
|
|
|
|
2021-06-20 23:43:57 +02:00
|
|
|
# population Fitness
|
2021-06-21 00:38:56 +02:00
|
|
|
fitness = []
|
2021-06-21 03:24:07 +02:00
|
|
|
|
2021-06-21 00:38:56 +02:00
|
|
|
for i in range(0, population_size):
|
|
|
|
fitness.append((i, population_fitness(population_text[i], field, population_size)))
|
2021-06-20 23:43:57 +02:00
|
|
|
|
2021-06-20 18:02:11 +02:00
|
|
|
print("Fitness")
|
|
|
|
print(fitness)
|
|
|
|
|
2021-06-21 04:43:13 +02:00
|
|
|
best = sorted(fitness, key=lambda tup: tup[1], reverse=True)[0:num_parents]
|
2021-06-21 00:38:56 +02:00
|
|
|
|
|
|
|
# Leaderboard only
|
|
|
|
best_outputs.append(best[0][1])
|
|
|
|
|
2021-06-20 18:02:11 +02:00
|
|
|
# The best result in the current iteration.
|
2021-06-21 00:38:56 +02:00
|
|
|
print("Best result : ", best[0])
|
2021-06-20 18:02:11 +02:00
|
|
|
|
2021-06-21 00:38:56 +02:00
|
|
|
# TODO METODA WYBORU OSOBNIKA - RANKING
|
2021-06-20 18:02:11 +02:00
|
|
|
# Selecting the best parents in the population for mating.
|
2021-06-21 04:43:13 +02:00
|
|
|
print(best)
|
2021-06-21 00:38:56 +02:00
|
|
|
parents = [population_text[i[0]] for i in best]
|
2021-06-21 04:43:13 +02:00
|
|
|
parents_copy = copy.deepcopy(parents)
|
2021-06-20 18:02:11 +02:00
|
|
|
print("Parents")
|
2021-06-21 04:43:13 +02:00
|
|
|
# for i in range(0, len(parents)):
|
|
|
|
# print('\n'.join([''.join(['{:4}'.format(item) for item in row])
|
|
|
|
# for row in parents[i]]))
|
|
|
|
# print("")
|
2021-06-20 18:02:11 +02:00
|
|
|
|
|
|
|
# Generating next generation using crossover.
|
2021-06-21 01:56:55 +02:00
|
|
|
offspring_x = random.randint(1, D.GSIZE - 2)
|
|
|
|
offspring_y = random.randint(1, D.GSIZE - 2)
|
|
|
|
|
2021-06-21 03:38:21 +02:00
|
|
|
# TODO OPERATOR KRZYŻOWANIA
|
2021-06-21 03:24:07 +02:00
|
|
|
offspring_crossover = crossover(parents)
|
2021-06-20 18:02:11 +02:00
|
|
|
print("Crossover")
|
2021-06-21 04:43:13 +02:00
|
|
|
# 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("")
|
2021-06-20 18:02:11 +02:00
|
|
|
|
2021-06-21 03:38:21 +02:00
|
|
|
# TODO OPERATOR MUTACJI
|
2021-06-21 03:24:07 +02:00
|
|
|
offspring_mutation = mutation(population_units, offspring_crossover, population_size - num_parents,
|
|
|
|
num_mutations=10)
|
2021-06-20 18:02:11 +02:00
|
|
|
print("Mutation")
|
2021-06-21 04:43:13 +02:00
|
|
|
# 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("")
|
2021-06-21 03:24:07 +02:00
|
|
|
|
2021-06-21 04:04:26 +02:00
|
|
|
population_text_copy = copy.deepcopy(population_text)
|
|
|
|
unused_indexes = [i for i in range(0, population_size) if i not in [j[0] for j in best]]
|
2021-06-21 03:24:07 +02:00
|
|
|
# Creating next generation
|
|
|
|
population_text = []
|
2021-06-21 04:43:13 +02:00
|
|
|
for k in parents_copy:
|
|
|
|
population_text.append(k)
|
2021-06-21 03:24:07 +02:00
|
|
|
for k in range(0, len(offspring_mutation)):
|
|
|
|
population_text.append(offspring_mutation[k])
|
2021-06-21 04:04:26 +02:00
|
|
|
while len(population_text) < population_size:
|
|
|
|
x = random.choice(unused_indexes)
|
|
|
|
population_text.append(population_text_copy[x])
|
|
|
|
unused_indexes.remove(x)
|
|
|
|
|
2021-06-21 03:38:21 +02:00
|
|
|
# TODO WARUNEK STOPU
|
|
|
|
stop = 0
|
2021-06-21 04:43:13 +02:00
|
|
|
if generation > 10:
|
2021-06-21 03:38:21 +02:00
|
|
|
if best_outputs[-1] / best_outputs[-2] < 1.05:
|
|
|
|
stop += 1
|
|
|
|
if best_outputs[-1] / best_outputs[-3] < 1.05:
|
|
|
|
stop += 1
|
|
|
|
if best_outputs[-2] / best_outputs[-3] < 1.05:
|
|
|
|
stop += 1
|
|
|
|
|
2021-06-21 03:24:07 +02:00
|
|
|
# final Fitness
|
|
|
|
fitness = []
|
|
|
|
for i in range(0, population_size):
|
|
|
|
fitness.append((i, population_fitness(population_text[i], field, population_size)))
|
|
|
|
|
|
|
|
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])
|
2021-06-20 13:24:12 +02:00
|
|
|
|
2021-06-21 01:56:55 +02:00
|
|
|
pretty_printer(best_outputs)
|
2021-06-20 18:02:11 +02:00
|
|
|
|
2021-06-21 04:43:13 +02:00
|
|
|
# TODO REALLY return best iteration of field
|
2021-06-20 18:02:11 +02:00
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
|
|
# Define the map of the field
|
|
|
|
mapschema = maps.createField()
|
|
|
|
|
|
|
|
# Create field array
|
|
|
|
field = []
|
|
|
|
|
|
|
|
# Populate the field array
|
|
|
|
for row in range(D.GSIZE):
|
|
|
|
field.append([])
|
|
|
|
for column in range(D.GSIZE):
|
|
|
|
fieldbit = F.Field(row, column, mapschema[column][row])
|
|
|
|
field[row].append(fieldbit)
|
|
|
|
|
|
|
|
genetic_algorithm_setup(field)
|