From 22c4d2ba04fc08ff5e4161956233e5e8c2cae89d Mon Sep 17 00:00:00 2001 From: Adam Cherek Date: Thu, 9 Jun 2022 23:20:37 +0200 Subject: [PATCH] Genetic algorithm to find best pathway --- board.py | 18 ++++-- imagerecognizer.py | 8 +-- pathfinder.py | 144 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+), 10 deletions(-) diff --git a/board.py b/board.py index 59f9b01..b6197c6 100644 --- a/board.py +++ b/board.py @@ -68,8 +68,10 @@ class Board: self.first_ground = self.board[0].index('T') self.show_board() self.init_board() - self.bombfield = pathfinder.find_bomb(self.fields, self.first_ground) - print(self.bombfield) + #self.bombfield = pathfinder.find_bomb(self.fields, self.first_ground) + self.genetic = pathfinder.Genetic(self.fields, self.first_ground) + self.bombfield = self.genetic.genetic_path.fields_order[0] + #print(self.bombfield) self.pathf = pathfinder.Pathfind(self.fields, self.bombfield, self.first_ground) self.ir = ImageRecognizer() self.dt = DecisionTree() @@ -167,10 +169,14 @@ class Board: self.fields[agent.pos_field].object.move_away(SQUARE_WIDTH, SQUARE_HEIGHT) self.fields[agent.pos_field].redisp = True self.bombs -= 1 - if self.bombs > 0: - self.bombfield = pathfinder.find_bomb(self.fields, agent.pos_field) - #print(self.bombfield) - self.pathf = pathfinder.Pathfind(self.fields, self.bombfield, agent.pos_field) + if self.bombs > 0 and agent.pos_field == self.bombfield: + #self.bombfield = pathfinder.find_bomb(self.fields, agent.pos_field) + #print(self.bombfield) + self.genetic.genetic_path.fields_order.remove(self.genetic.genetic_path.fields_order[0]) + self.bombfield = self.genetic.genetic_path.fields_order[0] + print("next bombfield is: ", self.bombfield) + self.pathf = pathfinder.Pathfind(self.fields, self.bombfield, agent.pos_field) + def automove_agent(self,agent): diff --git a/imagerecognizer.py b/imagerecognizer.py index f60b5b5..ded3cde 100644 --- a/imagerecognizer.py +++ b/imagerecognizer.py @@ -4,8 +4,8 @@ from keras import layers as ls import numpy as np -image_height = 64 -image_width = 64 +image_height = 256 +image_width = 256 batch_size = 32 sets_path = "./learning_sets" model_path="./IR.model" @@ -16,7 +16,7 @@ class ImageRecognizer(): if train_new_model == True: # deklarowanie setów treningowych i testowych self.trainset = keras.utils.image_dataset_from_directory(sets_path, validation_split=0.2, subset="training",seed=0, image_size=(image_height, image_width),batch_size=batch_size) - self.testset = keras.utils.image_dataset_from_directory(sets_path, validation_split=0.2,subset="validation", seed=0,image_size=(image_height, image_width),atch_size=batch_size) + self.testset = keras.utils.image_dataset_from_directory(sets_path, validation_split=0.2,subset="validation", seed=0,image_size=(image_height, image_width),batch_size=batch_size) self.class_names = self.trainset.class_names self.trainset = self.trainset.cache().shuffle(1000).prefetch(buffer_size=tensorflow.data.AUTOTUNE) self.testset = self.testset.cache().prefetch(buffer_size=tensorflow.data.AUTOTUNE) @@ -51,4 +51,4 @@ class ImageRecognizer(): classification = tensorflow.nn.softmax(prediction[0]) #wynik predykcji print("Image: ",image_path," is classified as: ",format(self.class_names[np.argmax(classification)])," with: ", 100 * np.max(classification), " accuracy") - return format(self.class_names[np.argmax(classification)]) + return format(self.class_names[np.argmax(classification)]) \ No newline at end of file diff --git a/pathfinder.py b/pathfinder.py index ef78ef0..daa8596 100644 --- a/pathfinder.py +++ b/pathfinder.py @@ -1,4 +1,5 @@ import board +import random def distance_between(startpoint, endpoint): @@ -22,6 +23,149 @@ def find_bomb(fields, start_position): return bombfield +class Chromosome: + def __init__(self, fo, wl): + self.fields_order = fo + self.way_lenght = wl + +class Genetic: + def __init__(self, fields, ap): + self.bombfields = self.get_bombs(fields) + self.agent_position = ap + self.local_minimum_path = self.find_local_minimum_path() + self.make_parents() + self.parents = self.make_parents() + self.children = self.make_children(self.parents) + self.genetic_path = self.parents[0] + for i in range(10000): + self.genetic_path = self.find_genetic_path() + print("Genetic path way: ", self.genetic_path.fields_order) + print("Genetic path way lenght: ", self.genetic_path.way_lenght) + print("Local minimum path: ", self.local_minimum_path.fields_order) + print("Local minimum path way lenght: ", self.local_minimum_path.way_lenght) + if self.local_minimum_path.way_lenght >= self.genetic_path.way_lenght: + print("Wygrywa genetic path !!!") + else: + print("Local minimum path teoretycznie byłby lepszy :/") + + def get_bombs(self,fields): + bombfields = [] + for i in range(len(fields)): + if fields[i].type == 'B': + bombfields.append(i) + #print(bombfields) + return bombfields + + + def make_parents(self): + parent_chromosomes = [] + for i in range(len(self.bombfields)*10): + bombfieldscopy = self.bombfields.copy() + single_chromosome = [] + weight_of_chromosome = 0 + for j in range(len(self.bombfields)): + random_choice = random.randint(0,(len(bombfieldscopy)-1)) + single_chromosome.append(bombfieldscopy[random_choice]) + bombfieldscopy.remove(bombfieldscopy[random_choice]) + if j == 0: + weight_of_chromosome = weight_of_chromosome + distance_between(self.agent_position,single_chromosome[j]) + else: + weight_of_chromosome = weight_of_chromosome + distance_between(single_chromosome[j-1],single_chromosome[j]) + parent_chromosomes.append(Chromosome(single_chromosome,weight_of_chromosome)) + #print("parent chromosome ", i, ":") + #print(parent_chromosomes[i].fields_order) + #print(parent_chromosomes[i].way_lenght) + return parent_chromosomes + + def make_children(self,parents): + children_chromosomes = [] + parentscopy = parents.copy() + for i in range(len(self.bombfields)*10): + parentscopy = parents.copy() + rch = random.randint(0,(len(self.bombfields)*10)-1) + parent1 = parentscopy[rch].fields_order.copy() + #print("parent 1 order: ", parent1) + parentscopy.remove(parentscopy[rch]) + rch2 = random.randint(0,(len(self.bombfields)*10)-2) + parent2 = parentscopy[rch2].fields_order.copy() + #print("parent 2 order: ",parent2) + parentscopy.remove(parentscopy[rch2]) + how_many_elements = random.randint(1,len(self.bombfields)-1) + elements_to_switch = [] + single_chromosome = [] + weight_of_chromosome = 0 + for j in range(how_many_elements): + random_choice = random.randint(0,(len(parent1)-1)) + elements_to_switch.append(parent1[random_choice]) + #print("element to switch: ", elements_to_switch[j]) + parent1.remove(elements_to_switch[j]) + #print("parent 2 order: ", parent2.fields_order) + parent2.remove(elements_to_switch[j]) + parent2.append(elements_to_switch[j]) + single_chromosome = parent2.copy() + for j in range(len(single_chromosome)): + if j == 0: + weight_of_chromosome = weight_of_chromosome + distance_between(self.agent_position,single_chromosome[j]) + else: + weight_of_chromosome = weight_of_chromosome + distance_between(single_chromosome[j - 1],single_chromosome[j]) + children_chromosomes.append(Chromosome(single_chromosome,weight_of_chromosome)) + #print("children chromosome ", i, ":") + #print(children_chromosomes[i].fields_order) + #print(children_chromosomes[i].way_lenght) + return children_chromosomes + + + def find_genetic_path(self): + chromosomes = [] + new_parents = [] + for i in range(len(self.parents)): + chromosomes.append(self.parents[i]) + for i in range(len(self.children)): + chromosomes.append(self.children[i]) + chromosomes.sort(key=lambda x: x.way_lenght) + for j in range(len(self.bombfields)**2): + new_parents.append(chromosomes[j]) + self.parents = new_parents + self.children = self.make_children(self.parents) + return chromosomes[0] + + def find_local_minimum_path(self): + path = [] + bombfiledscopy = self.bombfields.copy() + path_lenght = 0 + bombfield = -1 + mindist = board.BOARDCOLS ** 2 + for field in bombfiledscopy: + dist = distance_between(self.agent_position,field) + if dist < mindist: + bombfield = field + mindist = dist + path_lenght = path_lenght + mindist + path.append(bombfield) + bombfiledscopy.remove(bombfield) + + while len(bombfiledscopy) > 0: + mindist = board.BOARDCOLS ** 2 + for field in bombfiledscopy: + dist = distance_between(bombfield, field) + if dist < mindist: + bombfield = field + mindist = dist + path_lenght = path_lenght + mindist + path.append(bombfield) + bombfiledscopy.remove(bombfield) + + return Chromosome(path,path_lenght) + + + + + + + + + + class Node: def __init__(self,fieldN,parent,destination,obstacle_deley_value):