Added genetic algorithm

This commit is contained in:
Jakub Sztuba 2022-06-10 04:05:23 +02:00
parent ff1b84c9e4
commit 62966a76a0
12 changed files with 272 additions and 4 deletions

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

8
.idea/KELNER.iml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
.idea/misc.xml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/KELNER.iml" filepath="$PROJECT_DIR$/.idea/KELNER.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

BIN
can.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
mess.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

163
restaurant.py Normal file
View File

@ -0,0 +1,163 @@
import numpy as np
import pygame
import tiles
#Parameters for genetic algorithm
n_trashes = tiles.howManyMesses
n_population = 100
mutation_rate = 0.5
listDraft = []
#Some settings for the whole project window
pygame.display.set_caption('Inteligentny Kelner - projekt SI 2022')
Icon = pygame.image.load('waiter.png')
pygame.display.set_icon(Icon)
#Take data from tiles.py
for i in range(len(tiles.messesArray)):
# Generating a list of coordinates representing each trash
coordinates_list = [[x*32,y*32] for x,y in tiles.messesArray]
listDraft.append(tiles.coordsToNum(coordinates_list[i]))
#Add some data
names_list = np.array(listDraft)
trashes_dict = {x:y for x, y in zip(names_list, coordinates_list)}
#Testing:
#print(trashes_dict)
#Function computing the distance between two points by its coordinates
def compute_trash_distance_coordinates(a, b):
return ((a[0]-b[0])**2+(a[1]-b[1])**2)**0.5
def compute_trash_distance_numbers(trash_a, trash_b, trash_dict):
return compute_trash_distance_coordinates(trash_dict[trash_a], trash_dict[trash_b])
#First step is to create the first population set
def genesis(trash_list, n_population):
population_set = []
for i in range(n_population):
#Randomly generated new solution
sol_i = trash_list[np.random.choice(list(range(n_trashes)), n_trashes, replace=False)]
population_set.append(sol_i)
return np.array(population_set)
population_set = genesis(names_list, n_population)
#Testing
#print(population_set)
def fitness_eval(trash_list, trash_dict):
total = 0
for i in range(n_trashes - 1):
a = trash_list[i]
b = trash_list[i + 1]
total += compute_trash_distance_numbers(a, b, trash_dict)
return total
def get_all_fitnes(population_set, trash_dict):
fitnes_list = np.zeros(n_population)
#Looping over all solutions computing the fitness for each solution
for i in range(n_population):
fitnes_list[i] = fitness_eval(population_set[i], trash_dict)
return fitnes_list
fitnes_list = get_all_fitnes(population_set, trashes_dict)
#Testing
#print(fitnes_list)
def ancestors_choose(population_set, fitnes_list):
total_fit = fitnes_list.sum()
prob_list = fitnes_list / total_fit
pop_len = len(population_set)
ancestor_list_a = np.random.choice(list(range(pop_len)), pop_len, p=prob_list, replace=True)
ancestor_list_b = np.random.choice(list(range(pop_len)), pop_len, p=prob_list, replace=True)
ancestor_list_a = population_set[ancestor_list_a]
ancestor_list_b = population_set[ancestor_list_b]
return np.array([ancestor_list_a, ancestor_list_b])
ancestor_list = ancestors_choose(population_set, fitnes_list)
#print(ancestor_list[0][2])
def mate_ancestors(prog_a, prog_b):
offspring = prog_a[0:5]
for trash in prog_b:
if not trash in offspring:
offspring = np.concatenate((offspring, [trash]))
return offspring
def mate_population(progenitor_list):
new_population_set = []
for i in range(progenitor_list.shape[1]):
prog_a, prog_b = progenitor_list[0][i], progenitor_list[1][i]
offspring = mate_ancestors(prog_a, prog_b)
new_population_set.append(offspring)
return new_population_set
new_population_set = mate_population(ancestor_list)
#print(new_population_set[0])
def mutate_offspring(offspring):
for q in range(int(n_trashes * mutation_rate)):
a = np.random.randint(0, n_trashes)
b = np.random.randint(0, n_trashes)
offspring[a], offspring[b] = offspring[b], offspring[a]
return offspring
def mutate_population(new_population_set):
mutated_pop = []
for offspring in new_population_set:
mutated_pop.append(mutate_offspring(offspring))
return mutated_pop
mutated_pop = mutate_population(new_population_set)
#print(mutated_pop[0])
best_solution = [-1, np.inf, np.array([])]
for i in range(1001):
#What I put here: iteration number, minimal fitness value, average fitness value
if i % 100 == 0: print(i, fitnes_list.min(), fitnes_list.mean())
fitnes_list = get_all_fitnes(mutated_pop, trashes_dict)
#Saving the best solution
if fitnes_list.min() < best_solution[1]:
best_solution[0] = i
best_solution[1] = fitnes_list.min()
best_solution[2] = np.array(mutated_pop)[fitnes_list.min() == fitnes_list]
ancestor_list = ancestors_choose(population_set, fitnes_list)
new_population_set = mate_population(ancestor_list)
mutated_pop = mutate_population(new_population_set)
trashesList = []
for i in range(len(best_solution[2][0])):
trashesList.append(0)
for i in range(len(best_solution[2][0])):
trashesList[i] = best_solution[2][0][i]
#Prints some specs to recreate if needed
print(trashesList)
print(tiles.messesArray)
#Pass solution to draw
tiles.main(trashesList)

