From 1fd7a90fd1b0960d8f0643999c7bdd07da877216 Mon Sep 17 00:00:00 2001 From: kkhrystsenka Date: Tue, 25 Jun 2024 06:57:55 +0200 Subject: [PATCH] Added genetic algorithm --- ai-wozek/.idea/misc.xml | 2 +- ai-wozek/.idea/vcs.xml | 6 + ai-wozek/.idea/wozek.iml | 2 +- ai-wozek/__pycache__/classes.cpython-312.pyc | Bin 0 -> 4433 bytes ai-wozek/wozek.py | 169 +++++++++++++++---- 5 files changed, 146 insertions(+), 33 deletions(-) create mode 100644 ai-wozek/.idea/vcs.xml create mode 100644 ai-wozek/__pycache__/classes.cpython-312.pyc diff --git a/ai-wozek/.idea/misc.xml b/ai-wozek/.idea/misc.xml index c44baca..f47cba7 100644 --- a/ai-wozek/.idea/misc.xml +++ b/ai-wozek/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/ai-wozek/.idea/vcs.xml b/ai-wozek/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/ai-wozek/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ai-wozek/.idea/wozek.iml b/ai-wozek/.idea/wozek.iml index efbf1b4..acbca30 100644 --- a/ai-wozek/.idea/wozek.iml +++ b/ai-wozek/.idea/wozek.iml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/ai-wozek/__pycache__/classes.cpython-312.pyc b/ai-wozek/__pycache__/classes.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..577d6dd8a15273ef48518ea00e1bdc143a805227 GIT binary patch literal 4433 zcmcIn-D@1z6~A|OW_R{W*4p}7D^6CHiaKs01;uZr5OnN>>nJ_n}B7DRrJA?;5_9I=!NfCR&re#{B z)aMDsm_XhlMr?@~;%&j-RTMc-0$$t{Z^r_z#JLIJ%5B^@=O%%hYU3t2Hx1lO8&~Gs zEO2`wT}jT{2fW^hm#R}G_it1?qfk#Q+0~1>e+i$`V6r^~gH>XZA~i@+Fz6B~#tZ?d zSdS^9CrxRrRMk05!4~{P{GjdM@~utUBxr5+XOyHDpEs@2yz5DqEyJDnB*Uyh7r*Rtw_n|%jc;=Ae114GcI!Y*J2U4E=3 zK9Gkt`(FT=Oeiz(VoO}fZo?@=kBkKqG!8fI$G}}BO|pO@9nGMZz6&4ysvDWo5N-#j zT%~Sg(uK%?y9X>FnjNi4!`E!SxbOiVhKsZY90vnrEwOe~)UwjVi}ASy4^Y|Cxz_np6;$Aj&C z5QP9p@4J3#`PACb{q)FIuK(`9#71tib!KZYzgqu8{n6m~y}|Kyabxh6)|r**&1~-a z?DFi|oAOnLi8(uZM$nOJW5OWFtrpBf%rR zY@kv%ZCh1uQT9FHI+)geLI!N|ftGe!f^os}bsm-ARJXTrWtz>;*Uq(d} zxUbD5uObu4C@w@MiAf`m2@roLu0MxKq;r_zzLf~^B%VE$*e?DIQ4M0FE8raKt})TW zFB)NthUyX#rJL?LV0`SG!95NKFeGUAU2p{i7l;oou0IF3GNkvK##~1aG6@{lmVxja zI(!{U$nL(*{n<;f0C3T9LYXFvk+o8TZ?Eug!(miqM<{DQ5u4UXQ)Be(a-x zhw>X=@3gg0;E;>T$Nq2tvOeZ(k_VN zI0nC9-`?81P8dch{2!3uB{J>c5oT`!v;7U`nV^vi6+|Flusc}5!OPnZrRPeD-+l%X zNCCJV8I_G958pvQf1bt>5_E9~FS10o1u6~uGPu$mf^YhVa$z27_3kJX;7}-I_xwXC zL0P-|4<*Dz@MImbUa89JP^q|P*$L5^f-{~*r-y5ep!q%uVPyi)1lg;9FhXe0<)Tc! z$uH-IriN>}ktxIfaqM`LF0{u6?7;?gU>7d0O<#aD)X~wtzVgP((Z#gR8@%px0V|G< z_8$EA?XLMf^5>`u=T&HIrjee~D&uZJGmMjkM(;#{BUZ4S!d#V|EGP*tWjR&_{)<&~ z)30_AYIX*Q7uRYvvtlrO(s>??3Px@l#3?KoWl*3Zw-MMRoc{oXoby1SBuMw)Fy24= zAbt3z`{C6OuHF$p&3=--KYn&I(|dh-dHPZ2(7nu|HREAs^k13Wjq^9f50f7x*M4*N z$jLj$K0W=(={u8m_fJ2}oDUqnYYD-AikI#1`X3_?$?NdrSrn@{K^oeYMd@wo`#!EK zX?750V?aEqvRJOwSsodfpm^QEUpk(Vc|PH>#EQX9HW$e zMzVh={hyKjPsBlb@N)uW=V*+Mw#*#@-A+oRBR7uk5a@O?F*?#Zi~NzDlt53k7Iz4A XPh^1(e-5MJCvuX$O}`*W`Ir0`m~2b= literal 0 HcmV?d00001 diff --git a/ai-wozek/wozek.py b/ai-wozek/wozek.py index 9983292..afd08aa 100644 --- a/ai-wozek/wozek.py +++ b/ai-wozek/wozek.py @@ -1,8 +1,5 @@ import pygame import sys -import random -import os -import time from collections import deque import heapq import torch @@ -11,7 +8,6 @@ from classes import * import numpy as np import pandas as pd import torchvision.transforms as transforms -import math from PIL import Image class Node(): @@ -385,7 +381,7 @@ tree_data_base = pd.read_csv('paczki.csv') def entropy(data): labels = data.iloc[:, -1] # Ostatnia kolumna zawiera etykiety klas i pomija 1 wiersz bo jest tytulowy counts = labels.value_counts() #tu zlicza wszystkie opcje - probabilities = counts / len(labels) + probabilities = counts / len(labels) entropy = -sum(probabilities * np.log2(probabilities)) return entropy @@ -400,11 +396,143 @@ def information_gain(data, attribute): return (total_entropy - weighted_entropy) - +# Define constants +POPULATION_SIZE = 100 +GENERATIONS = 50 +MUTATION_RATE = 0.1 + +# Define movements +MOVES = ['UP', 'DOWN', 'LEFT', 'RIGHT'] + + +# Fitness function +def fitness(path, start, goal, obstacles, center): + position = start[:] + for move in path: + if move == 'UP': + position[1] -= 1 + elif move == 'DOWN': + position[1] += 1 + elif move == 'LEFT': + position[0] -= 1 + elif move == 'RIGHT': + position[0] += 1 + + # If we reach an obstacle + if position in obstacles: + return 0 + + # If we reach the goal + if position == goal: + break + + # Calculate fitness based on distance from center + distance_from_center = abs(center[0] - goal[0]) + abs(center[1] - goal[1]) + + # We want to maximize distance from center + return distance_from_center + + +# Generate initial population +def generate_initial_population(): + return [[random.choice(MOVES) for _ in range(50)] for _ in range(POPULATION_SIZE)] + + +# Selection +def selection(population, fitnesses): + selected = random.choices(population, weights=fitnesses, k=POPULATION_SIZE // 2) + return selected + + +# Crossover +def crossover(parent1, parent2): + crossover_point = random.randint(0, len(parent1)) + return parent1[:crossover_point] + parent2[crossover_point:] + + +# Mutation +def mutate(path): + if random.random() < MUTATION_RATE: + index = random.randint(0, len(path) - 1) + path[index] = random.choice(MOVES) + return path + + +# Genetic Algorithm +def genetic_algorithm(start, goal, obstacles, center): + population = generate_initial_population() + + for generation in range(GENERATIONS): + fitnesses = [fitness(path, start, goal, obstacles, center) for path in population] + population = selection(population, fitnesses) + new_population = [] + + for i in range(0, len(population), 2): + if i + 1 < len(population): + child1 = crossover(population[i], population[i + 1]) + child2 = crossover(population[i + 1], population[i]) + new_population.append(mutate(child1)) + new_population.append(mutate(child2)) + + population = new_population + + best_path = max(population, key=lambda p: fitness(p, start, goal, obstacles, center)) + return best_path + +def find_best_destination(freight, current_position, obstacles, center): + if freight.content != 'car_parts': + img = freight.image + image = Image.open(img).convert("RGB") + tensor = transform(image).unsqueeze(0) + with torch.no_grad(): + tensor = tensor.to(device) + outputs = model(tensor) + probabilities = torch.nn.functional.softmax(outputs, dim=1) + score = probabilities.cpu().numpy().flatten() + + best_goal = None + + if score[0] > score[1] and score[0] > score[2]: + print("flammable") + best_goal, best_path = find_best_position_with_ga(current_position, sorted(free_lime), obstacles, center) + free_lime.remove(best_goal) + elif score[1] > score[0] and score[1] > score[2]: + print("fragile") + best_goal, best_path = find_best_position_with_ga(current_position, sorted(free_pink), obstacles, center) + free_pink.remove(best_goal) + elif score[2] > score[0] and score[2] > score[1]: + print("toxic") + best_goal, best_path = find_best_position_with_ga(current_position, sorted(free_red), obstacles, center) + free_red.remove(best_goal) + else: + best_goal, best_path = find_best_position_with_ga(current_position, sorted(free_cyan), obstacles, center) + free_cyan.remove(best_goal) + + return best_goal + + +def find_best_position_with_ga(current_position, goal_positions, obstacles, center): + best_path = None + best_score = float('-inf') # Мы ищем максимальное значение + best_goal = None + + for goal in goal_positions: + path = genetic_algorithm(current_position, goal, obstacles, center) + score = fitness(path, current_position, goal, obstacles, center) + if score > best_score: + best_score = score + best_path = path + best_goal = goal + + return best_goal, best_path + + # Main game loop def game_loop(): init_game() + obstacles = [] + center = [GRID_WIDTH // 2, GRID_HEIGHT // 2] current=Node(forklift_pos,rotation,'start',None,0) dest=current_freight.pop() final=Node([dest[0],dest[1]],'N','final',None,0) @@ -442,32 +570,11 @@ def game_loop(): reset_truck_bed_freight() if(forklift_pos==final.position): handle_freight() - destination=[] + obstacles.append(final.position) if carrying_freight: - if(carried_freight.content!='car_parts'): - img=carried_freight.image - image=Image.open(img).convert("RGB") - tensor=transform(image).unsqueeze(0) - with torch.no_grad(): - tensor = tensor.to(device) - outputs = model(tensor) - probabilities = torch.nn.functional.softmax(outputs, dim=1) - score=probabilities.cpu().numpy().flatten() - if(score[0]>score[1] and score[0]>score[2]): - print("flammable") - destination=free_lime.pop() - elif(score[1]>score[0] and score[1]>score[2]): - print("fragile") - destination=free_pink.pop() - elif(score[2]>score[0] and score[2]>score[1]): - print("toxic") - destination=free_red.pop() - else: - destination=free_cyan.pop() - - #return probabilities.cpu().numpy().flatten() + destination = find_best_destination(carried_freight, forklift_pos, obstacles, center) print(destination) - final=Node([destination[0],destination[1]],'N','final',None,0) + final = Node([destination[0],destination[1]],'N','final',None,0) else: destination=current_freight.pop() print(destination) @@ -489,7 +596,7 @@ def game_loop(): rotate_forklift('R') load_images() i=i+1 - pygame.time.wait(500) + pygame.time.wait(100) pygame.quit() sys.exit()