From 55baf245139e9cc4bd820a6f54bac831b25221ac Mon Sep 17 00:00:00 2001 From: Mateusz Date: Fri, 26 May 2023 19:08:22 +0200 Subject: [PATCH] updated agent to collect garbage --- .idea/.gitignore | 3 - __pycache__/astar.cpython-310.pyc | Bin 990 -> 0 bytes __pycache__/bfs.cpython-310.pyc | Bin 710 -> 0 bytes __pycache__/garbage_truck.cpython-310.pyc | Bin 1744 -> 0 bytes __pycache__/heuristicfn.cpython-310.pyc | Bin 340 -> 0 bytes __pycache__/main.cpython-310.pyc | Bin 2616 -> 0 bytes __pycache__/state.cpython-310.pyc | Bin 697 -> 0 bytes __pycache__/succ.cpython-310.pyc | Bin 1456 -> 0 bytes astar.py | 23 ------ collect | 22 +++--- collect.pdf | Bin 13985 -> 14067 bytes garbage_truck.py | 83 +++++++++++++++++---- home.py | 4 - litter.py | 8 -- main.py | 87 ++++------------------ map.py | 44 +++++++++++ request.py | 13 ++++ succ.py | 32 ++++---- treelearn.py | 20 +++++ 19 files changed, 190 insertions(+), 149 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 __pycache__/astar.cpython-310.pyc delete mode 100644 __pycache__/bfs.cpython-310.pyc delete mode 100644 __pycache__/garbage_truck.cpython-310.pyc delete mode 100644 __pycache__/heuristicfn.cpython-310.pyc delete mode 100644 __pycache__/main.cpython-310.pyc delete mode 100644 __pycache__/state.cpython-310.pyc delete mode 100644 __pycache__/succ.cpython-310.pyc delete mode 100644 home.py delete mode 100644 litter.py create mode 100644 map.py create mode 100644 request.py create mode 100644 treelearn.py diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/__pycache__/astar.cpython-310.pyc b/__pycache__/astar.cpython-310.pyc deleted file mode 100644 index 42aa76a6d268a4bb9cc8921e9b9f384a169d91f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 990 zcmZuwO=}b}7*1xA`Pj}@i-Kq`ew@~W+oOnzpcM2_D!na82|MX_c4u~`Nw#z$14{ch zgf5=^E&hXCJ@qFjRD3cm*n=7Jemw7I@@DFOzeljne(mKyI3Yj1a&rYx-eBu3keuYS zBo!G^>gAves&Eu`a#*s8k2qwO^D{Dv@@S6?;tNEP0d-6-#$)jQt}1F(nB~WXTu1X@uE26)FvlVG$8&A2Vvp~Io z6xpDYqVqVXHeLmk08Mf-3)OQk!T&!t{nVm$liJvZmfGNywTb2Dy)L)U8c)}-vjgUP zvB^8~X{SwXipnXhDXgitwmsXk{Fo?lwCnvndXKbgrjN|&bRGL&gpav(8n^JWYKv?$$6* z7=$V6xl5Ys`6@qA7m0BPr-yQ(3T=w9<44`(`$(+)=pCQbqCB}`OP4i5Yng8svdmHZ zKo#?ebcsA^%38_XacyLyJ@c`#EM?`p;>V&~NEd=RHmq-tQG1JScC<`$k>Z*|ALa3P-zMmUe784|#i~Sq8KsEKOSvuZH_)m!528n2oMwHP6 z-(8w@8t5Mut_Ke~ETI8#Z})!evd3T#9zuiVb8wkluub&@sdfgj^8cFhuV3Bq#1BYq idgAZ0^Xd+9gFJ@8B`>QwUzGB-pR7(mGLoTc7W@T@(*rC3 diff --git a/__pycache__/bfs.cpython-310.pyc b/__pycache__/bfs.cpython-310.pyc deleted file mode 100644 index 6cd41fc78b2a22ce17a38a9563ed9dc2ade24751..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 710 zcmZuvyN(kv6!mjnNdyIAp@wECh!7h`W@W?T9?${nyJ>VgB@db8xOUy%vh$CYZ?Wx2rJ`jvxlu5Lu=0S)c|38|& zxr-hBNQT7meKgJ+W{fZ5H9f%DT=E>fJsDD$!ip&T2HlT^7QI+%)xGT^^ ztLrMCK#7G|dA_MdvHMHCpEkl;B~P^~B$Td=t~SaiYS$FCQPOkUs>TKiwXrHx8P?-h zqUe;TK%bF0fo=YJG=E>0YF>)1?Mq!~QO#|s)k+Jq74w%>s|vk=+De=sjlWyl`%UjD zaCkp^4h>w`dMg}AjePTzv>lmuB>w7z%9~Jwm zkxW#_R3Z=KO|`I_#ls|YCl1w4ygaYWBPI!$KWocdSrRTM-XPykqB!!>Dw8WpY!j9E^?;!S?gnY!Y$$(HVsp#7Ri=y-6RW!G3hPW{WkRC(j!~QqKljobF@bI&^)GdY}Vp>#fLF7CT}1~0p8YH+KUVPKuV|yWJ%c_u4+5kUML+y)?v%5BxqwPbUjpP12d;gxb;GL(CLL`y9ziH zdIb)foR>+E_0MbMPvAXIC1Ph!l)UWKf_h-Xwt@yI)>N$t{`5|M4GAWLbizTPIWy3toomvU{BJ!&?ZLat$Z(>c} zB5?*%dJV!mpNFt`3p}*+4=;0V8jtFId=y;`(kn*L*E?d{XbIQR5EkjuXcG7U&F+{s zj)@~jT-Sj=&5+r0RHGQm)Q!WF4#5*@&Zt~1|g!o2E2DpyyC|M=~&8#2)(8wh*mh1$-59^LJefl&rJ`n_;=NOyRr8E&6kZgpWi9If8p)xo0;76 zWN;fHnhs6g0UgTOF;3f)Zeu5#yG~sabtJJ`Qu{4C(F4*Rk$6nv6lksKMnH5S`sK7_ tGn?BD+iaPV*1L|74*vDWpg#k>d{G`{zbsqgE8g`kg7$C0DfK}5F^Gc(44TZzEI=U`0I^wt z*cph6b$~<(Lk&>16hjRoh?D^8X=Vb7F@eRH5n|#DAhY~l8UgjZ1lgv^c#F9pzg&~$ z7F%&iVo^y2l&-wRnx3DSQvsnWS27fF09F5T*3Zb#P1Vm$%r36X&CJP6%+oK<%}hVn&qysT$}BF)Ois(wE2zB1jl^dJnpzBUhz?^BC~W*R bAvD-JB!UwtcZ77i; diff --git a/__pycache__/main.cpython-310.pyc b/__pycache__/main.cpython-310.pyc deleted file mode 100644 index 6af302422eab42f221324e2ac5ba4c544cdee10a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2616 zcmZWqTW=#p7Ov`>+ik~5Cdo`PS(Xe8AcH0Wg!TatFq7K^4H-y+kPN8RaaBC+wA)T~ zWrsv<3CaA6eQ_T7OZBwUKILtn_l5mV*_jJetE$eW>U7n2F4dozi5Ob&;eqh$jQxk0 zSDOdsEA--1&X{0=XRI}ud5eR0GNd>rCHLF(hH!;(CLo`}{7qhK5cbS+I^S?1M zKXO`Y;+9zWjkWHHMX`kWEpc1i!Th#Z7Au(V%Xh@xQ%C(v-XGCz`JwI2)oVg^zsZez zd{SWY4|Sp?i281#j+2f&Qs?c{rgOdKGNybizIOj_oe z0^xe@W^WtBYs~@o6?(CVK{E1w%Mn~SxV0RFG=(D!G#IqIL%WX$E&baP;>`8;+GA3@bw$zKJJ2* zdD4?{Y@#^s^~HHcbUlvG&Xa7SQ5G#al|9;Im?gG~;V!!UL&)mfN?yaX0yR0w0wX|Z zrnz>s+wq31!-gE)(VpNVzQumNH*{an3qw!)vwqr^#!qu0e=$Ka7|2{SE2egm%1jh-mKNH~SSC)CN-pA$US~fxJT<&)7A6)q zt-YrwkFtLI)XWZ4+E=N*mzz@V%iIfiE9B2u^2(mF@~E8)iqii{NNPl|q#}i_Sb+r`?iu zy)Mwl7)*4!(hbK|TjLPcO>cs43ApiS@`IQE|#?>I{}Qf7C1|Hy{9;lCJu zVS>R$2Z3iQA}t140>Sw}P_00Ip-$x51QXoV8kxRF!^;??@G~``lIQW{KMx=%D1iv7 zce(S&veV#d1A;ak?WPe;-NHnemAHhWnqZALxmv%WU>K2B<1KHVVFkx**`;gby+O zCDuhDx*1d%cLcZThMvV^1gGNjN4^MzJ93dcK5R6RIzboD z4J>?zB$_7|<_lI9LiQtMx2&vcWmU)oWD6vF!DDeCsNVco2%FYJ3&(e!m;Ac|x z{v4Ga72!u%SA2pYLbl$eoOL4JKxlg0`85Q+?1VO>DXSw+be%hngTSr3>TCK7Dl=J% z6gy%!w-nPRV}{y}SJrjKN7AIT|p^a2?FhrO+%$0m5ZP1vgstmQ&#s`XO6 zLu`%Mb~2y`3DvKM>@!~0PlT!3tc~}+*#&y2PX(~*;qUDvlj=Qdipnc3Q1o7!s;#q@ zU$SZ{xR#|_W}->uwSqeks86kQXK(w-*5=di_m50uX?te-mRR3UJWAPSkx}zRy{rY6 yvIQaheDZ>QK_OUtfgxlefUN^ybU;35Ida77-GgI1-f%)cY=pN$H@pYO{qcXU1!#Q$ diff --git a/__pycache__/state.cpython-310.pyc b/__pycache__/state.cpython-310.pyc deleted file mode 100644 index 927e172c331ed437c286156d87409a0f0fb83ba6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 697 zcmY+C&2HN;41g(HcHGoyft>dOz9cWO76o<~cFD!JTm->V8#Vq(B?V{--PS$E9-yzJ z>z<*Poklvyn$qAWks?is_Ar}G0p<65t$s0pKV+OsipCwPnxfYe2*_JX z1&&NYhD<|(yR)bPeu)g_>p@{8Re7DAZbcp>QG?h28!k7vqWuEsenPGJqjorL!P2UemH z;1P%R2wPr*rIU({9ao8^ZymG2Z?qj7KZ25CF2nEos?x!#%Bas?c3Oxy z6`~u|zNLLB#M553#}hllTzgHR$((_zSp3C+)X^LZC|FsHz7_UJ{Rx=_y^7UlDhx^ diff --git a/__pycache__/succ.cpython-310.pyc b/__pycache__/succ.cpython-310.pyc deleted file mode 100644 index d3465fc75de02eb6e777170701bdbb8ce625f5c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1456 zcmb7E%Zl4D6qRJz@i>_>Oat@i7Z^$dT@NK?l5_$gQ<9WGC=?TEGOk}ia$o{36sC(V z`w8u`KhY1-qFr>AeOF!e%9Dr7%*Fy;A6@BQpL6v{_V*nG?bn|n`@DzHZ#^hB0|rg# z@;MlW7!FZ{Cm3r?LK2Y)0c^Y_6JtUd<@ky)lUbkW#AKBra_tqwAr~uin0hG(P`&00 z;mg#YUd1k1>Ab50Fp9`@O7-e>GvWIP`Z;v@5s1vt2b!VxKq4R_&gfU1k_>2o&wx&u zkztJ)Jw+!d_v9!wH!Cud8MpMd@(l!RiM{zxY8?a1lGza316@D2 zymq?E@!Hg7r>k6DKv!y|73LhHItoyMQ9<7kur0062*?*KdJiZpm+QX5vb8q!&i%(F z*QWO^KR0D7hM1LW`|*Iba@_7~D_0vh|Ha({jXO?jjYoGHOP(sY%+AlkV6=8h2Zxi#0yKeA6Gfrm*z%!Q7LQv)96hl&R09GG~bw-rRkb%8`rdluMZi z`5lQ92>E-~xK1M8h`c~9BR}-LxFI8-Pkm1WUZWeQJoIP4F81CP{5sFG`BG60^gAS< zf}z+UP29u|ZmrQFpjz&$ZBZQ%#o`GB^j%AtQonn--dv-23=^WRjb4(oESOX9Df=u+ T*dpXFbOogiriN 10 ; 11 [label="garbage_weight <= 0.612\ngini = 0.094\nsamples = 61\nvalue = [3, 58]\nclass = no-collect"] ; 10 -> 11 ; -12 [label="odour_intensity <= 5.682\ngini = 0.5\nsamples = 2\nvalue = [1, 1]\nclass = collect"] ; +12 [label="distance <= 10.5\ngini = 0.5\nsamples = 2\nvalue = [1, 1]\nclass = collect"] ; 11 -> 12 ; 13 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]\nclass = collect"] ; 12 -> 13 ; @@ -36,7 +36,7 @@ edge [fontname="helvetica"] ; 15 -> 16 ; 17 [label="garbage_weight <= 15.925\ngini = 0.26\nsamples = 13\nvalue = [2, 11]\nclass = no-collect"] ; 15 -> 17 ; -18 [label="fuel <= 13561.0\ngini = 0.444\nsamples = 3\nvalue = [2, 1]\nclass = collect"] ; +18 [label="odour_intensity <= 5.724\ngini = 0.444\nsamples = 3\nvalue = [2, 1]\nclass = collect"] ; 17 -> 18 ; 19 [label="gini = 0.0\nsamples = 2\nvalue = [2, 0]\nclass = collect"] ; 18 -> 19 ; @@ -54,11 +54,11 @@ edge [fontname="helvetica"] ; 23 -> 25 ; 26 [label="gini = 0.0\nsamples = 6\nvalue = [6, 0]\nclass = collect"] ; 25 -> 26 ; -27 [label="distance <= 7.0\ngini = 0.5\nsamples = 2\nvalue = [1, 1]\nclass = collect"] ; +27 [label="space_occupied <= 0.936\ngini = 0.5\nsamples = 2\nvalue = [1, 1]\nclass = collect"] ; 25 -> 27 ; -28 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]\nclass = collect"] ; +28 [label="gini = 0.0\nsamples = 1\nvalue = [0, 1]\nclass = no-collect"] ; 27 -> 28 ; -29 [label="gini = 0.0\nsamples = 1\nvalue = [0, 1]\nclass = no-collect"] ; +29 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]\nclass = collect"] ; 27 -> 29 ; 30 [label="odour_intensity <= 7.156\ngini = 0.292\nsamples = 107\nvalue = [88, 19]\nclass = collect"] ; 0 -> 30 [labeldistance=2.5, labelangle=-45, headlabel="False"] ; @@ -88,14 +88,18 @@ edge [fontname="helvetica"] ; 40 -> 42 ; 43 [label="gini = 0.0\nsamples = 8\nvalue = [0, 8]\nclass = no-collect"] ; 42 -> 43 ; -44 [label="distance <= 24.0\ngini = 0.48\nsamples = 10\nvalue = [4, 6]\nclass = no-collect"] ; +44 [label="days_since_last_collection <= 20.0\ngini = 0.48\nsamples = 10\nvalue = [4, 6]\nclass = no-collect"] ; 42 -> 44 ; 45 [label="gini = 0.0\nsamples = 2\nvalue = [2, 0]\nclass = collect"] ; 44 -> 45 ; -46 [label="space_occupied <= 0.243\ngini = 0.375\nsamples = 8\nvalue = [2, 6]\nclass = no-collect"] ; +46 [label="paid_on_time <= 0.5\ngini = 0.375\nsamples = 8\nvalue = [2, 6]\nclass = no-collect"] ; 44 -> 46 ; -47 [label="gini = 0.0\nsamples = 2\nvalue = [2, 0]\nclass = collect"] ; +47 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]\nclass = collect"] ; 46 -> 47 ; -48 [label="gini = 0.0\nsamples = 6\nvalue = [0, 6]\nclass = no-collect"] ; +48 [label="space_occupied <= 0.243\ngini = 0.245\nsamples = 7\nvalue = [1, 6]\nclass = no-collect"] ; 46 -> 48 ; +49 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]\nclass = collect"] ; +48 -> 49 ; +50 [label="gini = 0.0\nsamples = 6\nvalue = [0, 6]\nclass = no-collect"] ; +48 -> 50 ; } diff --git a/collect.pdf b/collect.pdf index 0bc379927db21cbde9a5f095addac35482cbcb4f..2f2f23cad3af0a06e164d3f945efc105fcfd11bd 100644 GIT binary patch delta 12187 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 IvJ}$)0dX>`xBvhE diff --git a/garbage_truck.py b/garbage_truck.py index 9998400..af0e228 100644 --- a/garbage_truck.py +++ b/garbage_truck.py @@ -1,31 +1,38 @@ +from heuristicfn import heuristicfn + FIELDWIDTH = 50 +TURN_FUEL_COST = 10 +MOVE_FUEL_COST = 200 +MAX_FUEL = 20000 +MAX_SPACE = 5 +MAX_WEIGHT = 200 -class GarbageTank: - def __init__(self, volume_capacity, mass_capacity): - self.vcapacity = volume_capacity #m^3 - self.mcapacity = mass_capacity #kg - -class Engine: - def __init__(self, power): - self.power = power #HP class GarbageTruck: - def __init__(self, dump_location, fuel_capacity, rect, orientation): - self.dump_location = dump_location - self.tank = GarbageTank(15, 18000) - self.engine = Engine(400) - self.fuel = fuel_capacity + + garbage_types = {'bio': 0, 'electronics': 1, 'mixed': 2, 'recyclable': 3} + + def __init__(self, dump_x, dump_y, rect, orientation, request_list: list, clf): + self.dump_x = dump_x + self.dump_y = dump_y + self.fuel = MAX_FUEL + self.free_space = MAX_SPACE + self.weight_capacity = MAX_WEIGHT self.rect = rect self.orientation = orientation - self.houses = [] #lista domów do odwiedzenia + self.request_list = request_list #lista domów do odwiedzenia + self.clf = clf def turn_left(self): self.orientation = (self.orientation - 1) % 4 + self.fuel -= TURN_FUEL_COST def turn_right(self): self.orientation = (self.orientation + 1) % 4 + self.fuel -= TURN_FUEL_COST def forward(self): + self.fuel -= MOVE_FUEL_COST if self.orientation == 0: self.rect.x += FIELDWIDTH elif self.orientation == 1: @@ -33,4 +40,50 @@ class GarbageTruck: elif self.orientation == 2: self.rect.x -= FIELDWIDTH else: - self.rect.y -= FIELDWIDTH \ No newline at end of file + self.rect.y -= FIELDWIDTH + + def next_destination(self): + if self.fuel <= 0 or not self.request_list: + return self.dump_x, self.dump_y + + for i in range(len(self.request_list)): + request = self.request_list[i] + + #nie ma miejsca w zbiorniku lub za ciężkie śmieci + if request.volume > self.free_space or request.weight > self.weight_capacity: + continue + + #nie straczy paliwa na dojechanie i powrót na wysypisko + if heuristicfn(request.x_pos, request.y_pos, self.dump_x, self.dump_y) / 50 * 200 > self.fuel: + continue + + + + distance = heuristicfn(self.rect.x, self.rect.y, request.x_pos, request.y_pos) / 50 + + r = [ + self.fuel, + distance, + request.volume, + request.last_collection, + request.is_paid, + request.odour_intensity, + request.weight, + request.type + ] + if self.clf.predict([r]) == True: + self.request_list.pop(i) + self.free_space -= request.volume + self.weight_capacity -= request.weight + return request.x_pos, request.y_pos + return self.dump_x, self.dump_y + + + + def collect(self): + if self.rect.x == self.dump_x and self.rect.y == self.dump_y: + self.fuel = MAX_WEIGHT + self.free_space = MAX_SPACE + self.weight_capacity = MAX_WEIGHT + print(f'agent at ({self.rect.x}, {self.rect.y}); fuel: {self.fuel}; free space: {self.free_space}; weight capacity: {self.weight_capacity}') + pass \ No newline at end of file diff --git a/home.py b/home.py deleted file mode 100644 index e795dfc..0000000 --- a/home.py +++ /dev/null @@ -1,4 +0,0 @@ -class Home: - def __init__(self, coord): - self.coord = coord - self.collect_request = False \ No newline at end of file diff --git a/litter.py b/litter.py deleted file mode 100644 index 6dc9dd9..0000000 --- a/litter.py +++ /dev/null @@ -1,8 +0,0 @@ -class Litter: - - types = ['PAPER', 'GLASS', 'PLASTIC', 'METAL', 'BIO', 'MUNICIPAL', 'ELECTRONICS'] - - def __init__(self, type, volume, mass): - self.type = type - self.volume = volume - self.mass = mass diff --git a/main.py b/main.py index 3123f69..e37f883 100644 --- a/main.py +++ b/main.py @@ -1,9 +1,5 @@ import pygame -import random -import pandas as pd -from sklearn import tree -from sklearn.preprocessing import LabelEncoder -import graphviz +from treelearn import treelearn from astar import astar @@ -11,6 +7,7 @@ from state import State import time from garbage_truck import GarbageTruck from heuristicfn import heuristicfn +from map import randomize_map pygame.init() WIDTH, HEIGHT = 800, 800 @@ -18,52 +15,12 @@ window = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Intelligent Garbage Collector") AGENT_IMG = pygame.image.load("garbage-truck-nbg.png") AGENT = pygame.transform.scale(AGENT_IMG, (50, 50)) -DIRT_IMG = pygame.image.load("dirt.jpg") -DIRT = pygame.transform.scale(DIRT_IMG, (50, 50)) -GRASS_IMG = pygame.image.load("grass.png") -GRASS = pygame.transform.scale(GRASS_IMG, (50, 50)) -SAND_IMG = pygame.image.load("sand.jpeg") -SAND = pygame.transform.scale(SAND_IMG, (50, 50)) -COBBLE_IMG = pygame.image.load("cobble.jpeg") -COBBLE = pygame.transform.scale(COBBLE_IMG, (50, 50)) FPS = 10 FIELDCOUNT = 16 FIELDWIDTH = 50 - -class Agent: - def __init__(self, rect, direction): - self.rect = rect - self.direction = direction - - -def randomize_map(): # tworzenie mapy z losowymi polami - field_array_1 = [] - field_array_2 = [] - field_priority = [] - for i in range(16): - temp_priority = [] - for j in range(16): - if i in (0, 1) and j in (0, 1): - field_array_2.append(GRASS) - temp_priority.append(1) - else: - prob = random.uniform(0, 100) - if 0 <= prob <= 12: - field_array_2.append(COBBLE) - temp_priority.append(3) - elif 12 < prob <= 24: - field_array_2.append(SAND) - temp_priority.append(2) - else: - field_array_2.append(GRASS) - temp_priority.append(1) - field_array_1.append(field_array_2) - field_array_2 = [] - field_priority.append(temp_priority) - return field_array_1, field_priority - - +GRASS_IMG = pygame.image.load("grass.png") +GRASS = pygame.transform.scale(GRASS_IMG, (50, 50)) def draw_window(agent, fields, flip): if flip: direction = pygame.transform.flip(AGENT, True, False) @@ -77,35 +34,22 @@ def draw_window(agent, fields, flip): def main(): - train_data = pd.read_csv('./data_set.csv') - attributes = train_data.drop('collect', axis='columns') - e_type = LabelEncoder() - attributes['type_num'] = e_type.fit_transform(attributes['garbage_type']) - attr_encoded = attributes.drop(['garbage_type'], axis='columns') - attr_names = ['fuel','distance','space_occupied','days_since_last_collection','paid_on_time','odour_intensity','garbage_weight', 'garbage_type'] - label_names = ['collect', 'no-collect'] - label = train_data['collect'] - print(attr_encoded) - print(label) - classifier = tree.DecisionTreeClassifier() - classifier.fit(attr_encoded, label) - dot_data = tree.export_graphviz(classifier, out_file=None, feature_names=attr_names, class_names=label_names) - graph = graphviz.Source(dot_data) - graph.render('collect') + clf = treelearn() clock = pygame.time.Clock() run = True - x, y = [0, 0] - agent = GarbageTruck(0, 0, pygame.Rect(x, y, 50, 50), 0) # tworzenie pola dla agenta - fields, priority_array = randomize_map() - final_x, final_y = [100, 300] + fields, priority_array, request_list = randomize_map() + agent = GarbageTruck(0, 0, pygame.Rect(0, 0, 50, 50), 0, request_list, clf) # tworzenie pola dla agenta while run: clock.tick(FPS) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False - # keys_pressed = pygame.key.get_pressed() draw_window(agent, fields, False) # false = kierunek east (domyslny), true = west - steps = astar(State(None, None, x, y, 'E', priority_array[0][0], heuristicfn(x, y, final_x, final_y)), final_x, final_y, priority_array) + x, y = agent.next_destination() + if x == agent.rect.x and y == agent.rect.y: + print('out of jobs') + break + steps = astar(State(None, None, agent.rect.x, agent.rect.y, agent.orientation, priority_array[0][0], heuristicfn(agent.rect.x, agent.rect.y, x, y)), x, y, priority_array) for interm in steps: if interm.action == 'LEFT': agent.turn_left() @@ -121,10 +65,11 @@ def main(): draw_window(agent, fields, True) else: draw_window(agent, fields, False) - time.sleep(0.5) + time.sleep(0.3) + agent.collect() + fields[agent.rect.x//50][agent.rect.y//50] = GRASS + time.sleep(0.5) - while True: - pass pygame.quit() diff --git a/map.py b/map.py new file mode 100644 index 0000000..f155c2b --- /dev/null +++ b/map.py @@ -0,0 +1,44 @@ +import pygame, random +from request import Request + +DIRT_IMG = pygame.image.load("dirt.jpg") +DIRT = pygame.transform.scale(DIRT_IMG, (50, 50)) +GRASS_IMG = pygame.image.load("grass.png") +GRASS = pygame.transform.scale(GRASS_IMG, (50, 50)) +SAND_IMG = pygame.image.load("sand.jpeg") +SAND = pygame.transform.scale(SAND_IMG, (50, 50)) +COBBLE_IMG = pygame.image.load("cobble.jpeg") +COBBLE = pygame.transform.scale(COBBLE_IMG, (50, 50)) + +def randomize_map(): # tworzenie mapy z losowymi polami + request_list = [] + field_array_1 = [] + field_array_2 = [] + field_priority = [] + for i in range(16): + temp_priority = [] + for j in range(16): + if i in (0, 1) and j in (0, 1): + field_array_2.append(GRASS) + temp_priority.append(1) + else: + prob = random.uniform(0, 100) + if 0 <= prob <= 12: + field_array_2.append(COBBLE) + temp_priority.append(100) + request_list.append(Request( + i*50,j*50, #lokacja + random.randint(0,3), #typ śmieci + random.random(), #objętość śmieci + random.randint(0,30), #ostatni odbiór + random.randint(0,1), #czy opłacone w terminie + random.random() * 10, #intensywność odoru + random.random() * 50 #waga śmieci + )) + else: + field_array_2.append(GRASS) + temp_priority.append(1) + field_array_1.append(field_array_2) + field_array_2 = [] + field_priority.append(temp_priority) + return field_array_1, field_priority, request_list \ No newline at end of file diff --git a/request.py b/request.py new file mode 100644 index 0000000..9064eb8 --- /dev/null +++ b/request.py @@ -0,0 +1,13 @@ +from dataclasses import dataclass + +@dataclass +class Request: + def __init__(self, x_pos, y_pos, type, volume, last_collection, is_paid, odour_intensity, weight): + self.x_pos = x_pos + self.y_pos = y_pos + self.type = type + self.volume = volume + self.last_collection = last_collection + self.is_paid = is_paid + self.odour_intensity = odour_intensity + self.weight = weight \ No newline at end of file diff --git a/succ.py b/succ.py index 8773dcd..07f73fa 100644 --- a/succ.py +++ b/succ.py @@ -5,27 +5,27 @@ FIELDWIDTH, FIELDCOUNT = 50, 16 def succ(st: State, passedPriorities, goalx, goaly): successors = [] - if st.orientation == 'N': - successors.append(State(st, 'LEFT', st.xpos, st.ypos, 'W', passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) - successors.append(State(st, 'RIGHT', st.xpos, st.ypos, 'E', passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) + if st.orientation == 3: + successors.append(State(st, 'LEFT', st.xpos, st.ypos, 2, passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) + successors.append(State(st, 'RIGHT', st.xpos, st.ypos, 0, passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) if st.ypos > 0: - successors.append(State(st, 'FORWARD', st.xpos, st.ypos - FIELDWIDTH , 'N', passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) + successors.append(State(st, 'FORWARD', st.xpos, st.ypos - FIELDWIDTH , 3, passedPriorities[st.xpos//50][st.ypos//50 - 1], heuristicfn(st.xpos, st.ypos - 50, goalx, goaly))) - if st.orientation == 'S': - successors.append(State(st, 'LEFT', st.xpos, st.ypos, 'E', passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) - successors.append(State(st,'RIGHT', st.xpos, st.ypos, 'W', passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) + if st.orientation == 1: + successors.append(State(st, 'LEFT', st.xpos, st.ypos, 0, passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) + successors.append(State(st,'RIGHT', st.xpos, st.ypos, 2, passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) if st.ypos < FIELDWIDTH * (FIELDCOUNT - 1): - successors.append(State(st, 'FORWARD', st.xpos, st.ypos + FIELDWIDTH , 'S', passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) + successors.append(State(st, 'FORWARD', st.xpos, st.ypos + FIELDWIDTH , 1, passedPriorities[st.xpos//50][st.ypos//50 + 1], heuristicfn(st.xpos, st.ypos + 50, goalx, goaly))) - if st.orientation == 'W': - successors.append(State(st, 'LEFT', st.xpos, st.ypos, 'S', passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) - successors.append(State(st,'RIGHT', st.xpos, st.ypos, 'N', passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) + if st.orientation == 2: + successors.append(State(st, 'LEFT', st.xpos, st.ypos, 1, passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) + successors.append(State(st,'RIGHT', st.xpos, st.ypos, 3, passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) if st.xpos > 0: - successors.append(State(st, 'FORWARD', st.xpos - FIELDWIDTH , st.ypos, 'W', passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) + successors.append(State(st, 'FORWARD', st.xpos - FIELDWIDTH , st.ypos, 2, passedPriorities[st.xpos//50 - 1][st.ypos//50], heuristicfn(st.xpos - 50, st.ypos, goalx, goaly))) - if st.orientation == 'E': - successors.append(State(st, 'LEFT', st.xpos, st.ypos, 'N', passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) - successors.append(State(st, 'RIGHT', st.xpos, st.ypos, 'S', passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) + if st.orientation == 0: + successors.append(State(st, 'LEFT', st.xpos, st.ypos, 3, passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) + successors.append(State(st, 'RIGHT', st.xpos, st.ypos, 1, passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) if st.xpos < FIELDWIDTH * (FIELDCOUNT - 1): - successors.append(State(st, 'FORWARD', st.xpos + FIELDWIDTH , st.ypos, 'E', passedPriorities[st.xpos//50][st.ypos//50], heuristicfn(st.xpos, st.ypos, goalx, goaly))) + successors.append(State(st, 'FORWARD', st.xpos + FIELDWIDTH , st.ypos, 0, passedPriorities[st.xpos//50 + 1][st.ypos//50], heuristicfn(st.xpos + 50, st.ypos, goalx, goaly))) return successors diff --git a/treelearn.py b/treelearn.py new file mode 100644 index 0000000..7d20976 --- /dev/null +++ b/treelearn.py @@ -0,0 +1,20 @@ +import pandas as pd +from sklearn import tree +from sklearn.preprocessing import LabelEncoder +import graphviz + +def treelearn(): + train_data = pd.read_csv('./data_set.csv') + attributes = train_data.drop('collect', axis='columns') + e_type = LabelEncoder() + attributes['type_num'] = e_type.fit_transform(attributes['garbage_type']) + attr_encoded = attributes.drop(['garbage_type'], axis='columns') + attr_names = ['fuel','distance','space_occupied','days_since_last_collection','paid_on_time','odour_intensity','garbage_weight', 'garbage_type'] + label_names = ['collect', 'no-collect'] + label = train_data['collect'] + classifier = tree.DecisionTreeClassifier() + classifier.fit(attr_encoded.values, label) + dot_data = tree.export_graphviz(classifier, out_file=None, feature_names=attr_names, class_names=label_names) + graph = graphviz.Source(dot_data) + graph.render('collect') + return classifier \ No newline at end of file