From 3193a8853ae27df627ff0c91e3f25f3c40c9b70a Mon Sep 17 00:00:00 2001 From: Gasper Spagnolo Date: Wed, 9 Nov 2022 22:27:52 +0100 Subject: [PATCH] Make a python class rather.. --- a1/code/main.py | 234 +++++++++++++++++++++--------------------------- 1 file changed, 104 insertions(+), 130 deletions(-) diff --git a/a1/code/main.py b/a1/code/main.py index 5af0e089..4e4fe603 100644 --- a/a1/code/main.py +++ b/a1/code/main.py @@ -1,113 +1,93 @@ import pygad import numpy as np -global punish_matrix -global start_pos -global end_pos -global shortest_path - -def walk_through_maze(solution_matrix): - global punish_matrix, start_pos, end_pos, maze - solution_matrix = solution_matrix.reshape((len(maze), len(maze))) - - queue = [[start_pos]] - - def add_to_queue(full_path, x, y): - if (x,y) not in full_path: - full_path.append((x, y)) - queue.append(full_path) - - while queue != []: - full_path = queue.pop() - x, y = full_path[-1] - if(maze[x][y] == 'E'): - return len(full_path) - if x + 1 < len(maze) : - if solution_matrix[x+1, y] == 1: - add_to_queue(full_path, x+1, y) - if x - 1 >= 0: - if solution_matrix[x-1, y] == 1: - add_to_queue(full_path, x-1, y) - if y + 1 < len(maze) : - if solution_matrix[x, y+1] == 1: - add_to_queue(full_path, x, y+1) - if y - 1 >= 0: - if solution_matrix[x, y-1] == 1: - add_to_queue(full_path, x, y-1) - return 42069 - +# Create a maze class +global maze_ix def fitness_func(path, solution_idx): - global punish_matrix, start_pos, end_pos, shortest_path - - punish = np.sum(path * punish_matrix.reshape(-1)) - print('Matrix multiplication', punish) - - # chekc if path is valied from start to end - path = path.reshape(len(punish_matrix), len(punish_matrix)) + maze = mazes[maze_ix] + fitness = np.sum(path * maze.punish_matrix.reshape(-1)) + print('After matrix multiplication', fitness) + path = path.reshape(maze.punish_matrix.shape) - if path[start_pos] == 0: - punish -= 1000 - if path[end_pos] == 0: - punish -= 1000 - if path[start_pos] == 1 and path[end_pos] == 1: - walk = walk_through_maze(path) - if walk < shortest_path: - punish += 10000 - shortest_path = walk - return punish + if path[maze.start_pos] == 0: + fitness -= 10000 + if path[maze.end_pos] == 0: + fitness -= 10000 + if path[maze.start_pos] == 1 and path[maze.end_pos] == 1: + # Check if there is a valid path + complete_path = maze.walk_through_maze(path) + print('My complete path is', complete_path) + complete_path_len = len(complete_path) + if complete_path_len != 0 and complete_path_len < len(maze.shortest_path): + maze.shortest_path = complete_path + maze.adjust_weights(complete_path) + return fitness +class Maze: + def __init__(self, maze, start_pos, end_pos, punish_matrix, shortest_path): + self.maze = maze + self.start_pos = start_pos + self.end_pos = end_pos + self.punish_matrix = punish_matrix + self.shortest_path = shortest_path -def run_genetic_algorithm(m, pm, sp, ep): - # Set global punish matrix - global punish_matrix, start_pos, end_pos, maze, shortest_path - punish_matrix = pm - start_pos = sp - end_pos = ep - maze = m - shortest_path = len(maze) *2 + def run_genetic_algorithm(self): + # Set global punish matrix + punish_matrix = self.punish_matrix + maze = self.maze + + ga_instance = pygad.GA(num_genes=punish_matrix.size, + num_generations=1000, + sol_per_pop=2, + num_parents_mating=2, + gene_type=int, + fitness_func=fitness_func, + keep_parents=2, + allow_duplicate_genes=True, + gene_space=[0, 1]) + ga_instance.run() + ga_instance.plot_fitness() + + solution, solution_fitness, solution_idx = ga_instance.best_solution() + print("Parameters of the best solution : {solution}".format( + solution=solution)) + print(solution.reshape(len(maze), len(maze))) + print("Fitness value of the best solution = {solution_fitness}".format( + solution_fitness=solution_fitness)) - fitness_function = fitness_func - - num_generations = 500 - num_parents_mating = 4 - - sol_per_pop = 20 - num_genes = punish_matrix.size - - init_range_low = 0 - init_range_high = 1 - - parent_selection_type = "sss" - keep_parents = 1 - - crossover_type = "single_point" - - mutation_type = "random" - - ga_instance = pygad.GA(num_generations=num_generations, - num_parents_mating=num_parents_mating, - fitness_func=fitness_function, - sol_per_pop=sol_per_pop, - num_genes=num_genes, - init_range_low=init_range_low, - init_range_high=init_range_high, - parent_selection_type=parent_selection_type, - keep_parents=keep_parents, - crossover_type=crossover_type, - mutation_type=mutation_type, - mutation_num_genes=2, - gene_space=[0, 1]) - ga_instance.run() - - solution, solution_fitness, solution_idx = ga_instance.best_solution() - print("Parameters of the best solution : {solution}".format( - solution=solution)) - print(solution.reshape(len(maze), len(maze))) - print("Fitness value of the best solution = {solution_fitness}".format( - solution_fitness=solution_fitness)) + def walk_through_maze(self, solution_matrix): + queue = [[self.start_pos]] + + def add_to_queue(full_path, x, y): + if (x,y) not in full_path: + full_path.append((x, y)) + queue.append(full_path) + + while queue != []: + full_path = queue.pop() + x, y = full_path[-1] + if(self.maze[x][y] == 'E'): + return full_path # Adjust weights for the path :tipspepe: + if x + 1 < len(self.maze) : + if solution_matrix[x+1, y] == 1:# and maze[x+1][y] == ".": + add_to_queue(full_path, x+1, y) + if x - 1 >= 0: + if solution_matrix[x-1, y] == 1:# and maze[x-1][y] == ".": + add_to_queue(full_path, x-1, y) + if y + 1 < len(self.maze) : + if solution_matrix[x, y+1] == 1:# and maze[x][y+1] == ".": + add_to_queue(full_path, x, y+1) + if y - 1 >= 0: + if solution_matrix[x, y-1] == 1:# and maze[x][y-1] == ".": + add_to_queue(full_path, x, y-1) + return [] # You return an empty array bro! + def adjust_weights(self, found_path): + for (x, y) in found_path: + self.punish_matrix[x,y] += 100 + def read_mazes(): with open('./mazes.r', 'r') as f: mazes = [] @@ -122,48 +102,42 @@ def read_mazes(): def prepare_maze(maze_ix, mazes): maze = mazes[maze_ix] - punish_matrix_t = np.zeros((len(maze), len(maze)), dtype=np.int64) + punish_matrix = np.zeros((len(maze), len(maze)), dtype=np.int64) - start_index_t = 0, 0 - end_index_t = 0, 0 + start_index = 0, 0 + end_index = 0, 0 + treasures = [] + + # Initialize punish matrix and find start and end index for i, x in enumerate(maze): for j, y in enumerate(x): if y == "#": - punish_matrix_t[i, j] = -300 + punish_matrix[i, j] = -300 if y == ".": - punish_matrix_t[i, j] = +200 + punish_matrix[i, j] = +200 if y == "S": - start_index_t = i, j + start_index = i, j if y == "E": - end_index_t = i, j + end_index = i, j + if y == "T": + treasures.append((i, j)) + + # Create maze class + maze = Maze(maze, start_index, end_index, punish_matrix, []) + + return maze - return maze, punish_matrix_t, start_index_t, end_index_t - -def print_maze(maze): - for row in maze: - print(row) - def main(): # Read mazes - mazes = read_mazes() + global maze_ix, mazes + mazes = [] + text_mazes = read_mazes() for i in range(1): - maze, punish_matrix_t, start_index_t, end_index_t = prepare_maze(1, mazes) - run_genetic_algorithm(maze, punish_matrix_t, start_index_t, end_index_t) - print_maze(maze) + maze_ix = i + maze = prepare_maze(1, text_mazes) + mazes.append(maze) + maze.run_genetic_algorithm() if __name__ == "__main__": - main() - -""" - mutascija -> nesme mutirati u zid - -> more mutirat v start ce tam ni poti - -> more mutirat v end ce tam ni poti - -> ce je na zidu enka mutiri v 0 - tresure kdr bo - - crossover -> - malo z weights - - TRESURE -> spremeni fitrnes mutacijo in crossover -""" + main()