adding genetic algorithm implementation that chooses which plants to farm #3

Merged
s464891 merged 3 commits from genetic_algorithm into master 2022-06-06 18:27:42 +02:00
4 changed files with 46 additions and 18 deletions
Showing only changes of commit 3387d41839 - Show all commits

View File

@ -25,8 +25,8 @@ class Constants:
NONE = 'brak'
CACTUS = 'kaktus'
POTATO = 'ziemniak'
WEATH = 'pszenica'
WHEAT = 'pszenica'
# Genetic algorithm points average
POINTS_AVERAGE = 20
POINTS_AVERAGE = range(5, 8)

View File

@ -12,7 +12,7 @@ class GeneticAlgorithm:
def selection_strategy(self, generation: BaseField):
maximum_selected_items = int(len(generation) / 10)
sorted_elements = sorted(generation, key=lambda x: x.evaluation)
return sorted[:maximum_selected_items]
return sorted_elements[:maximum_selected_items]
def _generate_random_plants(self):
plant_names = [choice(BaseField.possibilities) for _ in range(9)]
@ -22,8 +22,6 @@ class GeneticAlgorithm:
return [BaseField(self._generate_random_plants()) for _ in range(100)]
def run(self):
for population in self._generate_first_population():
print(population)
first_population = self._generate_first_population()
first_population.sort(key=lambda x: x.evaluation)
population_length = len(first_population)
@ -40,8 +38,9 @@ class GeneticAlgorithm:
first_population = new_population
best_match = min(first_population, key=lambda x: x.evaluation)
i += 1
if self.stop_condition(best_match):
if self.stop_condition(float(best_match)):
break
print(best_match)
def main():

View File

@ -13,21 +13,21 @@ class BasePlant:
pass
def __int__(self):
return sum([self.appearance_points, self.difficulty_points, self.profit_points])
return sum([self.appearance_points, self.profit_points]) - self.difficulty_points
def __float__(self):
return self.__int__()
def stop_condition(average):
return average == Constants.POINTS_AVERAGE
return average in Constants.POINTS_AVERAGE
def plant_selector(plant_name: str) -> BasePlant:
if plant_name == Constants.POTATO:
return Potato()
elif plant_name == Constants.WEATH:
return Weath()
elif plant_name == Constants.WHEAT:
return Wheat()
elif plant_name == Constants.CACTUS:
return Cactus()
@ -35,7 +35,7 @@ def plant_selector(plant_name: str) -> BasePlant:
class BaseField:
"""Class that represents what plants grow on a certain field divided into 9 tiles"""
possibilities = [Constants.WEATH, Constants.POTATO, Constants.CACTUS]
possibilities = [Constants.WHEAT, Constants.POTATO, Constants.CACTUS]
def __init__(self, plants):
self.plants: list(BasePlant) = plants
@ -54,27 +54,56 @@ class BaseField:
new_plants = self.plants[:length] + other_field.plants[length:]
return BaseField(new_plants)
def evaluate_function(self):
current_fields_average = sum([int(plant) for plant in self.plants]) / 9
return Constants.POINTS_AVERAGE - current_fields_average
def evaluate_function(self) -> float:
current_fields_average = self.__float__()
if current_fields_average not in Constants.POINTS_AVERAGE:
if current_fields_average < Constants.POINTS_AVERAGE[0]:
return abs(current_fields_average - Constants.POINTS_AVERAGE[0])
elif current_fields_average > Constants.POINTS_AVERAGE[-1]:
return abs(current_fields_average - Constants.POINTS_AVERAGE[1])
return 0
def __str__(self):
return ''.join([str(plant) + ' ' for plant in self.plants])
def __float__(self):
return sum([int(plant) for plant in self.plants]) / 9
class Potato(BasePlant):
def __init__(self):
super().__init__()
self.appearance_points = 3
self.difficulty_points = 4
self.profit_points = 7
def __str__(self):
return Constants.POTATO
class Cactus(BasePlant):
def __init__(self):
super(Cactus, self).__init__()
self.appearance_points = 6
self.difficulty_points = 3
self.profit_points = 2
def __str__(self):
return Constants.CACTUS
class Weath(BasePlant):
class Wheat(BasePlant):
def __init__(self):
super(Wheat, self).__init__()
self.appearance_points = 5
self.difficulty_points = 7
self.profit_points = 9
def __str__(self):
return Constants.WEATH
return Constants.WHEAT

View File

@ -53,7 +53,7 @@ class World:
img = pygame.transform.scale(self.farmland_empty, (self.settings.tile_size, self.settings.tile_size))
elif to_water == 0 and rodzaj_rosliny == Constants.CACTUS:
img = pygame.transform.scale(self.farmland_cactus, (self.settings.tile_size, self.settings.tile_size))
elif to_water == 0 and rodzaj_rosliny == Constants.WEATH:
elif to_water == 0 and rodzaj_rosliny == Constants.WHEAT:
img = pygame.transform.scale(self.farmland_wheat, (self.settings.tile_size, self.settings.tile_size))
elif to_water == 0 and rodzaj_rosliny == Constants.POTATO:
img = pygame.transform.scale(self.farmland_potato, (self.settings.tile_size, self.settings.tile_size))
@ -61,7 +61,7 @@ class World:
img = pygame.transform.scale(self.dirt_empty, (self.settings.tile_size, self.settings.tile_size))
elif to_water == 1 and rodzaj_rosliny == Constants.CACTUS:
img = pygame.transform.scale(self.dirt_cactus, (self.settings.tile_size, self.settings.tile_size))
elif to_water == 1 and rodzaj_rosliny == Constants.WEATH:
elif to_water == 1 and rodzaj_rosliny == Constants.WHEAT:
img = pygame.transform.scale(self.dirt_wheat, (self.settings.tile_size, self.settings.tile_size))
elif to_water == 1 and rodzaj_rosliny == Constants.POTATO:
img = pygame.transform.scale(self.dirt_potato, (self.settings.tile_size, self.settings.tile_size))