Genetic algorithm to find best pathway

This commit is contained in:
Adam Cherek 2022-06-09 23:20:37 +02:00
parent e07ab2a955
commit 22c4d2ba04
3 changed files with 160 additions and 10 deletions

View File

@ -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):

View File

@ -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)

View File

@ -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):