diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/Madra_smieciarka.iml b/.idea/Madra_smieciarka.iml new file mode 100644 index 0000000..b7231fb --- /dev/null +++ b/.idea/Madra_smieciarka.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/csv-editor.xml b/.idea/csv-editor.xml new file mode 100644 index 0000000..b3dabd0 --- /dev/null +++ b/.idea/csv-editor.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..40e984a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..dcc7f12 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/classes/Decisiontree.py b/classes/Decisiontree.py index 42eeb11..5b25d67 100644 --- a/classes/Decisiontree.py +++ b/classes/Decisiontree.py @@ -6,6 +6,7 @@ from sklearn.preprocessing import LabelEncoder from sklearn.tree import plot_tree import matplotlib.pyplot as plt from sklearn.tree import export_text +from joblib import dump data = pd.read_csv("data.csv") @@ -28,18 +29,24 @@ treeclf.fit(x_train, y_train) y_pred = treeclf.predict(x_test) -#print("Przewidywane etykiety dla danych testowych:") -#print(y_pred) - accuracy = accuracy_score(y_test, y_pred) print("Dokładność:", accuracy) +# Zapisanie modelu do pliku +dump(treeclf, 'drzewo.joblib') class_names = [str(class_label) for class_label in labels['decyzja'].classes_] plt.figure(figsize=(25,20)) plot_tree(treeclf, feature_names=x.columns, class_names=class_names, filled=True) plt.show() +for (column, encoder) in labels.items(): + if column == 'decyzja': + continue + print(f"{column}:") + for (i, label) in enumerate(encoder.classes_): + print(f"{i}: {label}") + tree_text = export_text(treeclf, feature_names=list(x.columns)) tree_file_path = "wyuczone_drzewo.txt" with open(tree_file_path, "w") as tree_file: diff --git a/classes/Garbage.py b/classes/Garbage.py index 7767285..78ae05e 100644 --- a/classes/Garbage.py +++ b/classes/Garbage.py @@ -4,16 +4,20 @@ from classes.Trash import * class Garbage: def __init__(self): + self.full = random.randint(0, 2) self.content = [] - self.predict = [] + self.known = [] self.prob: float = 0.3 - self.generatePredict() + self.generateKnown() self.generateContent() - self.predict = tuple(self.predict) + self.known = tuple(self.known) def getContent(self): return self.content + def getFull(self): + return self.full + def setContent(self, content): self.content = content return self @@ -23,17 +27,17 @@ class Garbage: return self def removeContent(self, item: int): - return self.content.pop(item) + return self.content.remove(item) - def getPredict(self): - return self.predict + def getKnown(self): + return self.known - def setPredict(self, predict): - self.predict = predict + def setKnown(self, predict): + self.known = predict return self - def addPredict(self, item): - self.predict.append(item) + def addKnown(self, item): + self.known.append(item) return self def getProb(self): @@ -43,20 +47,20 @@ class Garbage: self.prob = prob return self - def generatePredict(self, i=random.choice([2, 3])): + def generateKnown(self, i=random.choice([2, 3])): if i < 0: - self.predict.pop(i) + self.known.pop(i) else: for _ in range(i): possible = [Papier(), MetalPlastik(), Szklo(), Mixed(), Bio()] traf = random.choice(possible) - self.predict.append(traf) + self.known.append(traf) for bruh in possible: if bruh != traf: del bruh def generateContent(self): - self.setContent(self.predict[:]) + self.setContent(self.known[:]) if random.random() < self.prob: mod = random.choice([1, -1]) - self.generatePredict(mod) + self.generateKnown(mod) diff --git a/classes/Garbagetruck.py b/classes/Garbagetruck.py index cd72fba..82ba7b6 100644 --- a/classes/Garbagetruck.py +++ b/classes/Garbagetruck.py @@ -1,7 +1,7 @@ import math import random import heapq - +from joblib import load import pygame from classes.Household import * from classes.Node import * @@ -12,6 +12,11 @@ class Garbagetruck: def __init__(self, mult): self.mult = mult + self.weather = random.randint(0, 2) + self.season = random.randint(0, 3) + self.daytime = random.randint(0, 3) + self.zapelnienie: int = 1 + self.knowledge = [self.season, self.daytime, -1, -1, self.zapelnienie, -1, -1, self.weather] self.capacity: int = 20 self.trash: list = [] self.trashweight: int = 0 @@ -29,11 +34,45 @@ class Garbagetruck: self.route = None self.scanner = None self.planner = None - self.driver = None + self.driver = load("./classes/drzewo.joblib") self.orientation = 3 # Niech numery będą tak: N - 0, W - 1, S - 2, E - 3 -- po prostu odwrotnie do zegara self.runningtime = 0 self.movesequence = [] self.target = None + self.analising = False + + def getAnalising(self): + return self.analising + + def switchAnalising(self): + self.analising = False if self.analising else True + return self + + def decision(self, house, trash, can): + knowledge = self.knowledge[:] + knowledge[2] = trash.getTreetype() + knowledge[3] = can.getFull() + knowledge[5] = house.getPaid() + knowledge[6] = house.getLastTaken() + print(knowledge) + + if -1 not in knowledge: + return self.driver.predict([knowledge]) + else: + print("NIE WIEM, BRAK DANYCH") + + def pickTrash(self): + house = self.getState() + can = house.getGarbage() + trashlist = can.getContent() + for trash in trashlist: + if self.trashweight + trash.getWaga() <= self.capacity: + decision = self.decision(house, trash, can) + print(f"{trash.getTtype()} - decyzja: {decision}") + if decision: + self.addTrash(trash) + can.removeContent(trash) + self.switchAnalising() def getState(self): return self.state @@ -99,14 +138,24 @@ class Garbagetruck: self.trash.append(trash) self.addTrashweight(trash.getWaga()) + def changeZapelnienie(self) -> None: + if self.trashweight < 0.25*self.capacity: + self.zapelnienie = 1 + elif self.trashweight < self.capacity: + self.zapelnienie = 2 + else: + self.zapelnienie = 0 + def getTrashweight(self) -> int: return self.trashweight def setTrashweight(self, weight: int) -> None: self.trashweight = weight + self.changeZapelnienie() def addTrashweight(self, weight: int) -> None: self.trashweight += weight + self.changeZapelnienie() def getImage(self) -> object: return self.image @@ -121,7 +170,7 @@ class Garbagetruck: self.position = position return self - def modPosiotion(self, modX, modY): + def modPosition(self, modX, modY): x = self.getPosition()[0] + modX y = self.getPosition()[1] + modY position = [x, y] @@ -211,11 +260,12 @@ class Garbagetruck: stepY = 1 elif ort == 3 and x != 30: stepX = 1 - self.modPosiotion(stepX, stepY) + self.modPosition(stepX, stepY) def graphsearch(self): house_positions = [house.getPosition() for house in self.houses] cans_positions = [can.getPosition() for can in self.trashcans] + def succ(elem): def virtRotateLeft(state): ort = (state[-1] + 1) % 4 @@ -246,7 +296,6 @@ class Garbagetruck: result = [x, y, ort] return result - op = elem.getState() forward = {"result": virtMoveForward(op), "action": "F"} left = {"result": virtRotateLeft(op), "action": "L"} @@ -263,7 +312,7 @@ class Garbagetruck: x, y, _ = state if (x, y) in house_positions: return 10 - elif (x,y) in cans_positions: + elif (x, y) in cans_positions: return 5 else: return 1 @@ -274,7 +323,6 @@ class Garbagetruck: temp = self.getPosition()[:] temp.append(self.getOrientation()) initial = Node(temp) - initial.setCost(0) fringe.append((0, initial)) # (priority, node) while True: @@ -300,11 +348,12 @@ class Garbagetruck: explored.append(elem) suc = succ(elem) for wynik in suc: - if wynik['result'] not in [item[1].getState() for item in fringe] and wynik['result'] not in [item.getState() for item in explored]: - x = Node(wynik["result"]) - x.setParent(elem) - x.setAction(wynik["action"]) - x.setCost(elem.getCost() + cost(x.getState())) + if (wynik['result'] not in [item[1].getState() for item in fringe] + and wynik['result'] not in [item.getState() for item in explored]): + x = (Node(wynik["result"]) + .setParent(elem) + .setAction(wynik["action"])) + x.setCost(x.getParent().getCost() + cost(x.getState())) priority = x.getCost() + heuristic(x.getState()) heapq.heappush(fringe, (priority, x)) @@ -318,15 +367,18 @@ class Garbagetruck: self.moveForward() def randomTarget(self): - wybor1 = random.choice([1,2]) - if wybor1 == 1: + # wybor1 = random.random() + # if wybor1 < 0.75: + wybor2 = random.choice(self.houses) + while not wybor2.getGarbage().getContent(): wybor2 = random.choice(self.houses) - else: - wybor2 = random.choice(self.trashcans) + # else: + # wybor2 = random.choice(self.trashcans) wybor2.switchFinal() # print(wybor2) def classifyTrash(self): pass # Tutaj jest plan żeby dopiero napisać funkcję jak już będzie klasyfikator -# ogólnie to myślałem żeby po prostu zklasyfikować śmieć i zmienić mu trashtype na rozpoznany, żeby śmieciarka go tak posegreowała +# ogólnie to myślałem żeby po prostu zklasyfikować śmieć i zmienić mu trashtype na rozpoznany, +# żeby śmieciarka go tak posegreowała diff --git a/classes/Household.py b/classes/Household.py index ac5069f..b518845 100644 --- a/classes/Household.py +++ b/classes/Household.py @@ -1,8 +1,12 @@ +import random + from classes.Garbage import * class Household: def __init__(self, mult): + self.paid = random.randint(0, 1) + self.lastTaken = random.randint(0, 30) self.mult = mult self.id: int = 0 self.image: object = None @@ -13,6 +17,12 @@ class Household: def getFinal(self): return self.final + def getPaid(self): + return self.paid + + def getLastTaken(self): + return self.lastTaken + def switchFinal(self): self.final = False if self.final else True return self diff --git a/classes/Node.py b/classes/Node.py index 75c4ff1..0e2d6dd 100644 --- a/classes/Node.py +++ b/classes/Node.py @@ -27,6 +27,7 @@ class Node: def setCost(self, cost): self.cost = cost + return self def __lt__(self, other): return self.getState() < other.getState() \ No newline at end of file diff --git a/classes/Trash.py b/classes/Trash.py index dbbe399..6cacaff 100644 --- a/classes/Trash.py +++ b/classes/Trash.py @@ -3,6 +3,13 @@ typelist = ["paper", "metals_and_plastics", "mixed", "bio_waste", "glass"] class Trash: + def getTreetype(self): + return self.treetype + + def setTreetype(self, treetype): + self.treetype = id + return self + def getTtype(self): return self.ttype @@ -27,6 +34,7 @@ class Trash: class Papier(Trash): def __init__(self): + self.treetype = 1 self.ttype = "Papier" self.waga = 2 self.image = None @@ -34,6 +42,7 @@ class Papier(Trash): class MetalPlastik(Trash): def __init__(self): + self.treetype = 2 self.ttype = "MetalPlastik" self.waga = 3 self.image = None @@ -41,6 +50,7 @@ class MetalPlastik(Trash): class Mixed(Trash): def __init__(self): + self.treetype = 4 self.ttype = "Mixed" self.waga = 1 self.image = None @@ -48,6 +58,7 @@ class Mixed(Trash): class Bio(Trash): def __init__(self): + self.treetype = 0 self.ttype = "Bio" self.waga = 2 self.image = None @@ -55,6 +66,7 @@ class Bio(Trash): class Szklo(Trash): def __init__(self): + self.treetype = 3 self.ttype = "Szklo" self.waga = 5 self.image = None diff --git a/classes/drzewo.joblib b/classes/drzewo.joblib new file mode 100644 index 0000000..68021ec Binary files /dev/null and b/classes/drzewo.joblib differ diff --git a/classes/wyuczone_drzewo.txt b/classes/wyuczone_drzewo.txt new file mode 100644 index 0000000..854a1c7 --- /dev/null +++ b/classes/wyuczone_drzewo.txt @@ -0,0 +1,67 @@ +|--- zapelnienie_kosza <= 0.50 +| |--- czy_zaplacone <= 0.50 +| | |--- class: 0 +| |--- czy_zaplacone > 0.50 +| | |--- pora_dnia <= 1.50 +| | | |--- dni_od_ostatniego_wywozu <= 15.00 +| | | | |--- typ_smieci <= 1.00 +| | | | | |--- class: 1 +| | | | |--- typ_smieci > 1.00 +| | | | | |--- pora_dnia <= 0.50 +| | | | | | |--- class: 0 +| | | | | |--- pora_dnia > 0.50 +| | | | | | |--- dni_od_ostatniego_wywozu <= 9.50 +| | | | | | | |--- zapelnienie_smieciarki <= 0.50 +| | | | | | | | |--- class: 0 +| | | | | | | |--- zapelnienie_smieciarki > 0.50 +| | | | | | | | |--- pora_roku <= 2.00 +| | | | | | | | | |--- class: 0 +| | | | | | | | |--- pora_roku > 2.00 +| | | | | | | | | |--- class: 1 +| | | | | | |--- dni_od_ostatniego_wywozu > 9.50 +| | | | | | | |--- class: 1 +| | | |--- dni_od_ostatniego_wywozu > 15.00 +| | | | |--- dni_od_ostatniego_wywozu <= 26.50 +| | | | | |--- class: 1 +| | | | |--- dni_od_ostatniego_wywozu > 26.50 +| | | | | |--- class: 0 +| | |--- pora_dnia > 1.50 +| | | |--- class: 1 +|--- zapelnienie_kosza > 0.50 +| |--- zapelnienie_kosza <= 1.50 +| | |--- class: 0 +| |--- zapelnienie_kosza > 1.50 +| | |--- zapelnienie_smieciarki <= 0.50 +| | | |--- pora_dnia <= 0.50 +| | | | |--- class: 0 +| | | |--- pora_dnia > 0.50 +| | | | |--- pora_dnia <= 1.50 +| | | | | |--- class: 1 +| | | | |--- pora_dnia > 1.50 +| | | | | |--- dni_od_ostatniego_wywozu <= 29.50 +| | | | | | |--- class: 0 +| | | | | |--- dni_od_ostatniego_wywozu > 29.50 +| | | | | | |--- class: 1 +| | |--- zapelnienie_smieciarki > 0.50 +| | | |--- pora_dnia <= 0.50 +| | | | |--- warunki_pogodowe <= 0.50 +| | | | | |--- class: 0 +| | | | |--- warunki_pogodowe > 0.50 +| | | | | |--- dni_od_ostatniego_wywozu <= 5.50 +| | | | | | |--- class: 0 +| | | | | |--- dni_od_ostatniego_wywozu > 5.50 +| | | | | | |--- class: 1 +| | | |--- pora_dnia > 0.50 +| | | | |--- warunki_pogodowe <= 1.50 +| | | | | |--- class: 1 +| | | | |--- warunki_pogodowe > 1.50 +| | | | | |--- pora_roku <= 2.50 +| | | | | | |--- dni_od_ostatniego_wywozu <= 23.00 +| | | | | | | |--- class: 1 +| | | | | | |--- dni_od_ostatniego_wywozu > 23.00 +| | | | | | | |--- dni_od_ostatniego_wywozu <= 29.50 +| | | | | | | | |--- class: 0 +| | | | | | | |--- dni_od_ostatniego_wywozu > 29.50 +| | | | | | | | |--- class: 1 +| | | | | |--- pora_roku > 2.50 +| | | | | | |--- class: 0 diff --git a/generators.py b/generators.py index 416a553..07f51a8 100644 --- a/generators.py +++ b/generators.py @@ -36,9 +36,18 @@ def trashcanGenerator(mult) -> list: def householdGenerator(mult): new_house_size = (mult, mult) - house_positions = [(15, 5), (17, 5), (19, 5), (21, 5), (15, 8), (17, 8), (19, 8), (21, 8)] + temp = [] + for i in range(1, 29): + if i % 2 == 1: + temp.append((i, 6)) + temp.append((i, 12)) + elif i % 2 == 0: + temp.append((i, 9)) + if i % 2 == 1 and i % 4 != 1: + temp.append((i, 10)) + house_positions = temp houses = [] - for i in range(8): + for i in range(len(house_positions)): house_image = pygame.image.load(f'sprites/domek.png') house_image = pygame.transform.scale(house_image, new_house_size) house = generateHousehold(mult, i, house_image, house_positions[i]) diff --git a/main.py b/main.py index 6e0fec1..b8658d3 100644 --- a/main.py +++ b/main.py @@ -9,7 +9,7 @@ MULT = 50 SIZE = (MULT*W, MULT*H) pygame.init() screen = pygame.display.set_mode(SIZE) -tilemap = Tilemap(Tileset("sprites/TIles/1Tiles/FieldsTile_38.png", mult=MULT), mult=MULT, size=(W, H)) +tilemap = Tilemap(Tileset("sprites/TIles/1 Tiles/FieldsTile_38.png", mult=MULT), mult=MULT, size=(W, H)) targimage = pygame.image.load("sprites/X.png").convert_alpha() targimage = pygame.transform.scale(targimage, (MULT, MULT)) @@ -17,13 +17,16 @@ trashcans = trashcanGenerator(MULT) houses = householdGenerator(MULT) garbagetruck = Garbagetruck(MULT).setHouses(houses).setTrashcans(trashcans) +print("Kolejność danych do drzewa:") +print("Pora roku - Pora dnia - Typ śmieci - Zapełnienie kosza - Zapełnienie śmieciarki - Zapłacone - Ostatnio zabrane " + "- Pogoda") + running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False - print(garbagetruck.movesequence) garbagetruck.setTarget() garbagetruck.executeMovement() screen.fill((0, 0, 0)) @@ -33,7 +36,6 @@ while running: screen.blit(i.getImage(), i.printme()) for h in houses: screen.blit(h.getImage(), h.printme()) - print(garbagetruck.getPosition()) bruh = garbagetruck.target.getPosition() bruhlist = [i*MULT for i in bruh] screen.blit(targimage, bruhlist) @@ -41,15 +43,19 @@ while running: pygame.display.update() garbagetruck.scanTile() state = garbagetruck.getState() + while garbagetruck.getAnalising(): + garbagetruck.pickTrash() if not garbagetruck.movesequence: moves = garbagetruck.graphsearch() garbagetruck.setMovesequence(moves) if state: if state.getFinal(): + print([trash.getTtype() for trash in state.getGarbage().getContent()]) + garbagetruck.switchAnalising() garbagetruck.getState().switchFinal() elif not garbagetruck.movesequence: garbagetruck.randomTarget() time.sleep(0.5) -pygame.quit() \ No newline at end of file +pygame.quit() diff --git a/słownik_danych.txt b/słownik_danych.txt new file mode 100644 index 0000000..60d98b8 --- /dev/null +++ b/słownik_danych.txt @@ -0,0 +1,37 @@ +pora_roku: +0: jesien +1: lato +2: wiosna +3: zima + +pora_dnia: +0: noc +1: popoludnie +2: rano +3: wieczor + +typ_smieci: +0: bio odpady +1: papier +2: plastik i metale +3: szklo +4: zmieszane + +zapelnienie_kosza: +0: pelny +1: pusty +2: srednio zapelniony + +zapelnienie_smieciarki: +0: pelna +1: pusta +2: srednio zapelniona + +czy_zaplacone: +0: nie +1: tak + +warunki_pogodowe: +0: dobre +1: umiarkowane +2: zle \ No newline at end of file