Binary file not shown.

View File

@ -5,6 +5,7 @@ import pygame
import pytmx import pytmx
from queue import Queue from queue import Queue
import pandas as pd import pandas as pd
from pygame import surface
from sklearn.model_selection import train_test_split from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier from sklearn.tree import DecisionTreeClassifier
import json import json
@ -29,6 +30,9 @@ waiterImgL = pygame.image.load("waiterL.png")
waiterImgR = pygame.image.load("waiterR.png") waiterImgR = pygame.image.load("waiterR.png")
tableImg = pygame.image.load('table.png') tableImg = pygame.image.load('table.png')
chairImg = pygame.image.load('chair.png') chairImg = pygame.image.load('chair.png')
messImg = pygame.image.load('mess.png')
messImg2 = pygame.image.load('trash.png')
messImg3 = pygame.image.load('can.png')
clientImg = pygame.image.load('client.png') clientImg = pygame.image.load('client.png')
image = pygame.image.load('test/0.jpg') image = pygame.image.load('test/0.jpg')
@ -114,6 +118,13 @@ class Chair:
def render(self, surface): def render(self, surface):
surface.blit(chairImg, (self.loc[0], self.loc[1])) surface.blit(chairImg, (self.loc[0], self.loc[1]))
class Mess:
def __init__(self, loc):
self.loc = loc
def render(self, surface):
surface.blit(messImg, (self.loc[0], self.loc[1]))
def pos_of_chair(table_cor, k): def pos_of_chair(table_cor, k):
pos = ((table_cor[0], table_cor[1] - 32), pos = ((table_cor[0], table_cor[1] - 32),
@ -336,6 +347,9 @@ class Map:
def add_chair(self, loc): def add_chair(self, loc):
self.arr[loc[0] // 32, loc[1] // 32] = 100 self.arr[loc[0] // 32, loc[1] // 32] = 100
def add_mess(self, loc):
self.arr[loc[0] // 32, loc[1] // 32] = 100
def add_table(self, loc): def add_table(self, loc):
self.arr[loc[0] // 32, loc[1] // 32] = 200 self.arr[loc[0] // 32, loc[1] // 32] = 200
@ -576,6 +590,9 @@ def get_pizza(number):
def display_img(surface, image): def display_img(surface, image):
surface.blit(image, (120, 120)) surface.blit(image, (120, 120))
def display_sth(surface, image, coordX,coordY):
surface.blit(image, (coordX, coordY))
def create_training_data(): def create_training_data():
DATADIR = "Images" DATADIR = "Images"
@ -638,14 +655,12 @@ def learn_neural_network(X, y):
return model return model
def prepare_img(filepath): def prepare_img(filepath):
IMG_SIZE = 90 IMG_SIZE = 90
img_array = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE) img_array = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE)
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE)) new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
return new_array.reshape(-1, IMG_SIZE, IMG_SIZE, 1) / 255 return new_array.reshape(-1, IMG_SIZE, IMG_SIZE, 1) / 255
def predict(model,filepath): def predict(model,filepath):
return model.predict([prepare_img(filepath)]) return model.predict([prepare_img(filepath)])
@ -685,7 +700,31 @@ client = Client(generate_client())
neural_prediction_in = False neural_prediction_in = False
def main(): restaurantIsClean = False
howManyMesses = random.randint(8, 12)
messesArray = [[0 for x in range(2)] for y in range(howManyMesses)]
for i in range(howManyMesses):
whereMessX = random.randint(1, 18)
whereMessY = random.randint(1, 18)
messesArray[i][0] = whereMessX
messesArray[i][1] = whereMessY
#messesArray = [[3, 14], [7, 17], [10, 9], [16, 10], [12, 18], [4, 11], [11, 14], [3, 5], [7, 18], [6, 13], [10, 8], [13, 16], [10, 6], [8, 6], [4, 10], [14, 6], [18, 1], [12, 17], [10, 11], [18, 3]]
#messesArray = [[9, 5], [16, 5], [5, 5], [10, 13], [3, 10], [8, 15], [13, 8], [14, 14], [12, 12], [3, 1]]
#messesArray = [[12, 8], [15, 9], [14, 9], [13, 6], [7, 7], [9, 7], [2, 15], [18, 16], [13, 15], [8, 18], [7, 14]]
#good example below
#messesArray = [[10, 12], [5, 17], [18, 3], [13, 2], [4, 5], [7, 4], [16, 5], [3, 2], [14, 17]]
#messesArray = [[12, 3], [11, 9], [13, 15], [3, 5], [2, 14], [17, 15], [1, 12], [14, 9], [7, 1], [7, 6]]
#this one below!
#messesArray = [[2, 15], [11, 9], [5, 11], [17, 1], [15, 7], [14, 10], [18, 8], [2, 9], [6, 4], [18, 10]]
#print(messesArray)
pygame.font.init()
default_font = pygame.font.get_default_font()
font_renderer = pygame.font.Font(default_font, 12)
def main(trashesList):
direction = [] direction = []
first_time = True first_time = True
number = 0 number = 0
@ -706,6 +745,20 @@ def main():
if tile is not None: if tile is not None:
display.blit(tile, (x * gameMap.tilewidth, y * gameMap.tileheight)) display.blit(tile, (x * gameMap.tilewidth, y * gameMap.tileheight))
key = pygame.key.get_pressed()
messesToDisplay = messesArray
for i in range (len(messesToDisplay)):
currentMessX = messesToDisplay[i][0]
currentMessY = messesToDisplay[i][1]
if i % 3 == 0:
display.blit(messImg, (currentMessX * 32, currentMessY * 32))
elif i % 3 == 1:
display.blit(messImg2, (currentMessX * 32, currentMessY * 32))
elif i % 3 == 2:
display.blit(messImg3, (currentMessX * 32, currentMessY * 32))
waiter.handle_events() waiter.handle_events()
for table in tables: for table in tables:
table.render(display) table.render(display)
@ -713,7 +766,6 @@ def main():
for chair in chair_list: for chair in chair_list:
chair.render(display) chair.render(display)
key = pygame.key.get_pressed()
left, middle, right = pygame.mouse.get_pressed() left, middle, right = pygame.mouse.get_pressed()
if key[pygame.K_e]: if key[pygame.K_e]:
@ -801,6 +853,19 @@ def main():
neural_prediction_in = False neural_prediction_in = False
font = pygame.font.SysFont('Arial', 18, bold=True)
trashesArray = trashesList
trashesLen = len(trashesArray)
#pygame.draw.line(display, (15, 0, 148), (32, 32), (numToX(trashesArray[0]), numToY(trashesArray[0])), 4)
for i in range(len(trashesArray)-1):
img = font.render(str(i), True,
pygame.Color(255, 255, 255),
pygame.Color(10, 148, 0))
pygame.draw.line(display, (10, 148, 0), (numToX(trashesArray[i]),numToY(trashesArray[i])), (numToX(trashesArray[i+1]),numToY(trashesArray[i+1])), 4)
display_sth(display, img, numToX(trashesArray[i]), numToY(trashesArray[i]))
img = font.render(str(trashesLen-1), True, pygame.Color(255, 255, 255), pygame.Color(10, 148, 0))
display_sth(display, img, numToX(trashesArray[trashesLen-1]), numToY(trashesArray[trashesLen-1]))
pygame.display.update() pygame.display.update()

BIN
trash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB