Compare commits
3 Commits
neural_net
...
main
Author | SHA1 | Date | |
---|---|---|---|
6cba5133a3 | |||
|
8a2d14b8a3 | ||
7defc84f17 |
BIN
genetic_algorithm_matrix.pkl
Normal file
BIN
genetic_algorithm_matrix.pkl
Normal file
Binary file not shown.
3
main.py
3
main.py
@ -1,7 +1,7 @@
|
||||
import pygame
|
||||
import sys
|
||||
import random
|
||||
from settings import SIZE, directions, draw_lines_on_window
|
||||
from settings import SIZE, directions, draw_lines_on_window, matrix_plants_type
|
||||
from src.map import drawRoads, seedForFirstTime, return_fields_list, WORLD_MATRIX, get_type_by_position
|
||||
from src.Tractor import Tractor
|
||||
from src.bfs import Astar
|
||||
@ -45,6 +45,7 @@ def recognize_plants(fields, destination):
|
||||
print(pred)
|
||||
return pred
|
||||
|
||||
|
||||
# pygame initialization
|
||||
pygame.init()
|
||||
clock = pygame.time.Clock()
|
||||
|
@ -1,6 +1,11 @@
|
||||
from cmath import sqrt
|
||||
import pygame
|
||||
import pickle
|
||||
|
||||
def load_matrix(filename):
|
||||
with open(filename, 'rb') as file:
|
||||
matrix = pickle.load(file)
|
||||
return matrix
|
||||
|
||||
screen_width = 1368
|
||||
screen_height = 936
|
||||
@ -18,6 +23,7 @@ field_width = 4
|
||||
field_height = 4
|
||||
field_size = field_width*field_height
|
||||
fields_amount = 25
|
||||
matrix_plants_type = load_matrix("genetic_algorithm_matrix.pkl")
|
||||
|
||||
directions = {0: 'UP', 90: 'RIGHT', 180: 'DOWN', 270: 'LEFT'}
|
||||
|
||||
@ -30,3 +36,5 @@ def draw_lines_on_window(background):
|
||||
pygame.draw.line(background, (0, 0, 0), (968, 649), (1336 , 649))
|
||||
pygame.draw.line(background, (0, 0, 0), (968, 285), (968, 649))
|
||||
pygame.draw.line(background, (0, 0, 0), (1336, 285), (1336, 649))
|
||||
|
||||
|
||||
|
161
src/genetic_algorithm.py
Normal file
161
src/genetic_algorithm.py
Normal file
@ -0,0 +1,161 @@
|
||||
import random
|
||||
import copy
|
||||
import pickle
|
||||
import numpy
|
||||
|
||||
# Constants
|
||||
GRID_SIZE = 5
|
||||
PLANT_TYPES = [1, 2, 3]
|
||||
POPULATION_SIZE = 1000
|
||||
MAX_GENERATIONS = 100
|
||||
MUTATION_RATE = 0.1
|
||||
|
||||
def generate_random_chromosome():
|
||||
# Generate a random chromosome (random matrix)
|
||||
chromosome = [[0] * GRID_SIZE for _ in range(GRID_SIZE)]
|
||||
|
||||
for row in range(GRID_SIZE):
|
||||
for col in range(GRID_SIZE):
|
||||
available_types = PLANT_TYPES.copy()
|
||||
chromosome[row][col] = random.choice(available_types)
|
||||
|
||||
return chromosome
|
||||
|
||||
def calculate_fitness(chromosome):
|
||||
# Calculate the fitness by counting the number of adjacent fields with the same plant type
|
||||
fitness = 0
|
||||
appearances = [0,0,0]
|
||||
|
||||
for row in range(GRID_SIZE):
|
||||
for col in range(GRID_SIZE):
|
||||
plant_type = chromosome[row][col]
|
||||
|
||||
# Check left neighbor
|
||||
if col > 0 and chromosome[row][col - 1] == plant_type:
|
||||
fitness += 1
|
||||
# Check top neighbor
|
||||
if row > 0 and chromosome[row - 1][col] == plant_type:
|
||||
fitness += 1
|
||||
|
||||
|
||||
for row in chromosome:
|
||||
appearances[0] = appearances[0] + row.count(1)
|
||||
appearances[1] = appearances[1] + row.count(2)
|
||||
appearances[2] = appearances[2] + row.count(3)
|
||||
|
||||
for i in range(len(appearances)):
|
||||
if appearances[i] < 7 and appearances[i] > 9:
|
||||
fitness = fitness + abs(appearances[i]-8)
|
||||
return fitness
|
||||
|
||||
def selection(population):
|
||||
# Perform tournament selection to choose parents for reproduction
|
||||
tournament_size = 5
|
||||
parents = []
|
||||
|
||||
for _ in range(len(population)):
|
||||
tournament = random.sample(population, tournament_size)
|
||||
tournament.sort(key=lambda chromosome: calculate_fitness(chromosome))
|
||||
parents.append(tournament[0])
|
||||
|
||||
return parents
|
||||
|
||||
def crossover(parent1, parent2):
|
||||
# Perform single-point crossover to create two offspring
|
||||
crossover_point = random.randint(0, (GRID_SIZE*GRID_SIZE)-1)
|
||||
|
||||
row = crossover_point // GRID_SIZE
|
||||
column = crossover_point % GRID_SIZE
|
||||
offspring1 = []
|
||||
offspring2 = []
|
||||
counter = 0
|
||||
while counter<row:
|
||||
offspring1.append(parent1[counter])
|
||||
offspring2.append(parent2[counter])
|
||||
counter += 1
|
||||
# The place, where the parents are 'cutten' is here
|
||||
offspring1.append(parent1[counter][:column] + parent2[counter][column:])
|
||||
offspring2.append(parent2[counter][:column] + parent1[counter][column:])
|
||||
|
||||
while counter<GRID_SIZE-1:
|
||||
offspring1.append(parent2[counter])
|
||||
offspring2.append(parent1[counter])
|
||||
counter += 1
|
||||
|
||||
return offspring1, offspring2
|
||||
|
||||
|
||||
def genetic_algorithm():
|
||||
|
||||
results = []
|
||||
population = [generate_random_chromosome() for _ in range(POPULATION_SIZE)]
|
||||
|
||||
# Main loop
|
||||
for gen in range(MAX_GENERATIONS):
|
||||
parents = selection(population)
|
||||
offspring = []
|
||||
|
||||
# Crossover
|
||||
for i in range(0, len(parents), 2):
|
||||
parent1 = parents[i]
|
||||
parent2 = parents[i + 1]
|
||||
child1, child2 = crossover(parent1, parent2)
|
||||
offspring.append(child1)
|
||||
offspring.append(child2)
|
||||
|
||||
# Replacement
|
||||
population = offspring
|
||||
|
||||
# Count best fitness of each population
|
||||
best_chromosome = min(population, key=lambda chromosome: calculate_fitness(chromosome))
|
||||
best_fitness = calculate_fitness(best_chromosome)
|
||||
results.append((copy.deepcopy(best_chromosome), best_fitness))
|
||||
if best_fitness == 0:
|
||||
break
|
||||
|
||||
results.sort(key = lambda x: x[1])
|
||||
best_tuple = results[0]
|
||||
best_chromosome, best_fitness = best_tuple
|
||||
return best_chromosome
|
||||
|
||||
# Replacing numbers into plants:
|
||||
def replace_numbers(number_matrix):
|
||||
return_matrix = number_matrix.copy()
|
||||
for row in range(GRID_SIZE):
|
||||
for col in range(GRID_SIZE):
|
||||
if number_matrix[row][col] == 1:
|
||||
return_matrix[row][col] = "carrot"
|
||||
elif number_matrix[row][col] == 2:
|
||||
return_matrix[row][col] = "potato"
|
||||
elif number_matrix[row][col] == 3:
|
||||
return_matrix[row][col] = "wheat"
|
||||
else:
|
||||
number_matrix[row][col] = "error"
|
||||
return return_matrix
|
||||
|
||||
# Make the matrix as a list:
|
||||
def list_of_matrix(plant_matrix):
|
||||
return_list = []
|
||||
for i in range(len(plant_matrix)):
|
||||
return_list += plant_matrix[i]
|
||||
return return_list
|
||||
|
||||
# Run the genetic algorithm
|
||||
best_solution = genetic_algorithm()
|
||||
|
||||
# Print the best solution found
|
||||
print("Best Solution:")
|
||||
for row in best_solution:
|
||||
print(row)
|
||||
print("Best fitness: ", calculate_fitness(best_solution))
|
||||
print("")
|
||||
|
||||
replaced_matrix = replace_numbers(best_solution)
|
||||
print("Replaced Matrix:")
|
||||
for row in replaced_matrix:
|
||||
print(row)
|
||||
return_list = list_of_matrix(replaced_matrix)
|
||||
|
||||
|
||||
with open("genetic_algorithm_matrix.pkl", "wb") as file:
|
||||
pickle.dump(return_list, file)
|
@ -1,6 +1,6 @@
|
||||
from cmath import sqrt
|
||||
import pygame
|
||||
from settings import screen_height, screen_width, SIZE, SPECIES, block_size, tile, road_coords, fields_amount, field_size, field_height, field_width
|
||||
from settings import screen_height, screen_width, SIZE, SPECIES, block_size, tile, road_coords, fields_amount, field_size, field_height, field_width, matrix_plants_type
|
||||
from src.Plant import Plant
|
||||
import random
|
||||
from src.Field import Field
|
||||
@ -60,9 +60,11 @@ def drawRoads(screen):
|
||||
return screen
|
||||
|
||||
def seedForFirstTime():
|
||||
plants_type = matrix_plants_type
|
||||
|
||||
plant_group = pygame.sprite.Group()
|
||||
for field in range(fields_amount):
|
||||
plant_name = random.choice(SPECIES)
|
||||
plant_name = matrix_plants_type[field]
|
||||
blocks_seeded_in_field = 0
|
||||
while (blocks_seeded_in_field < field_size):
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user