From 0becd1b1f6932e873ed1ea31087d74e7769ef939 Mon Sep 17 00:00:00 2001 From: Mateusz Czajka Date: Thu, 6 Jun 2024 08:35:36 +0200 Subject: [PATCH 1/7] Made genetic algorithm and made a field using it. --- GeneticAlgorithm.py | 208 ++++++++++++++++++++++++++ pole_pop120_iter2500_True.json | 266 +++++++++++++++++++++++++++++++++ 2 files changed, 474 insertions(+) create mode 100644 GeneticAlgorithm.py create mode 100644 pole_pop120_iter2500_True.json diff --git a/GeneticAlgorithm.py b/GeneticAlgorithm.py new file mode 100644 index 0000000..3352824 --- /dev/null +++ b/GeneticAlgorithm.py @@ -0,0 +1,208 @@ +import copy +import json +import random +from displayControler import NUM_X, NUM_Y + +# Definiowanie stałych dla roślin i plonów +plants = ['corn', 'potato', 'tomato', 'carrot'] +initial_yields = {'corn': 38, 'potato': 40, 'tomato': 43, 'carrot': 45} +yield_reduction = { + 'corn': {'corn': -4.5, 'potato': -3, 'tomato': -7, 'carrot': -7}, + 'potato': {'corn': -7, 'potato': -5, 'tomato': -10, 'carrot': -6}, + 'tomato': {'corn': -4, 'potato': -5, 'tomato': -7, 'carrot': -7}, + 'carrot': {'corn': -11, 'potato': -5, 'tomato': -4, 'carrot': -7} +} +yield_multiplier = {'corn': 1.25, 'potato': 1.17, 'tomato': 1.22, 'carrot': 1.13} + + +# Generowanie listy 20x12 z losowo rozmieszczonymi roślinami +def generate_garden(rows=20, cols=12): + return [[random.choice(plants) for _ in range(cols)] for _ in range(rows)] + + +# Funkcja do obliczania liczby plonów +def calculate_yields(garden): + rows = len(garden) + cols = len(garden[0]) + + total_yields = 0 + + for i in range(rows): + for j in range(cols): + plant = garden[i][j] + yield_count = initial_yields[plant] + + # Sprawdzanie sąsiadów + neighbors = [ + (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1) + ] + + for ni, nj in neighbors: + if 0 <= ni < rows and 0 <= nj < cols: + neighbor_plant = garden[ni][nj] + yield_count += yield_reduction[plant][neighbor_plant] + + yield_count *= yield_multiplier[plant] + total_yields += yield_count + + return total_yields + + +# Funkcja do generowania planszy/ogrodu i zapisywania go jako lista z liczbą plonów +def generate_garden_with_yields(rows=NUM_Y, cols=NUM_X): + garden = generate_garden(rows, cols) + total_yields = calculate_yields(garden) + return [garden, total_yields] + + +# Funkcja do generowania linii cięcia i zapisywania jej jako liczba roślin w kolumnie z pierwszej planszy/ogrodu +def line(): + path = [] + flag = False + x = random.randint(4, 8) + position = (0, x) + path.append(position) + while not flag: # wybór punktu dopóki nie wybierze się skrajnego + # prawdopodobieństwo "ruchu" -> 0.6: w prawo, 0.2: w góre, 0.2: w dół + p = [(position[0] + 1, position[1]), (position[0], position[1] + 1), (position[0], position[1] - 1)] + w = [0.6, 0.2, 0.2] + position2 = random.choices(p, w)[0] + if position2 not in path: # sprawdzenie czy dany punkt nie był już wybrany aby nie zapętlać się + path.append(position2) + position = position2 + if position[0] == NUM_X or position[1] == 0 or position[1] == NUM_Y: # sprawdzenie czy osiągnięto skrajny punkt + flag = True + info = [] # przeformatowanie sposobu zapisu na liczbę roślin w kolumnie, które będzię się dzidziczyło z pierwszej planszy/ogrodu + for i in range(len(path) - 1): + if path[i + 1][0] - path[i][0] == 1: + info.append(NUM_Y - path[i][1]) + if len(info) < NUM_X: # uzupełnienie informacji o dziedziczeniu z planszy/ogrodu + if path[-1:][0][1] == 0: + x = NUM_Y + else: + x = 0 + while len(info) < NUM_X: + info.append(x) + # return path, info + return info + + +# Funkcja do generowania potomstwa +def divide_gardens(garden1, garden2): + info = line() + new_garden1 = [[] for _ in range(NUM_Y)] + new_garden2 = [[] for _ in range(NUM_Y)] + for i in range(NUM_X): + for j in range(NUM_Y): + # do utworzonych kolumn w nowych planszach/ogrodach dodajemy dziedziczone rośliny + if j < info[i]: + new_garden1[j].append(garden1[j][i]) + new_garden2[j].append(garden2[j][i]) + else: + new_garden1[j].append(garden2[j][i]) + new_garden2[j].append(garden1[j][i]) + + return [new_garden1, calculate_yields(new_garden1)], [new_garden2, calculate_yields(new_garden2)] + + +# Funkcja do mutacji danej planszy/ogrodu +def mutation(garden, not_used): + new_garden = copy.deepcopy(garden) + for i in range(NUM_X): + x = random.randint(0, 11) # wybieramy, w którym wierszu w i-tej kolumnie zmieniamy roślinę na inną + other_plants = [plant for plant in plants if plant != new_garden[x][i]] + new_garden[x][i] = random.choice(other_plants) + return [new_garden, calculate_yields(new_garden)] + + +# Funkcja do generowania pierwszego pokolenia +def generate(n): + generation = [] + for i in range(n * 3): + generation.append(generate_garden_with_yields()) + generation.sort(reverse=True, key=lambda x: x[1]) + return generation[:n] + + +# Funkcja do implementacji ruletki (sposobu wyboru) - sumuje wszystkie plony generacji +def sum_yields(x): + s = 0 + for i in range(len(x)): + s += x[i][1] + return s + + +if __name__ == '__main__': + roulette = True + attemps = 150 + iterat = 2500 + population = 100 + best = [] + for a in range(attemps): + generation = generate(population) + print(generation[0][1]) + for i in range(iterat): # ile iteracji - nowych pokoleń + print(a, i) + new_generation = generation[:(population // 7)] # dziedziczenie x najlepszych osobników + j = 0 + while j < ( + population - ( + population // 7)): # dobór reszty osobników do pełnej liczby populacji danego pokolenia + if roulette: # zasada ruletki -> "2 rzuty kulką" + s = sum_yields(generation) # suma wszystkich plnów całego pokolenia + z = [] + if s == 0: # wtedy każdy osobnik ma takie same szanse + z.append(random.randint(0, population - 1)) + z.append(random.randint(0, population - 1)) + else: + weights = [] # wagi prawdopodobieństwa dla każdego osobnika generacji + pos = [] # numery od 0 do 49 odpowiadające numerom osobnikom w generacji + for i in range(population): + weights.append(generation[i][1] / s) + pos.append(i) + z.append(random.choices(pos, weights)[0]) # wybranie osobnika według wag prawdopodobieństwa + z.append(random.choices(pos, weights)[0]) # wybranie osobnika według wag prawdopodobieństwa + else: # metoda rankingu + z = random.sample(range(0, int(population // 1.7)), 2) + + # krzyzowanie 90% szans, mutacja 10% szans + function = [divide_gardens, mutation] + weight = [0.9, 0.1] + fun = random.choices(function, weight)[0] + h = fun(generation[z[0]][0], generation[z[1]][0]) + if len(h[0]) == 2: + new_generation.append(h[0]) + new_generation.append(h[1]) + j += 2 + else: + new_generation.append(h) + j += 1 + + new_generation.sort(reverse=True, key=lambda x: x[1]) # sortowanie malejąco listy według wartości plonów + generation = new_generation[:population] + + best.append(generation[0]) + + best.sort(reverse=True, key=lambda x: x[1]) + + # Zapis do pliku + # for i in range(len(best)): + # print(best[i][1], calculate_yields(best[i][0])) + # + # + # with open(f'pole_pop{population}_iter{iterat}_{roulette}.json', 'w') as file: # zapis planszy/ogrodu do pliku json + # json.dump(best[0][0], file, indent=4) + # + # print("Dane zapisane do pliku") + + # Odczyt z pliku + # with open(f'pole_pop{population}_iter{iterat}_{roulette}.json', 'r') as file: + # garden_data = json.load(file) + # + # print("Odczytane dane ogrodu:") + # for row in garden_data: + # print(row) + # + # print(calculate_yields(garden_data)) + # if best[0][0] == garden_data: + # print("POPRAWNE: ", calculate_yields(garden_data), calculate_yields(best[0][0])) diff --git a/pole_pop120_iter2500_True.json b/pole_pop120_iter2500_True.json new file mode 100644 index 0000000..62b9994 --- /dev/null +++ b/pole_pop120_iter2500_True.json @@ -0,0 +1,266 @@ +[ + [ + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "corn", + "corn", + "corn", + "corn", + "corn", + "corn", + "corn", + "tomato", + "carrot", + "tomato", + "carrot", + "potato", + "potato", + "carrot", + "potato" + ], + [ + "carrot", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "corn", + "corn", + "corn", + "corn", + "corn", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "carrot", + "potato", + "potato", + "potato" + ], + [ + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "corn", + "corn", + "corn", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "carrot", + "potato", + "carrot" + ], + [ + "carrot", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "corn", + "corn", + "corn", + "corn", + "corn", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato" + ], + [ + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "corn", + "corn", + "corn", + "corn", + "corn", + "tomato", + "corn", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "carrot" + ], + [ + "corn", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "corn", + "corn", + "corn", + "corn", + "corn", + "corn", + "corn", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato" + ], + [ + "corn", + "corn", + "tomato", + "corn", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "corn", + "corn", + "corn", + "corn", + "corn", + "potato", + "carrot", + "tomato", + "carrot", + "tomato", + "carrot" + ], + [ + "tomato", + "corn", + "corn", + "corn", + "corn", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "corn", + "corn", + "corn", + "corn", + "corn", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato" + ], + [ + "carrot", + "potato", + "corn", + "corn", + "corn", + "corn", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "corn", + "corn", + "corn", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "carrot" + ], + [ + "potato", + "potato", + "corn", + "corn", + "corn", + "corn", + "corn", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "corn", + "corn", + "corn", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato" + ], + [ + "potato", + "carrot", + "tomato", + "corn", + "tomato", + "corn", + "corn", + "corn", + "tomato", + "carrot", + "tomato", + "corn", + "corn", + "corn", + "corn", + "tomato", + "carrot", + "carrot", + "tomato", + "carrot" + ], + [ + "carrot", + "tomato", + "carrot", + "tomato", + "carrot", + "tomato", + "corn", + "tomato", + "carrot", + "tomato", + "corn", + "corn", + "tomato", + "corn", + "tomato", + "carrot", + "tomato", + "tomato", + "carrot", + "tomato" + ] +] \ No newline at end of file -- 2.20.1 From 51a5b13669b8cdf1df51dfed0fddb95f9d59ac7d Mon Sep 17 00:00:00 2001 From: tafit0902 Date: Fri, 7 Jun 2024 00:02:36 +0200 Subject: [PATCH 2/7] ladowanie pola z pliku GA, rozpoznawanie zdjec na polu, decyzja o podlaniu --- App.py | 23 +++++++++++++++++++---- Drzewo.py | 2 +- Image.py | 22 ++++++++++++++++++++++ Pole.py | 8 ++++++++ Slot.py | 7 +++++++ Tractor.py | 24 +++++++++++++++++++----- neuralnetwork.py | 2 +- 7 files changed, 77 insertions(+), 11 deletions(-) diff --git a/App.py b/App.py index 591e937..efc84f6 100644 --- a/App.py +++ b/App.py @@ -10,6 +10,7 @@ import Ui import BFS import AStar import neuralnetwork +import json bfs1_flag=False @@ -20,8 +21,9 @@ Astar2 = False if bfs3_flag or Astar or Astar2: Pole.stoneFlag = True TreeFlag=False -nnFlag=True +nnFlag=False newModel=False +finalFlag = True pygame.init() show_console=True @@ -43,7 +45,15 @@ def init_demo(): #Demo purpose old_info="" traktor.draw_tractor() time.sleep(2) - pole.randomize_colors(nnFlag) + if not finalFlag: + pole.randomize_colors(nnFlag) + else: + population = 120 + iterat = 2500 + roulette = True + with open(f'pole_pop{population}_iter{iterat}_{roulette}.json', 'r') as file: + garden_data = json.load(file) + pole.setPlantsByList(garden_data) traktor.draw_tractor() start_flag=True while True: @@ -128,11 +138,16 @@ def init_demo(): #Demo purpose print_to_console("sieć nuronowa nauczona") print('model został wygenerowany') else: - model = neuralnetwork.loadModel('model.pth') + model = neuralnetwork.loadModel('model_500_hidden.pth') print_to_console("model został załądowny") testset = neuralnetwork.getDataset(False) print(neuralnetwork.accuracy(model, testset)) - traktor.snake_move_predict_plant(pole, model) + traktor.snake_move_predict_plant(pole, model, headers=['Coords','Real plant','Predicted plant','Result','Fertilizer'], actions=[traktor.fertilize_slot]) + if(finalFlag): + pass + model = neuralnetwork.loadModel('model_500_hidden.pth') + Tractor.drzewo.treeLearn() + traktor.snake_move_predict_plant(pole, model, headers=['Coords','Real plant','Predicted plant','Result','Decision'], actions=[traktor.irigate_slot_NN]) start_flag=False # demo_move() old_info=get_info(old_info) diff --git a/Drzewo.py b/Drzewo.py index 71b82c6..a3e0ae2 100644 --- a/Drzewo.py +++ b/Drzewo.py @@ -8,7 +8,7 @@ class Drzewo: self.tree=self.treeLearn() def treeLearn(self): - csvdata=pandas.read_csv('Data/dataTree.csv') + csvdata=pandas.read_csv('Data/dataTree2.csv') #csvdata = pandas.read_csv('Data/dataTree2.csv') x=csvdata[atributes] decision=csvdata['action'] diff --git a/Image.py b/Image.py index 90fefca..f296c7f 100644 --- a/Image.py +++ b/Image.py @@ -80,3 +80,25 @@ def getRandomImageFromDataBase(): image = pygame.image.load(imgPath) image=pygame.transform.scale(image,(dCon.CUBE_SIZE,dCon.CUBE_SIZE)) return image, label, imgPath + +def getSpedifiedImageFromDatabase(label): + folderPath = f"dataset/test/{label}" + files = os.listdir(folderPath) + random_image = random.choice(files) + imgPath = os.path.join(folderPath, random_image) + + while imgPath in imagePathList: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + quit() + label = random.choice(neuralnetwork.labels) + folderPath = f"dataset/test/{label}" + files = os.listdir(folderPath) + random_image = random.choice(files) + imgPath = os.path.join(folderPath, random_image) + + imagePathList.append(imgPath) + + image = pygame.image.load(imgPath) + image=pygame.transform.scale(image,(dCon.CUBE_SIZE,dCon.CUBE_SIZE)) + return image, label, imgPath diff --git a/Pole.py b/Pole.py index f8e6aa3..32ac0d2 100644 --- a/Pole.py +++ b/Pole.py @@ -62,6 +62,14 @@ class Pole: continue else: self.slot_dict[coordinates].set_random_plant(nn) + def setPlantsByList(self, plantList): + pygame.display.update() + time.sleep(3) + for coordinates in self.slot_dict: + if(coordinates==(0,0)): + continue + else: + self.slot_dict[coordinates].set_specifided_plant(plantList[coordinates[1]][coordinates[0]]) def change_color_of_slot(self,coordinates,color): #Coordinates must be tuple (x,y) (left top slot has cord (0,0) ), color has to be from defined in Colors.py or custom in RGB value (R,G,B) self.get_slot_from_cord(coordinates).color_change(color) diff --git a/Slot.py b/Slot.py index 69a971a..ede1309 100644 --- a/Slot.py +++ b/Slot.py @@ -49,6 +49,11 @@ class Slot: # print(self.plant_image) self.plant=Roslina.Roslina(self.label) self.set_image() + + def set_specifided_plant(self, plant): + self.plant_image, self.label, self.imagePath = self.specified_plant_dataset(plant) + self.plant=Roslina.Roslina(self.label) + self.set_image() def set_image(self): if self.plant_image is None: @@ -75,6 +80,8 @@ class Slot: return self.image_loader.return_random_plant() def random_plant_dataset(self): return Image.getRandomImageFromDataBase() + def specified_plant_dataset(self, plant): + return Image.getSpedifiedImageFromDatabase(plant) def return_plant(self): return self.plant diff --git a/Tractor.py b/Tractor.py index b135b08..e68cc35 100644 --- a/Tractor.py +++ b/Tractor.py @@ -30,6 +30,7 @@ class Tractor: DIRECTION_SOUTH = 'S' DIRECTION_WEST = 'W' DIRECTION_EAST = 'E' + def __init__(self,slot,screen, osprzet,clock,bfs2_flag): self.tractor_images = { Tractor.DIRECTION_NORTH: pygame.transform.scale(pygame.image.load('images/traktorN.png'), @@ -193,8 +194,7 @@ class Tractor: self.turn_left() print("podlanych slotów: ", str(counter)) - def snake_move_predict_plant(self, pole, model): - headers=['Coords','Real plant','Predicted plant','Result','Fertilizer'] + def snake_move_predict_plant(self, pole, model, headers, actions = None): print(format_string_nn.format(*headers)) initPos = (self.slot.x_axis, self.slot.y_axis) count = 0 @@ -207,9 +207,11 @@ class Tractor: predictedLabel = nn.predictLabel(self.slot.imagePath, model) #print(str("Coords: ({:02d}, {:02d})").format(self.slot.x_axis, self.slot.y_axis), "real:", self.slot.label, "predicted:", predictedLabel, "correct" if (self.slot.label == predictedLabel) else "incorrect", 'nawożę za pomocą:', nn.fertilizer[predictedLabel]) - print(format_string_nn.format(f"{self.slot.x_axis,self.slot.y_axis}",self.slot.label,predictedLabel,"correct" if (self.slot.label == predictedLabel) else "incorrect",nn.fertilizer[predictedLabel])) + # print(format_string_nn.format(f"{self.slot.x_axis,self.slot.y_axis}",self.slot.label,predictedLabel,"correct" if (self.slot.label == predictedLabel) else "incorrect",nn.fertilizer[predictedLabel])) + for a in actions: + a(predictedLabel) if self.slot.label != predictedLabel: - self.slot.mark_visited() + # self.slot.mark_visited() count += 1 self.move_forward(pole, False) if i % 2 == 0 and i != dCon.NUM_Y - 1: @@ -220,7 +222,19 @@ class Tractor: self.turn_left() self.move_forward(pole, False) self.turn_left() - print(f"Dobrze nawiezionych roślin: {20*12-count}, źle nawiezionych roślin: {count}") + print(f"Dobrze rozpoznanych roślin: {20*12-count}, źle rozpoznanych roślin: {count}") + + def fertilize_slot(self, predictedLabel): + print(format_string_nn.format(f"{self.slot.x_axis,self.slot.y_axis}",self.slot.label,predictedLabel,"correct" if (self.slot.label == predictedLabel) else "incorrect",nn.fertilizer[predictedLabel])) + if self.slot.label != predictedLabel: + self.slot.mark_visited() + + def irigate_slot_NN(self, predictedLabel): + attributes=self.get_attributes() + decision = drzewo.makeDecision(attributes) + print(format_string_nn.format(f"{self.slot.x_axis,self.slot.y_axis}",self.slot.label,predictedLabel,"correct" if (self.slot.label == predictedLabel) else "incorrect",decision)) + condition.cycle() + self.waterLevel = random.randint(0, 100) def snake_move(self,pole,x,y): next_slot_coordinates=(x,y) diff --git a/neuralnetwork.py b/neuralnetwork.py index 568abaf..09a369f 100644 --- a/neuralnetwork.py +++ b/neuralnetwork.py @@ -77,7 +77,7 @@ def saveModel(model, path): def loadModel(path): print("Loading model") model = getModel() - model.load_state_dict(torch.load(path)) + model.load_state_dict(torch.load(path, map_location=torch.device('cpu'))) # musiałem tutaj dodać to ładowanie z mapowaniem na cpu bo u mnie CUDA nie działa wy pewnie możecie to usunąć return model def trainNewModel(n_iter=100, batch_size=256): -- 2.20.1 From 4339284c4b965ff2847eac37cc682555a3ba622d Mon Sep 17 00:00:00 2001 From: jakzar Date: Fri, 7 Jun 2024 15:01:15 +0200 Subject: [PATCH 3/7] This: -changed label for decision -changed goaltressure for BFS3 --- App.py | 2 +- BFS.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/App.py b/App.py index efc84f6..2b8203c 100644 --- a/App.py +++ b/App.py @@ -147,7 +147,7 @@ def init_demo(): #Demo purpose pass model = neuralnetwork.loadModel('model_500_hidden.pth') Tractor.drzewo.treeLearn() - traktor.snake_move_predict_plant(pole, model, headers=['Coords','Real plant','Predicted plant','Result','Decision'], actions=[traktor.irigate_slot_NN]) + traktor.snake_move_predict_plant(pole, model, headers=['Coords','Real plant','Predicted plant','Result','Water decision'], actions=[traktor.irigate_slot_NN]) start_flag=False # demo_move() old_info=get_info(old_info) diff --git a/BFS.py b/BFS.py index 4324471..df72500 100644 --- a/BFS.py +++ b/BFS.py @@ -133,8 +133,12 @@ def check3(tab, state): return True -def BFS3(istate): - goalTreassuere = (random.randint(0,NUM_X-1), random.randint(0,NUM_Y-1)) +def BFS3(istate,GT): + randomGT=True + if(randomGT==True): + goalTreassuere = (random.randint(0,NUM_X-1), random.randint(0,NUM_Y-1)) + else: + goalTreassuere=GT print(goalTreassuere) fringe = [] explored = [] -- 2.20.1 From da1bfe1d8f24d5afb8ad0960bef4ac730af4b9f2 Mon Sep 17 00:00:00 2001 From: jakzar Date: Fri, 7 Jun 2024 15:29:26 +0200 Subject: [PATCH 4/7] This: -changed readme.txt --- readme.txt | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index 1cbea52..d22a68a 100644 --- a/readme.txt +++ b/readme.txt @@ -4,4 +4,21 @@ Required packages: pip install pygame pip install matplotlib pip install scikit-learn - pip install pandas \ No newline at end of file + pip install pandas +How to run: + For BFS3: + -in App.py change bfs3_flag to True (other flags need to be disabled) + -in Image.py change range in function return_random_plant to (0,5) + For Astar: + in App.py change Astar to True (other flags need to be disabled) + -in Image.py change range in function return_random_plant to (0,7) + For Astar2: + -in App.py change Astar2 flag to True (other flags need to be disabled) + -in Image.py change range in function return_random_plant to (0,7) + For Tree: + -in App.py change TreeFlag to True (other flags need to be disabled) + -in Image.py change range in function return_random_plant to (0,5) + For neuralnetwork: + -in App.py change nnFlag to True (other flags need to be disabled) + For final_show (neuralnetwork+tree+genetic algorithm) + -in App.py change finalFlag to True (other flags need to be disabled) \ No newline at end of file -- 2.20.1 From 6c86eebd89c062d6487779c926f619021316136f Mon Sep 17 00:00:00 2001 From: Paulina Smierzchalska Date: Fri, 7 Jun 2024 18:41:55 +0200 Subject: [PATCH 5/7] genetic algorithm 2 with a value of None --- GeneticAlgorithm2.py | 210 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 GeneticAlgorithm2.py diff --git a/GeneticAlgorithm2.py b/GeneticAlgorithm2.py new file mode 100644 index 0000000..e3972d5 --- /dev/null +++ b/GeneticAlgorithm2.py @@ -0,0 +1,210 @@ +import copy +import json +import random +from displayControler import NUM_X, NUM_Y + +# Definiowanie stałych dla roślin i plonów +plants = ['corn', 'potato', 'tomato', 'carrot'] +initial_yields = {'corn': 38, 'potato': 40, 'tomato': 43, 'carrot': 45} +yield_reduction = { + 'corn': {'corn': -4.5, 'potato': -3, 'tomato': -7, 'carrot': -7}, + 'potato': {'corn': None, 'potato': -5, 'tomato': -10, 'carrot': -6}, + 'tomato': {'corn': None, 'potato': -5, 'tomato': -7, 'carrot': -7}, + 'carrot': {'corn': None, 'potato': -5, 'tomato': -4, 'carrot': -7} +} +yield_multiplier = {'corn': 1.25, 'potato': 1.17, 'tomato': 1.22, 'carrot': 1.13} + + +# Generowanie listy 20x12 z losowo rozmieszczonymi roślinami +def generate_garden(rows=20, cols=12): + return [[random.choice(plants) for _ in range(cols)] for _ in range(rows)] + + +# Funkcja do obliczania liczby plonów +def calculate_yields(garden): + rows = len(garden) + cols = len(garden[0]) + + total_yields = 0 + + for i in range(rows): + for j in range(cols): + plant = garden[i][j] + yield_count = initial_yields[plant] + + # Sprawdzanie sąsiadów + neighbors = [ + (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1) + ] + + for ni, nj in neighbors: + if 0 <= ni < rows and 0 <= nj < cols: + neighbor_plant = garden[ni][nj] + + if yield_reduction[plant][neighbor_plant] is not None: #jeśli jest wartość None to nie zostaje wcale dodane + yield_count += yield_reduction[plant][neighbor_plant] + + yield_count *= yield_multiplier[plant] + total_yields += yield_count + + return total_yields + + +# Funkcja do generowania planszy/ogrodu i zapisywania go jako lista z liczbą plonów +def generate_garden_with_yields(rows=NUM_Y, cols=NUM_X): + garden = generate_garden(rows, cols) + total_yields = calculate_yields(garden) + return [garden, total_yields] + + +# Funkcja do generowania linii cięcia i zapisywania jej jako liczba roślin w kolumnie z pierwszej planszy/ogrodu +def line(): + path = [] + flag = False + x = random.randint(4, 8) + position = (0, x) + path.append(position) + while not flag: # wybór punktu dopóki nie wybierze się skrajnego + # prawdopodobieństwo "ruchu" -> 0.6: w prawo, 0.2: w góre, 0.2: w dół + p = [(position[0] + 1, position[1]), (position[0], position[1] + 1), (position[0], position[1] - 1)] + w = [0.6, 0.2, 0.2] + position2 = random.choices(p, w)[0] + if position2 not in path: # sprawdzenie czy dany punkt nie był już wybrany aby nie zapętlać się + path.append(position2) + position = position2 + if position[0] == NUM_X or position[1] == 0 or position[1] == NUM_Y: # sprawdzenie czy osiągnięto skrajny punkt + flag = True + info = [] # przeformatowanie sposobu zapisu na liczbę roślin w kolumnie, które będzię się dzidziczyło z pierwszej planszy/ogrodu + for i in range(len(path) - 1): + if path[i + 1][0] - path[i][0] == 1: + info.append(NUM_Y - path[i][1]) + if len(info) < NUM_X: # uzupełnienie informacji o dziedziczeniu z planszy/ogrodu + if path[-1:][0][1] == 0: + x = NUM_Y + else: + x = 0 + while len(info) < NUM_X: + info.append(x) + # return path, info + return info + + +# Funkcja do generowania potomstwa +def divide_gardens(garden1, garden2): + info = line() + new_garden1 = [[] for _ in range(NUM_Y)] + new_garden2 = [[] for _ in range(NUM_Y)] + for i in range(NUM_X): + for j in range(NUM_Y): + # do utworzonych kolumn w nowych planszach/ogrodach dodajemy dziedziczone rośliny + if j < info[i]: + new_garden1[j].append(garden1[j][i]) + new_garden2[j].append(garden2[j][i]) + else: + new_garden1[j].append(garden2[j][i]) + new_garden2[j].append(garden1[j][i]) + + return [new_garden1, calculate_yields(new_garden1)], [new_garden2, calculate_yields(new_garden2)] + + +# Funkcja do mutacji danej planszy/ogrodu +def mutation(garden, not_used): + new_garden = copy.deepcopy(garden) + for i in range(NUM_X): + x = random.randint(0, 11) # wybieramy, w którym wierszu w i-tej kolumnie zmieniamy roślinę na inną + other_plants = [plant for plant in plants if plant != new_garden[x][i]] + new_garden[x][i] = random.choice(other_plants) + return [new_garden, calculate_yields(new_garden)] + + +# Funkcja do generowania pierwszego pokolenia +def generate(n): + generation = [] + for i in range(n * 3): + generation.append(generate_garden_with_yields()) + generation.sort(reverse=True, key=lambda x: x[1]) + return generation[:n] + + +# Funkcja do implementacji ruletki (sposobu wyboru) - sumuje wszystkie plony generacji +def sum_yields(x): + s = 0 + for i in range(len(x)): + s += x[i][1] + return s + + +if __name__ == '__main__': + roulette = True + attemps = 150 + iterat = 2500 + population = 100 + best = [] + for a in range(attemps): + generation = generate(population) + print(generation[0][1]) + for i in range(iterat): # ile iteracji - nowych pokoleń + print(a, i) + new_generation = generation[:(population // 7)] # dziedziczenie x najlepszych osobników + j = 0 + while j < ( + population - ( + population // 7)): # dobór reszty osobników do pełnej liczby populacji danego pokolenia + if roulette: # zasada ruletki -> "2 rzuty kulką" + s = sum_yields(generation) # suma wszystkich plnów całego pokolenia + z = [] + if s == 0: # wtedy każdy osobnik ma takie same szanse + z.append(random.randint(0, population - 1)) + z.append(random.randint(0, population - 1)) + else: + weights = [] # wagi prawdopodobieństwa dla każdego osobnika generacji + pos = [] # numery od 0 do 49 odpowiadające numerom osobnikom w generacji + for i in range(population): + weights.append(generation[i][1] / s) + pos.append(i) + z.append(random.choices(pos, weights)[0]) # wybranie osobnika według wag prawdopodobieństwa + z.append(random.choices(pos, weights)[0]) # wybranie osobnika według wag prawdopodobieństwa + else: # metoda rankingu + z = random.sample(range(0, int(population // 1.7)), 2) + + # krzyzowanie 90% szans, mutacja 10% szans + function = [divide_gardens, mutation] + weight = [0.9, 0.1] + fun = random.choices(function, weight)[0] + h = fun(generation[z[0]][0], generation[z[1]][0]) + if len(h[0]) == 2: + new_generation.append(h[0]) + new_generation.append(h[1]) + j += 2 + else: + new_generation.append(h) + j += 1 + + new_generation.sort(reverse=True, key=lambda x: x[1]) # sortowanie malejąco listy według wartości plonów + generation = new_generation[:population] + + best.append(generation[0]) + + best.sort(reverse=True, key=lambda x: x[1]) + + # Zapis do pliku + # for i in range(len(best)): + # print(best[i][1], calculate_yields(best[i][0])) + # + # + # with open(f'pole_pop{population}_iter{iterat}_{roulette}.json', 'w') as file: # zapis planszy/ogrodu do pliku json + # json.dump(best[0][0], file, indent=4) + # + # print("Dane zapisane do pliku") + + # Odczyt z pliku + # with open(f'pole_pop{population}_iter{iterat}_{roulette}.json', 'r') as file: + # garden_data = json.load(file) + # + # print("Odczytane dane ogrodu:") + # for row in garden_data: + # print(row) + # + # print(calculate_yields(garden_data)) + # if best[0][0] == garden_data: + # print("POPRAWNE: ", calculate_yields(garden_data), calculate_yields(best[0][0])) -- 2.20.1 From d61b5858278c53b2532dd20d6afe17d3bc5199c7 Mon Sep 17 00:00:00 2001 From: Mateusz Czajka Date: Sat, 8 Jun 2024 23:25:08 +0200 Subject: [PATCH 6/7] Corrected GeneticAlgorithm2 and made a GeneticAlgorithm3 and generated fields using them. Made GeneticAccuracy to check the performance of the algorithms. --- GeneticAccuracy.py | 139 +++++++++++++++++ GeneticAlgorithm.py | 2 +- GeneticAlgorithm2.py | 31 ++-- GeneticAlgorithm3.py | 211 +++++++++++++++++++++++++ pole2_pop120_iter2500_True.json | 266 ++++++++++++++++++++++++++++++++ pole3_pop120_365_True.json | 266 ++++++++++++++++++++++++++++++++ 6 files changed, 900 insertions(+), 15 deletions(-) create mode 100644 GeneticAccuracy.py create mode 100644 GeneticAlgorithm3.py create mode 100644 pole2_pop120_iter2500_True.json create mode 100644 pole3_pop120_365_True.json diff --git a/GeneticAccuracy.py b/GeneticAccuracy.py new file mode 100644 index 0000000..35a4095 --- /dev/null +++ b/GeneticAccuracy.py @@ -0,0 +1,139 @@ +import json +import random + +from displayControler import NUM_Y, NUM_X + +iterat = 2500 +population = 120 +roulette = True + +plants = ['corn', 'potato', 'tomato', 'carrot'] +initial_yields = {'corn': 38, 'potato': 40, 'tomato': 43, 'carrot': 45} +yield_reduction = { + 'corn': {'corn': -4.5, 'potato': -3, 'tomato': -7, 'carrot': -7}, + 'potato': {'corn': -7, 'potato': -5, 'tomato': -10, 'carrot': -6}, + 'tomato': {'corn': -4, 'potato': -5, 'tomato': -7, 'carrot': -7}, + 'carrot': {'corn': -11, 'potato': -5, 'tomato': -4, 'carrot': -7} +} +yield_reduction2 = { + 'corn': {'corn': None, 'potato': -4, 'tomato': -2, 'carrot': -4}, + 'potato': {'corn': None, 'potato': -5, 'tomato': -5, 'carrot': -2}, + 'tomato': {'corn': -5, 'potato': -3, 'tomato': -7, 'carrot': None}, + 'carrot': {'corn': -3, 'potato': -6, 'tomato': -4, 'carrot': -9} +} +yield_multiplier = {'corn': 1.25, 'potato': 1.17, 'tomato': 1.22, 'carrot': 1.13} +yield_multiplier2 = {'corn': 1.25, 'potato': 1.19, 'tomato': 1.22, 'carrot': 1.15} + + +def calculate_yields(garden): + rows = len(garden) + cols = len(garden[0]) + + total_yields = 0 + + for i in range(rows): + for j in range(cols): + plant = garden[i][j] + yield_count = initial_yields[plant] + + # Sprawdzanie sąsiadów + neighbors = [ + (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1) + ] + + for ni, nj in neighbors: + if 0 <= ni < rows and 0 <= nj < cols: + neighbor_plant = garden[ni][nj] + yield_count += yield_reduction[plant][neighbor_plant] + + yield_count *= yield_multiplier[plant] + total_yields += yield_count + + return total_yields + + +def calculate_yields2(garden): + rows = len(garden) + cols = len(garden[0]) + + total_yields = 0 + + for i in range(rows): + for j in range(cols): + plant = garden[i][j] + yield_count = initial_yields[plant] + + # Sprawdzanie sąsiadów + neighbors = [ + (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1) + ] + neighbor_flag = False + for ni, nj in neighbors: + if 0 <= ni < rows and 0 <= nj < cols: + neighbor_plant = garden[ni][nj] + + if yield_reduction2[plant][neighbor_plant] is not None: # jeśli jest wartość None to plony dla tej rośliny będą wyzerowane + yield_count += yield_reduction2[plant][neighbor_plant] + else: + neighbor_flag = True + + if not neighbor_flag: + yield_count *= yield_multiplier2[plant] + total_yields += yield_count + + return total_yields + + +def generate_garden(rows=20, cols=12): + return [[random.choice(plants) for _ in range(cols)] for _ in range(rows)] + + +def generate_garden_with_yields(t, rows=NUM_Y, cols=NUM_X): + garden = generate_garden(rows, cols) + if t == 1: + total_yields = calculate_yields(garden) + else: + total_yields = calculate_yields2(garden) + return [garden, total_yields] + + +def generate(): + s1 = 0 + s2 = 0 + n = 150 + for i in range(n): + x = generate_garden_with_yields(1) + s1 += x[1] + y = generate_garden_with_yields(2) + s2 += y[1] + return [s1/n, s2/n] + + +data = generate() +# print(data) + +# Odczyt z pliku +with open(f'pole_pop{population}_iter{iterat}_{roulette}.json', 'r') as file: + garden_data = json.load(file) + +# print("Odczytane dane ogrodu:") +# for row in garden_data: +# print(row) + +print("Wygenerowane przy pomocy GA: ", calculate_yields(garden_data)) +print(f"Przeciętny ogród wygenerowany randomowo ma {data[0]} plonów") +print("Uśredniony przyrost plonów (ile razy więcej plonów): ", calculate_yields(garden_data)/data[0]) + + + +# Odczyt z pliku +with open(f'pole2_pop{population}_iter{iterat}_{roulette}.json', 'r') as file: + garden_data2 = json.load(file) + +# print("Odczytane dane ogrodu:") +# for row in garden_data2: +# print(row) + +print("Wygenerowane: przy pomocy GA2", calculate_yields2(garden_data2)) +print(f"Przeciętny ogród wygenerowany randomowo ma {data[1]} plonów") +print("Uśredniony przyrost plonów (ile razy więcej plonów): ", calculate_yields2(garden_data2)/data[1]) \ No newline at end of file diff --git a/GeneticAlgorithm.py b/GeneticAlgorithm.py index 3352824..c207d36 100644 --- a/GeneticAlgorithm.py +++ b/GeneticAlgorithm.py @@ -136,7 +136,7 @@ if __name__ == '__main__': roulette = True attemps = 150 iterat = 2500 - population = 100 + population = 120 best = [] for a in range(attemps): generation = generate(population) diff --git a/GeneticAlgorithm2.py b/GeneticAlgorithm2.py index e3972d5..c3d2be1 100644 --- a/GeneticAlgorithm2.py +++ b/GeneticAlgorithm2.py @@ -7,12 +7,12 @@ from displayControler import NUM_X, NUM_Y plants = ['corn', 'potato', 'tomato', 'carrot'] initial_yields = {'corn': 38, 'potato': 40, 'tomato': 43, 'carrot': 45} yield_reduction = { - 'corn': {'corn': -4.5, 'potato': -3, 'tomato': -7, 'carrot': -7}, - 'potato': {'corn': None, 'potato': -5, 'tomato': -10, 'carrot': -6}, - 'tomato': {'corn': None, 'potato': -5, 'tomato': -7, 'carrot': -7}, - 'carrot': {'corn': None, 'potato': -5, 'tomato': -4, 'carrot': -7} + 'corn': {'corn': None, 'potato': -4, 'tomato': -2, 'carrot': -4}, + 'potato': {'corn': None, 'potato': -5, 'tomato': -5, 'carrot': -2}, + 'tomato': {'corn': -5, 'potato': -3, 'tomato': -7, 'carrot': None}, + 'carrot': {'corn': -3, 'potato': -6, 'tomato': -4, 'carrot': -9} } -yield_multiplier = {'corn': 1.25, 'potato': 1.17, 'tomato': 1.22, 'carrot': 1.13} +yield_multiplier = {'corn': 1.25, 'potato': 1.19, 'tomato': 1.22, 'carrot': 1.15} # Generowanie listy 20x12 z losowo rozmieszczonymi roślinami @@ -36,16 +36,19 @@ def calculate_yields(garden): neighbors = [ (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1) ] - + neighbor_flag = False for ni, nj in neighbors: if 0 <= ni < rows and 0 <= nj < cols: neighbor_plant = garden[ni][nj] - if yield_reduction[plant][neighbor_plant] is not None: #jeśli jest wartość None to nie zostaje wcale dodane + if yield_reduction[plant][neighbor_plant] is not None: # jeśli jest wartość None to plony dla tej rośliny będą wyzerowane yield_count += yield_reduction[plant][neighbor_plant] + else: + neighbor_flag = True - yield_count *= yield_multiplier[plant] - total_yields += yield_count + if not neighbor_flag: + yield_count *= yield_multiplier[plant] + total_yields += yield_count return total_yields @@ -136,9 +139,9 @@ def sum_yields(x): if __name__ == '__main__': roulette = True - attemps = 150 + attemps = 20 iterat = 2500 - population = 100 + population = 120 best = [] for a in range(attemps): generation = generate(population) @@ -192,13 +195,13 @@ if __name__ == '__main__': # print(best[i][1], calculate_yields(best[i][0])) # # - # with open(f'pole_pop{population}_iter{iterat}_{roulette}.json', 'w') as file: # zapis planszy/ogrodu do pliku json + # with open(f'pole2_pop{population}_iter{iterat}_{roulette}.json', 'w') as file: # zapis planszy/ogrodu do pliku json # json.dump(best[0][0], file, indent=4) # # print("Dane zapisane do pliku") - + # # Odczyt z pliku - # with open(f'pole_pop{population}_iter{iterat}_{roulette}.json', 'r') as file: + # with open(f'pole2_pop{population}_iter{iterat}_{roulette}.json', 'r') as file: # garden_data = json.load(file) # # print("Odczytane dane ogrodu:") diff --git a/GeneticAlgorithm3.py b/GeneticAlgorithm3.py new file mode 100644 index 0000000..ef2db95 --- /dev/null +++ b/GeneticAlgorithm3.py @@ -0,0 +1,211 @@ +import copy +import json +import random +from displayControler import NUM_X, NUM_Y + +# Definiowanie stałych dla roślin i plonów +plants = ['corn', 'potato', 'tomato', 'carrot'] +initial_yields = {'corn': 38, 'potato': 40, 'tomato': 43, 'carrot': 45} +yield_reduction = { + 'corn': {'corn': None, 'potato': 0, 'tomato': 0, 'carrot': 0}, + 'potato': {'corn': None, 'potato': 0, 'tomato': 0, 'carrot': 0}, + 'tomato': {'corn': 0, 'potato': 0, 'tomato': 0, 'carrot': None}, + 'carrot': {'corn': 0, 'potato': 0, 'tomato': 0, 'carrot': 0} +} +yield_multiplier = {'corn': 1.25, 'potato': 1.19, 'tomato': 1.22, 'carrot': 1.13} + + +# Generowanie listy 20x12 z losowo rozmieszczonymi roślinami +def generate_garden(rows=20, cols=12): + return [[random.choice(plants) for _ in range(cols)] for _ in range(rows)] + + +# Funkcja do obliczania liczby plonów +def calculate_yields(garden): + rows = len(garden) + cols = len(garden[0]) + + total_yields = 0 + + for i in range(rows): + for j in range(cols): + plant = garden[i][j] + + # Sprawdzanie sąsiadów + neighbors = [ + (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1) + ] + neighbor_flag = False + for ni, nj in neighbors: + if 0 <= ni < rows and 0 <= nj < cols: + neighbor_plant = garden[ni][nj] + + if yield_reduction[plant][neighbor_plant] is None: # jeśli jest wartość None to plony dla tej rośliny będą wyzerowane + neighbor_flag = True + + if not neighbor_flag: + total_yields += 1 + + return total_yields + + +# Funkcja do generowania planszy/ogrodu i zapisywania go jako lista z liczbą plonów +def generate_garden_with_yields(rows=NUM_Y, cols=NUM_X): + garden = generate_garden(rows, cols) + total_yields = calculate_yields(garden) + return [garden, total_yields] + + +# Funkcja do generowania linii cięcia i zapisywania jej jako liczba roślin w kolumnie z pierwszej planszy/ogrodu +def line(): + path = [] + flag = False + x = random.randint(4, 8) + position = (0, x) + path.append(position) + while not flag: # wybór punktu dopóki nie wybierze się skrajnego + # prawdopodobieństwo "ruchu" -> 0.6: w prawo, 0.2: w góre, 0.2: w dół + p = [(position[0] + 1, position[1]), (position[0], position[1] + 1), (position[0], position[1] - 1)] + w = [0.6, 0.2, 0.2] + position2 = random.choices(p, w)[0] + if position2 not in path: # sprawdzenie czy dany punkt nie był już wybrany aby nie zapętlać się + path.append(position2) + position = position2 + if position[0] == NUM_X or position[1] == 0 or position[1] == NUM_Y: # sprawdzenie czy osiągnięto skrajny punkt + flag = True + info = [] # przeformatowanie sposobu zapisu na liczbę roślin w kolumnie, które będzię się dzidziczyło z pierwszej planszy/ogrodu + for i in range(len(path) - 1): + if path[i + 1][0] - path[i][0] == 1: + info.append(NUM_Y - path[i][1]) + if len(info) < NUM_X: # uzupełnienie informacji o dziedziczeniu z planszy/ogrodu + if path[-1:][0][1] == 0: + x = NUM_Y + else: + x = 0 + while len(info) < NUM_X: + info.append(x) + # return path, info + return info + + +# Funkcja do generowania potomstwa +def divide_gardens(garden1, garden2): + info = line() + new_garden1 = [[] for _ in range(NUM_Y)] + new_garden2 = [[] for _ in range(NUM_Y)] + for i in range(NUM_X): + for j in range(NUM_Y): + # do utworzonych kolumn w nowych planszach/ogrodach dodajemy dziedziczone rośliny + if j < info[i]: + new_garden1[j].append(garden1[j][i]) + new_garden2[j].append(garden2[j][i]) + else: + new_garden1[j].append(garden2[j][i]) + new_garden2[j].append(garden1[j][i]) + + return [new_garden1, calculate_yields(new_garden1)], [new_garden2, calculate_yields(new_garden2)] + + +# Funkcja do mutacji danej planszy/ogrodu +def mutation(garden, not_used): + new_garden = copy.deepcopy(garden) + for i in range(NUM_X): + x = random.randint(0, 11) # wybieramy, w którym wierszu w i-tej kolumnie zmieniamy roślinę na inną + other_plants = [plant for plant in plants if plant != new_garden[x][i]] + new_garden[x][i] = random.choice(other_plants) + return [new_garden, calculate_yields(new_garden)] + + +# Funkcja do generowania pierwszego pokolenia +def generate(n): + generation = [] + for i in range(n * 3): + generation.append(generate_garden_with_yields()) + generation.sort(reverse=True, key=lambda x: x[1]) + return generation[:n] + + +# Funkcja do implementacji ruletki (sposobu wyboru) - sumuje wszystkie plony generacji +def sum_yields(x): + s = 0 + for i in range(len(x)): + s += x[i][1] + return s + + +if __name__ == '__main__': + roulette = True + attemps = 1 + population = 120 + best = [] + iter = 0 + for a in range(attemps): + generation = generate(population) + print(generation[0][1]) + while generation[0][1] != NUM_X*NUM_Y: # ile iteracji - nowych pokoleń + iter += 1 + print(iter) + print(generation[0][1]) + new_generation = generation[:(population // 7)] # dziedziczenie x najlepszych osobników + j = 0 + while j < ( + population - ( + population // 7)): # dobór reszty osobników do pełnej liczby populacji danego pokolenia + if roulette: # zasada ruletki -> "2 rzuty kulką" + s = sum_yields(generation) # suma wszystkich plnów całego pokolenia + z = [] + if s == 0: # wtedy każdy osobnik ma takie same szanse + z.append(random.randint(0, population - 1)) + z.append(random.randint(0, population - 1)) + else: + weights = [] # wagi prawdopodobieństwa dla każdego osobnika generacji + pos = [] # numery od 0 do 49 odpowiadające numerom osobnikom w generacji + for i in range(population): + weights.append(generation[i][1] / s) + pos.append(i) + z.append(random.choices(pos, weights)[0]) # wybranie osobnika według wag prawdopodobieństwa + z.append(random.choices(pos, weights)[0]) # wybranie osobnika według wag prawdopodobieństwa + else: # metoda rankingu + z = random.sample(range(0, int(population // 1.7)), 2) + + # krzyzowanie 90% szans, mutacja 10% szans + function = [divide_gardens, mutation] + weight = [0.9, 0.1] + fun = random.choices(function, weight)[0] + h = fun(generation[z[0]][0], generation[z[1]][0]) + if len(h[0]) == 2: + new_generation.append(h[0]) + new_generation.append(h[1]) + j += 2 + else: + new_generation.append(h) + j += 1 + + new_generation.sort(reverse=True, key=lambda x: x[1]) # sortowanie malejąco listy według wartości plonów + generation = new_generation[:population] + + best.append(generation[0]) + + best.sort(reverse=True, key=lambda x: x[1]) + + # Zapis do pliku + # for i in range(len(best)): + # print(best[i][1], calculate_yields(best[i][0])) + # + # + # with open(f'pole3_pop{population}_{iter}_{roulette}.json', 'w') as file: # zapis planszy/ogrodu do pliku json + # json.dump(best[0][0], file, indent=4) + # + # print("Dane zapisane do pliku") + # + # Odczyt z pliku + # with open(f'pole3_pop{population}_{iter}_{roulette}.json', 'r') as file: + # garden_data = json.load(file) + # + # print("Odczytane dane ogrodu:") + # for row in garden_data: + # print(row) + # + # print(calculate_yields(garden_data)) + # if best[0][0] == garden_data: + # print("POPRAWNE: ", calculate_yields(garden_data), calculate_yields(best[0][0])) diff --git a/pole2_pop120_iter2500_True.json b/pole2_pop120_iter2500_True.json new file mode 100644 index 0000000..2b227ef --- /dev/null +++ b/pole2_pop120_iter2500_True.json @@ -0,0 +1,266 @@ +[ + [ + "tomato", + "corn", + "tomato", + "tomato", + "corn", + "tomato", + "tomato", + "corn", + "carrot", + "potato", + "potato", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato" + ], + [ + "corn", + "carrot", + "potato", + "potato", + "carrot", + "potato", + "potato", + "carrot", + "potato", + "potato", + "carrot", + "corn", + "tomato", + "corn", + "carrot", + "corn", + "tomato", + "corn", + "tomato", + "corn" + ], + [ + "carrot", + "potato", + "potato", + "carrot", + "corn", + "carrot", + "potato", + "carrot", + "potato", + "carrot", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato" + ], + [ + "potato", + "potato", + "carrot", + "corn", + "tomato", + "corn", + "carrot", + "corn", + "carrot", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn" + ], + [ + "potato", + "carrot", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato" + ], + [ + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn" + ], + [ + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato" + ], + [ + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn" + ], + [ + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "carrot", + "corn", + "tomato" + ], + [ + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "carrot", + "potato", + "tomato", + "potato" + ], + [ + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "carrot", + "corn", + "carrot", + "corn", + "carrot", + "potato", + "potato", + "tomato", + "potato" + ], + [ + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "corn", + "tomato", + "potato", + "potato", + "carrot", + "corn", + "tomato" + ] +] \ No newline at end of file diff --git a/pole3_pop120_365_True.json b/pole3_pop120_365_True.json new file mode 100644 index 0000000..9dd0188 --- /dev/null +++ b/pole3_pop120_365_True.json @@ -0,0 +1,266 @@ +[ + [ + "potato", + "carrot", + "carrot", + "potato", + "potato", + "carrot", + "carrot", + "potato", + "tomato", + "potato", + "carrot", + "potato", + "carrot", + "potato", + "carrot", + "carrot", + "potato", + "potato", + "potato", + "carrot" + ], + [ + "tomato", + "potato", + "carrot", + "potato", + "tomato", + "potato", + "carrot", + "carrot", + "potato", + "carrot", + "carrot", + "carrot", + "carrot", + "carrot", + "carrot", + "carrot", + "potato", + "potato", + "carrot", + "potato" + ], + [ + "corn", + "carrot", + "corn", + "carrot", + "potato", + "carrot", + "carrot", + "corn", + "tomato", + "corn", + "carrot", + "potato", + "potato", + "carrot", + "carrot", + "corn", + "carrot", + "potato", + "potato", + "tomato" + ], + [ + "tomato", + "potato", + "carrot", + "corn", + "tomato", + "corn", + "carrot", + "carrot", + "corn", + "carrot", + "potato", + "carrot", + "carrot", + "corn", + "carrot", + "carrot", + "potato", + "potato", + "tomato", + "tomato" + ], + [ + "tomato", + "potato", + "carrot", + "carrot", + "corn", + "carrot", + "carrot", + "potato", + "tomato", + "potato", + "carrot", + "carrot", + "potato", + "carrot", + "carrot", + "potato", + "tomato", + "tomato", + "potato", + "potato" + ], + [ + "potato", + "tomato", + "potato", + "potato", + "tomato", + "corn", + "carrot", + "potato", + "potato", + "tomato", + "potato", + "carrot", + "carrot", + "potato", + "carrot", + "potato", + "tomato", + "potato", + "carrot", + "carrot" + ], + [ + "potato", + "potato", + "tomato", + "tomato", + "corn", + "carrot", + "carrot", + "potato", + "tomato", + "potato", + "carrot", + "carrot", + "potato", + "carrot", + "carrot", + "carrot", + "potato", + "carrot", + "carrot", + "potato" + ], + [ + "carrot", + "potato", + "tomato", + "potato", + "carrot", + "carrot", + "potato", + "potato", + "tomato", + "tomato", + "potato", + "carrot", + "potato", + "potato", + "carrot", + "carrot", + "potato", + "carrot", + "corn", + "carrot" + ], + [ + "carrot", + "potato", + "tomato", + "potato", + "carrot", + "carrot", + "carrot", + "potato", + "tomato", + "potato", + "potato", + "carrot", + "carrot", + "potato", + "carrot", + "carrot", + "carrot", + "potato", + "tomato", + "corn" + ], + [ + "potato", + "tomato", + "tomato", + "potato", + "carrot", + "potato", + "potato", + "carrot", + "potato", + "potato", + "carrot", + "potato", + "carrot", + "carrot", + "potato", + "carrot", + "corn", + "tomato", + "potato", + "tomato" + ], + [ + "potato", + "tomato", + "corn", + "tomato", + "potato", + "potato", + "potato", + "potato", + "carrot", + "carrot", + "carrot", + "potato", + "carrot", + "carrot", + "potato", + "carrot", + "carrot", + "corn", + "tomato", + "potato" + ], + [ + "potato", + "potato", + "carrot", + "corn", + "carrot", + "potato", + "potato", + "potato", + "carrot", + "carrot", + "carrot", + "potato", + "carrot", + "carrot", + "potato", + "carrot", + "corn", + "carrot", + "corn", + "tomato" + ] +] \ No newline at end of file -- 2.20.1 From eb2529831a7af0830b577d4a2701b6c5b420f13c Mon Sep 17 00:00:00 2001 From: jakzar Date: Sun, 9 Jun 2024 18:33:50 +0200 Subject: [PATCH 7/7] This: -added goaltressure in bfs3 call in App.py -changed def value for randomGT in BFS3 in bfs.py -added more context to readme.txt --- App.py | 2 +- BFS.py | 2 +- readme.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/App.py b/App.py index 2b8203c..7d2e726 100644 --- a/App.py +++ b/App.py @@ -85,7 +85,7 @@ def init_demo(): #Demo purpose print_to_console("Traktor porusza sie obliczona sciezka BFS") traktor.move_by_root(bfsRoot2, pole, [traktor.irrigateSlot]) if(bfs3_flag): - bfsRoot3 = BFS.BFS3({'x': 0, 'y': 0, 'direction': "E"}) + bfsRoot3 = BFS.BFS3({'x': 0, 'y': 0, 'direction': "E"},goalTreasure) #displayControler: NUM_X: 20, NUM_Y: 12 (skarb) CHANGE THIS IN DCON BY HAND!!!!!!!! bfsRoot3.reverse() print_to_console("Traktor porusza sie obliczona sciezka BFS") diff --git a/BFS.py b/BFS.py index df72500..16b6519 100644 --- a/BFS.py +++ b/BFS.py @@ -134,7 +134,7 @@ def check3(tab, state): def BFS3(istate,GT): - randomGT=True + randomGT=False if(randomGT==True): goalTreassuere = (random.randint(0,NUM_X-1), random.randint(0,NUM_Y-1)) else: diff --git a/readme.txt b/readme.txt index d22a68a..4155475 100644 --- a/readme.txt +++ b/readme.txt @@ -7,7 +7,7 @@ Required packages: pip install pandas How to run: For BFS3: - -in App.py change bfs3_flag to True (other flags need to be disabled) + -in App.py: -change bfs3_flag to True (other flags need to be disabled) -ensure that in App.py in BFS3 you give goalTreasure -in Image.py change range in function return_random_plant to (0,5) For Astar: in App.py change Astar to True (other flags need to be disabled) -- 2.20.1