diff --git a/src/dna.py b/src/dna.py new file mode 100644 index 0000000..2a7c1f9 --- /dev/null +++ b/src/dna.py @@ -0,0 +1,49 @@ +import random +import string +from src.a_star import a_star_search +from random import shuffle +import numpy as np + +class DNA: + + def __init__(self, target): + shuffle(target) + self.genes = target.copy() + self.fitness = 1.0 + + def calcFitness(self, AGENT_MAP): + start = (0, 0) + sum = 1 + + agent_direction = "right" + + for goal in self.genes: + path = a_star_search(start, goal, agent_direction, AGENT_MAP) + sum = sum + len(path) - 1 + start = goal + + self.fitness = sum + + def crossover(self, partner): + + child = DNA(self.genes) + start = abs(random.randint(0, len(self.genes)) - 1) + end = abs(random.randint(start - 1, len(self.genes))) + + child.genes = child.genes[start:end] + + for i in range(len(self.genes)): + node = partner.genes[i] + + if node not in child.genes: + child.genes.append(node) + + return child + + def mutate(self, mutationRate): + + for i in range(len(self.genes)): + if random.random() < mutationRate: + indexA = abs(random.randint(0, len(self.genes)) - 1) + indexB = (indexA + 1) % len(self.genes) + self.genes[indexA], self.genes[indexB] = self.genes[indexB], self.genes[indexA] diff --git a/src/genetic.py b/src/genetic.py new file mode 100644 index 0000000..59d3ff5 --- /dev/null +++ b/src/genetic.py @@ -0,0 +1,51 @@ +import numpy as np +from src.dna import DNA +import random +import copy + +def genetic(goals, AGENT_MAP): + recordDistance = 1000000000 + + #count = 0 + generation = 0 + totalPopulaton = 10 + population = [] + matingPool = [] + + mutationRate = 0.01 + + for i in range(totalPopulaton): + population.append(DNA(goals)) + + for j in range(totalPopulaton): + matingPool.clear() + generation = generation + 1 + for i in range(totalPopulaton): + population[i].calcFitness(AGENT_MAP) + + if population[i].fitness < recordDistance: + recordDistance = population[i].fitness + best = copy.deepcopy(population[i]) + bestGeneration = generation + + for i in range(totalPopulaton): + n = population[i].fitness * 100 + + for j in range(int(n)): + matingPool.append(population[i]) + + for i in range(totalPopulaton): + if matingPool: + a = random.randint(0, len(matingPool) - 1) + b = random.randint(0, len(matingPool) - 1) + + partnerA = matingPool[a] + partnerB = matingPool[b] + + child = partnerA.crossover(partnerB) + + child.mutate(mutationRate) + + population[i] = child + + return best \ No newline at end of file diff --git a/src/main.py b/src/main.py index 6377253..e14a057 100644 --- a/src/main.py +++ b/src/main.py @@ -11,6 +11,7 @@ from mlxtend.data import loadlocal_mnist from src.a_star import a_star_search from src.training_data.scripts.gen_data_id3 import generate_size, generate_weight, generate_price, generate_flammability, generate_explosiveness from src.tree import predict_result, load_tree_from_structure +from src.genetic import genetic import torch from torch import nn from torch import optim @@ -30,6 +31,7 @@ IMAGE = pygame.transform.scale(pygame.image.load('img/wozek2.png'), (75, 75)) BACKGROUND = pygame.transform.scale(pygame.image.load('img/background.png'), (WIDTH, HEIGHT)) DOCK = pygame.transform.scale(pygame.image.load('img/dock_left.png'), (75, 75)) TRASH = pygame.transform.scale(pygame.image.load('img/trash.png'), (75, 75)) +GATE = pygame.transform.scale(pygame.image.load('img/shelf.png'), (75, 75)) get_pix_from_position = {} @@ -307,6 +309,7 @@ class Agent: def lift_package_bfs(self): for package in Package_list: + print(package.pos) if package.is_package_up: package.is_package_up = False elif package.pos == agent.pos: @@ -343,6 +346,9 @@ Shelf_list = [ Shelf((5, 8), 'Electronic', 5), Shelf((6, 8), 'Electronic', 5), Shelf((7, 8), 'Electronic', 5), Shelf((8, 8), 'Electronic', 5)] +gate_list = [(2, 1), (1, 5), (2, 6), (3, 4)] +goals_from_genetic = [] + coord_goals = [(0, 0)] free_shelf = [(5, 8), (6, 8), (7, 8), (8, 8), (5, 6), (6, 6), (7, 6), (8, 6)] @@ -354,7 +360,6 @@ Package_list = [ agent.path = a_star_search((agent.pos_coord[1], agent.pos_coord[0]), coord_goals.pop(0), agent.agent_direction, AGENT_MAP) - # Pętla służąca do tworzenia plam oleju na podstawie mapy magazynu Stain_list = [] @@ -364,6 +369,8 @@ for index_x in range(9): Stain_list.append(Stain((index_y, index_x))) running = True +newRandom = None #tymczasowe + while running: for event in pygame.event.get(): @@ -398,18 +405,31 @@ while running: agent.move_bfs() else: - agent.lift_package_bfs() + if agent.pos_coord == (0, 0) or agent.pos_coord == newRandom or agent.pos_coord == (8, 0): #powstrzymuje agenta przed zostawianiem paczek w punktach kontrolnych + agent.lift_package_bfs() if agent.pos_coord == (0, 0): if Package_list[-1].is_accepted == 1: - coord_goals.append(free_shelf[random.randint(0, 7)]) + newRandom = free_shelf[random.randint(0, 7)] + coord_goals.append(newRandom) + # Obliczanie optymalnej ścieżki + genetic_goals = gate_list.copy() + genetic_goals.append(newRandom) + goals_from_genetic = genetic(genetic_goals, AGENT_MAP).genes + goals_from_genetic.append((0, 0)) + print("GOALS", goals_from_genetic) + coord_goals.append((0, 0)) else: coord_goals.append((8, 0)) coord_goals.append((0, 0)) + goals_from_genetic = [] + goals_from_genetic.append((8, 0)) + goals_from_genetic.append((0, 0)) - agent.goal = coord_goals.pop(0) + #agent.goal = coord_goals.pop(0) + agent.goal = goals_from_genetic.pop(0) agent.goal_achieved = False agent.path = a_star_search((agent.pos_coord[1], agent.pos_coord[0]), (agent.goal[1], agent.goal[0]), @@ -432,6 +452,8 @@ while running: screen.blit(agent.image, agent.rect) for package in Package_list: screen.blit(package.image, package.rect) + for gate in gate_list: + screen.blit(GATE, (gate[0] * size, gate[1] * size)) time.sleep(0.05)