Sztuczna_Inteligencja-projekt/AI/ga_methods.py
Lewy 288d3cf30a GA implementation
- ADD crossover
- ADD mutation
- ADD next_gen preparation
- Project completed (with errors)

with Michał Malinowski
2021-06-21 03:24:07 +02:00

112 lines
3.6 KiB
Python

import copy
import random
import matplotlib
import numpy
import src.dimensions as D
# Genetic Algorithm methods
def local_fitness(field, x, y, plants_case):
soil_value = 0
if field[x][y].field_type == "soil":
soil_value = 1
else:
soil_value = 0.5
if plants_case[x][y] == "":
plant_value = 0
elif plants_case[x][y] == "w":
plant_value = 1
elif plants_case[x][y] == "p":
plant_value = 2
elif plants_case[x][y] == "s":
plant_value = 3
else:
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
if x + 1 < D.GSIZE:
if plants_case[x][y] == plants_case[x + 1][y]:
neighbour_bonus += 1
if y - 1 >= 0:
if plants_case[x][y] == plants_case[x][y - 1]:
neighbour_bonus += 1
if y + 1 < D.GSIZE:
if plants_case[x][y] == plants_case[x][y + 1]:
neighbour_bonus += 1
# TODO * multiculture_bonus
local_fitness_value = (soil_value + plant_value) * (0.5 * neighbour_bonus + 1)
return local_fitness_value
def population_fitness(population_text, field, population_size):
# Calculating the fitness value of each solution in the current population.
# The fitness function calulates the sum of products between each input and its corresponding weight.
fitness = []
for k in range(population_size):
population_values_single = []
population_values_single_row = []
fitness_row = []
for i in range(0, D.GSIZE):
for j in range(0, D.GSIZE):
population_values_single_row.append(local_fitness(field, i, j, population_text))
population_values_single.append(population_values_single_row)
for i in range(D.GSIZE):
fitness_row.append(sum(population_values_single[i]))
fitness = sum(fitness_row)
return fitness
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(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
def pretty_printer(best_outputs):
matplotlib.pyplot.plot(best_outputs)
matplotlib.pyplot.xlabel("Iteration")
matplotlib.pyplot.ylabel("Fitness")
matplotlib.pyplot.show()