From 88eff2c4b78e02fc61b277e4c619996e4d722f8b Mon Sep 17 00:00:00 2001 From: s473575 Date: Wed, 31 May 2023 21:03:00 +0200 Subject: [PATCH] Final A* --- src/__pycache__/agent.cpython-311.pyc | Bin 0 -> 12477 bytes src/__pycache__/simulation.cpython-311.pyc | Bin 0 -> 18976 bytes src/agent.py | 291 +++++++++------------ 3 files changed, 125 insertions(+), 166 deletions(-) create mode 100644 src/__pycache__/agent.cpython-311.pyc create mode 100644 src/__pycache__/simulation.cpython-311.pyc diff --git a/src/__pycache__/agent.cpython-311.pyc b/src/__pycache__/agent.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5b84d519a7e6d1d18ef9fa773c6feeb5a8b1be6 GIT binary patch literal 12477 zcmcIKTWlNGl{0*aPmu~KiF#R2+oEK>Y|D-<$&Xrc?8H{$D7Ir+4#8+BnX+DqTGesGKq_-fOjD*Qa}Y#AXxNch8Vzu0R#wGbg}+f(CaMF_GkB; zJLGVN@~eyXYIJy?=bn4-x#ym9?)|09Wv3v-?tPm%-bzvbj)_7r5VR{3~JHL`qChVlF8$GnVgD;}%k02Ibb0@-k9l zgA#j5iIt(psDR@!b}>4c?}_}-`NY#&h}@&X)HuyhKqU=58Iitm6Jvz7CfPK)z=S6Y zqr+xMvl0HE_5!#^#poCngqRXy21pgKQ!yi?)G;#D81)%F8ZgRcE*gr4Wy@lS4bMkq z)8qmd#lE=k>=auDm{=oP%=N2Z0!`zMN!r}xs7YR>B zLTqRvG9L}kMy3Jfd?;ARz7d+>*vW|yW_K^%maV~HWIhrN2A5qpwC+L@yXEQt+@Yk( z+JtGvE>+dTk3;hL;m4MMzo$@4O{xQeggO~5kbudcX0QqgF}fJPL2||@)&h|LO-2?l zu*gobc_DfoMunJ~npg*BS%Se?q|lM45ED));3@zBeQxi{?NtBT(X4wnZ{5whAa^ui z#-YuJ=EA|CY!3$K7MP`3j5~wDn@gctrG!N^tOvkn6lq5~WO0%SK>E1-0Pd)NIfKz$ zlcQ8%r_FnE)J~wFLrl+RH6N7hWHn$i;D<5fhe_nBLMWZs7jPN!l`^pg*}AyEMWT^~ zdD(t_VTlU|XCuH`Ml#c^ACR*(066RkcuE;OPRVjPAwlH^oFNV=hS~Nv!TP(T+BW!c zC*UtX;U*TBgMAHw7Xg`DY^0glDoi49!#~#wKs&Pr^X?qA6DaMm)ug(YAc1p>ls~-$ z;2ss#lmX+Zsb4_s3pG_z3+I&teXS`&oQ{FCQ0CDn8(}ZW^hYv%J7AD4x5AUr1y(jj zmlkz=>Q)MZ(S;xs&4$?~K#dc?H3PUqZ8^#lw^ly-;n2#^Pg_${YuA6$wbsSk+wYu` z9OZZ3B*UD9nrbLe{c^cvJ%h{p&f8~oGo*5j!fXs|$f9gg`Q$TNHhmbG=U^k^4&<;` zEiY6QaI5TqV)7|&Ghm0JI8f+UXB3J{`q#@wwSTq^s^+&pyBp%VNp&$1ZgSyPm<=M0 z%T+2dy8H%c#_mCo-~G>I#&)bw!jUbQhk)#a(!EaOURQxdjTQ4SrZ6ZXdG_)hgOZ(l zT{%_&ni&&73u6XYMvgZt14rAqjj;l>Gd7S4cG-LqWwuV-qL3y#Ua3bhL|CZ>%SxD>(Nvc`6VA>2L0%VsU&^vzb0Uo;>Nfs z1}8sqh7uT~a&&QRCHbZsWR5sLE2Yrqy-+GD07|E5s~ z*b!o8J=f4E1Jv1#X;$bt?M*w{BL%9A!QC=tAY<0&!#+~-ll023;6DegRO&P{f=UYs z@v>MM*@NGWTXj;@I)jG?33^)MwwO(~Kh4PDkf#~dlwn65!1Ure`cj5qEyc5=4q%-! zOqqtMYnyR<%&w!WD8KaiMY&$p26K(hNrv(8j1{6c}Hsz^At`PFy| z`cltUz=P^931lX;cx`#S?a`h>9gxrvEuM^k%Tg$NwcfE8*elVl9rxJNeE{xJ)3E=qRm5qXMo#PJ{1d~NTE&_pvoI|px;%F(^{CB{D)wA zOsEWql>u$O5?7QxJeD7$ef${J<;Ud+7yz<~S(;mv&BWXa)XH`)GPg7vLK}?GPwaWw z8D*CyZv+?E$aG|0c1$j@X!!?WP_lWN4J}@mEd&815gjL6rYwhvBg;w<{*J<5i->m*LpWZ44FglGs*FNUJm0}jQOJd8uPArYK1ipV?@ z{)k0}lpUdYV$+iXi$Xqo21_hTN3uQNA&%cQkK_ArVTr~193DMjnihiAMAffy3smH8 zgWd`@iDH{>)pcYJJ~%FRo)A0F3w5Jn-DtujTK!UGHJGm8&p=0pqmc5Wcf%!B*T9cc zs%s!sbCx1+NR>6KL9wz!tnA+~ed!ioKQF%izEJso&WLrM5H9+Lz=UnvTJhuZAC(JM zKlI02{adxI>9ay@w^-YqqpEDjo*?+)n~9O+0m=PZvTx;9ivH1ZVmURIu2{R2WEnaWI6rb=w=%~4(#-~*6!NZzVc zXV$x$_wLTrtzUSsYoj?E7~lf~8y|n&_vLr^3uD>iV?2D9KjbGF@p72I9?4#g@RuW! zzcqbwtvu6`_3z{T`y^leR;54XO4N_S>L_q&CfUZJv2tn6FAkgYt#S04K9femi6 z@5@_XJNWl5{-Inren}X(EDl`euTEqKCisDgEq`6=RGMBpoxZwWasLCM{(#^=DEbd> z&{_Wx!GGkplbfxZp|AFQJ-}an{}0E6Z(R|Njf=;|`458GV?q8{P^zv?x83jfWzRqL z2rUQ1mIHh>ep?+~pY49IJ7rq4rw{zZEmgN<+8%WLy65vAp<_Vo7~re%+uGm%o81qU zS_6W=2dbr+`wQZp0ddc1z8XKNxg}*uS)`h_jOl?}Y#$Qa&+s+)NzH9ovW*qMz+HVa z#jU>m$hSA^+naF+zJsFgAn!YZPwzq(r5GGD<)wE}-9yAIyN5q;Vi8rOz zE?A49^**8X;QGvF#ltziW%z}e9UB)Oc5OBb`%h_V>N0a>#+K6{{+zCF>Su&vz;gT&Xb$h__6oIk&FEMSF$5lc=)c(@Hb|~YjgZf zE_;pRuW`UalD8>+miKnSCsj9Rd=F}W-S~N<5I8CZj`G#`ZS@`eP36N%vX(~$f44HF z%c8I2k*_=J>(0al-;n4V;(bF(QC#$OJ@WNseSPa4#iA1@$!vFI=J@78$d>XMUF)?< z#-Aj2rRZ)>U&^{Wd3Wbl@9|B`S8k#A9kKVFq-oWjIwaQZ6Fgn{YL~O_eY|_$)`>H} zvwvlW3XY$?ojLvBZJ~ZptRECSLx0}(`R~1T_pMLPubu~aVUw)Rgh}y#6nr)yjwrOE ziGBV#MD*^^qJOHWfuhd|w6&F!Epcu&myUL0Wx%+ zMcJ~n$iNx2>{KMTk_ut9YXCrQd#g+Kg2{F$M*&EjE?Jq@{p*Jw9v50qiLIxSCehO* zHSM|YhLv(jtpTyMpXB{1XDc9h!P+#zD(Tk-?8pBGjR|N{0z<3H4TWo@O+!6(#kKiF z|EC#^Rj;e5$;X=DZ-kqIA}6S8J{5yoh+^+*{vhOQaDbjp`~+;bmhQCb-zkg)f0+^; z3%ns3zAAE6sb6G_VoYPece;KHyy+>Svp^5niO|jh|DYA>Mrg@X{Jaq&#%GNX=HrEw z;LK=eOh?Jzb#_WeXnM&ApSOl&gnv&;OJ?@3TSNWqYTN!TSL^S~$9aByHs3R_zx6kV zV9%6|vbe!m^bbG&UkHyMLM&1ad!I#fCSYODVL6e9C<@U+S(FWn({kA*a$T@LFC1md z9C)*XA=!k#dI9NxyTu3-hRdp3;pGZNN@}tqfR{S~bbzRIxL1xmq55rYsFq$y-CUgj z8R@G{^{t*wo5ZHx^$M{G6psVzmo`p5yt3&NPhQ~P9TQK!C-lF^doL!2x7}XR-I(sn zy4!en8;IT%y?Qtmx;vO0l&b4eCs)6nZn+yz#wCCKn(b$`e=dNdVER|wu#Q0aJQt8yBW69ZTZ18N3DQ=x#P^{1i!yepnXaAN7sx43bd z0)M#yG?;7PyEey+;1xQc^EMduno8UlGp4mv5K<8A^c6-`-33Z_;xVOB*V++c<`=b_ zD)Ic&)XE1jIO9GuYIb|T%pL{2vI%_$vV{%f<^=T!FZjR~UR(^%GqC&N5LeVBxtv>? zoCHgKfhDFexnTu2fSO5+Vh&X_#i&(G+G$8Hdz39-tox6U%iRS4JHDo2tu{T9X}*6( ztm#UW!>v4Q_V*KZG+^zLw>d{yY_AiLIE6;#4DW7&Z>ym>-61q|i49#zyX2{TZzn4~x#j zJo&cWHM~{1^U~c>qko6+P#Pk@L%Nefd;PCH*TG{RfHGBw(&`AhHkvbCk9kUS?%=IZ z+&J&nt~yh)%E)!#Qwl-VfJxD8QU77_l1?^H%`SxC@da5=*;#PR%)`?NWew5y5e@6# zVkj$!NS5u&3gQcnUqhNhB^af3Wiqrfly-_u``7!#rheXmpX6;6y>02}{n+|B@!;vr zo8rNA?-jv&B{7^B{-f8Qs`%vf)z=fl@YW&WP`0mDxkCk>O#QsF zeRV2o+^Bc4X{TSmAwj()SlLmAhOMmI-mtB|g;!Gg4XstR;9^CyNIS21N?K}`4O(ha zJ6qziF2luM+_Z9Penh|gaZ3qa4Gl5N|C=Jq%PGRk!2%;0WaDgjo*f2417(UZz?(wZ zKD`i{&GQTzOmcaci$>;vg_s~R33~`LU8EMcyU1G&4n@e%_kCp1FDd#`?%c^TRX3oau**B8Eei+}er*!tqT0fx9NRKwo%&9(E1^IHu~X+H?6x=eiIg4lChXg)49oDdsM z{Qkh^NBlb%zWSKINE}cX!@?V3;nb9PYD#FB0^-~aytQGct%kyqu=m$+TA=4x?={x@ zqKPG?%9E&i!vyCBRkW)0j1Tq~yv-^~A%=z=lU6^(J6ez=K*bkiivUGb+#FSJ#wd-4 z9o{*Vyjp|12O6wOldiscqQy!qGPqf@XzcTX9dRDUT^6%|yevy=EH

3EEa#_SKIS zXtB)TaYX|5wH{!Mv9enf+;&wL@+m4>JnE@fnI4Beg;wFS@7=W&>D%CKOd7rBJHqqZ z;4K@7p%3s@i`+TUD`kKMpAzi|F-xrE{a@Sxb)R{M3)oD0jX&;;Ibu$7nz(daUXZJ} ze(;pmG>A2UU-hs19@Yt+Lt^I;??0AsNmaFC)t-!juk1|Nx4rI^7cGsb|a6Ieo;oUt_ZGEy# zs%n9!X%&YhU){aYyQAqra5Alj#MajZ-x1Mwg!dhhT6@ISL&VinDtV>Pv zzTHWBtGe!|XVRC2`Yy4)OQ`M^tGjtm_qNmb<8wbcm#P=WR&)d2awd@Ux;b^6cHSsoBh%g72{CJDjA! zTS~}0npqZnM@8RJ$f|Eh(?1zW+P3PO(zTh1jUz(+h*%F9fAmzYmZxr|ZwsD2(bLD1 zFV{!8E6L>K4pJUpBDzy7BS#Xk+@WY48kdNZndV$D&FAOOcFZUYkZf(Lpi6i|5w4HzwPnx^LIm7W;=U35LD$A`9dQ64@= z{L)3Ss_&B~?l0W*dG{(g_Tlb~Y;m%?M}Vl8_*&bs%5DG!PlBtUo|3ylcBjMDT6iP3 zT%LC(RPb=KRE`HOUch z!PoQdcFE&gb)<&H`hB9O>yc+5>lxTMFAk0hp0`EM+kD~6xhdyPcZMBV!>-h8eZ`31Wz#Un__|8K)XRi7J%JM!!ygB c;0fk^Q!MbDH_|v=&;NO%lzsDpDr8pw5AetBhX4Qo literal 0 HcmV?d00001 diff --git a/src/__pycache__/simulation.cpython-311.pyc b/src/__pycache__/simulation.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98e4d19ec8bf9f57fabdf7814e2194042bc77014 GIT binary patch literal 18976 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 LPu8g=^5*{mGt6z> literal 0 HcmV?d00001 diff --git a/src/agent.py b/src/agent.py index f4cf648..6f72c71 100644 --- a/src/agent.py +++ b/src/agent.py @@ -3,6 +3,20 @@ import pygame as pg import heapq +class Node: + def __init__(self, state, parent, cost): + self.state = state + self.parent = parent + self.cost = cost + + def __lt__(self, other): + return self.cost < other.cost + +class State: + def __init__(self, position, house_list): + self.position = position + self.house_list = house_list + def vector_to_tuple(vector): tup = (int(vector.x), int(vector.y)) return tup @@ -27,43 +41,42 @@ class Agent: self.weights = {} self.orientation = 90 - # utworzenie grafu dróg - roads_pos = [vector_to_tuple(pos) for pos in self.simulation.state.road_pos_g + self.simulation.state.road_pos_r] + roads_pos = [vector_to_tuple(pos) for pos in + self.simulation.state.road_pos_g + self.simulation.state.road_pos_r] roads_pos.sort() for index, pos in enumerate(roads_pos): if pos[0] < 0 or pos[0] >= 27 or pos[1] < 0 or pos[1] >= 14: continue for another_pos in roads_pos[index:]: - if pos == another_pos or another_pos[0] < 0 or another_pos[0] >= 27 or another_pos[1] < 0 or another_pos[1] >= 14: + if pos == another_pos or another_pos[0] < 0 or another_pos[0] >= 27 or another_pos[1] < 0 or \ + another_pos[1] >= 14: continue - if ((abs(pos[0] - another_pos[0]) == 1 and abs(pos[1] - another_pos[1]) == 0) or (abs(pos[0] - another_pos[0]) == 0 and abs(pos[1] - another_pos[1]) == 1)): + if ((abs(pos[0] - another_pos[0]) == 1 and abs(pos[1] - another_pos[1]) == 0) or ( + abs(pos[0] - another_pos[0]) == 0 and abs(pos[1] - another_pos[1]) == 1)): if pos not in self.graph.keys(): self.graph[pos] = set() if another_pos not in self.graph.keys(): self.graph[another_pos] = set() - if another_pos in self.simulation.state.road_pos_r: + if another_pos in self.simulation.state.road_pos_r: weight = 1 elif another_pos in self.simulation.state.road_pos_g: - weight = 3 + weight = 100 else: weight = 1 self.graph[pos].add(another_pos) self.graph[another_pos].add(pos) - self.weights[(pos,another_pos)] = weight + self.weights[(pos, another_pos)] = weight self.weights[(another_pos, pos)] = weight - - - # dołączenie domów i składowisk do grafu dróg entities = self.simulation.state.entities for entity in entities: entity_pos = vector_to_tuple(entity.position) - for neighbour_pos in [(entity_pos[0]-1, entity_pos[1]), - (entity_pos[0]+1, entity_pos[1]), - (entity_pos[0], entity_pos[1]-1), - (entity_pos[0], entity_pos[1]+1)]: + for neighbour_pos in [(entity_pos[0] - 1, entity_pos[1]), + (entity_pos[0] + 1, entity_pos[1]), + (entity_pos[0], entity_pos[1] - 1), + (entity_pos[0], entity_pos[1] + 1)]: if neighbour_pos[0] < 0 or neighbour_pos[0] >= 27 or neighbour_pos[1] < 0 or neighbour_pos[1] >= 14: continue if neighbour_pos in roads_pos: @@ -77,10 +90,9 @@ class Agent: self.dumps[entity.trash_type] = vector_to_tuple(entity.position) if entity.entity_type == 'house': self.houses[vector_to_tuple(entity.position)] = HousePOI() - - self.path = self.A_star() + + self.path = self.a_star() pass - def update(self): entities = self.simulation.state.entities @@ -90,183 +102,130 @@ class Agent: self.fullness = entity.fullness self.orientation = entity.orientation - def decide_move(self): - move_a = self.path[0] - move = (move_a[0] - self.current_pos[0], move_a[1] - self.current_pos[1]) + if self.path: + move_a = self.path[0] + move = (move_a[0] - self.current_pos[0], move_a[1] - self.current_pos[1]) - if self.orientation == 0: - if move[0] == 0: - if move[1] == -1: - self.path.pop(0) - return pg.Vector2(move) - else: - return 180 - elif move[1] == 0: - if move[0] == -1: - return 270 - else: - return 90 - elif self.orientation == 90: - if move[0] == 0: - if move[1] == -1: - return 0 - else: - return 180 - elif move[1] == 0: - if move[0] == -1: - return 270 - else: - self.path.pop(0) - return pg.Vector2(move) - elif self.orientation == 180: - if move[0] == 0: - if move[1] == -1: - return 0 - else: - self.path.pop(0) - return pg.Vector2(move) - elif move[1] == 0: - if move[0] == -1: - return 270 - else: - return 90 + if self.orientation == 0: + if move[0] == 0: + if move[1] == -1: + self.path.pop(0) + return pg.Vector2(move) + else: + return 180 + elif move[1] == 0: + if move[0] == -1: + return 270 + else: + return 90 + elif self.orientation == 90: + if move[0] == 0: + if move[1] == -1: + return 0 + else: + return 180 + elif move[1] == 0: + if move[0] == -1: + return 270 + else: + self.path.pop(0) + return pg.Vector2(move) + elif self.orientation == 180: + if move[0] == 0: + if move[1] == -1: + return 0 + else: + self.path.pop(0) + return pg.Vector2(move) + elif move[1] == 0: + if move[0] == -1: + return 270 + else: + return 90 + else: + if move[0] == 0: + if move[1] == -1: + return 0 + else: + return 180 + elif move[1] == 0: + if move[0] == -1: + self.path.pop(0) + return pg.Vector2(move) + else: + return 90 else: - if move[0] == 0: - if move[1] == -1: - return 0 - else: - return 180 - elif move[1] == 0: - if move[0] == -1: - self.path.pop(0) - return pg.Vector2(move) - else: - return 90 - - def heuristic(self, start, end): - return abs((end[0][0] - start[0][0])) + abs((end[0][1] - start[0][1])) // (abs(len(start[1]) - len(end[1])) + 1) + return pg.Vector2(0, 0) - def weight_cost(self, start_pos, end_pos): - return self.weights[(start_pos, end_pos)] - - def get_move_cost(self, start_pos, end_pos): - return self.heuristic(start_pos, end_pos) + self.weight_cost(start_pos, end_pos) - - def get_start_state(self): - # entities = self.simulation.state.entities - # orientation - self.orientation - position = self.current_pos - house_list = tuple(self.houses) - start_state = (position, house_list) - return start_state - - def get_end_state(self): - position = (0,1) - house_list = () - end_state = (position, house_list) - return end_state - - def succesor(self, state): + def successors(self, state): successors_pos = self.graph[state[0]] house_list = state[1] - successors = () + successors = [] for pos in successors_pos: if pos in house_list: house_list = list(house_list) house_list.remove(pos) house_list = tuple(house_list) - successors = list(successors) - successors.append((pos, tuple(house_list))) - successors = tuple(successors) - else: - successors = list(successors) - successors.append((pos, tuple(house_list))) - successors = tuple(successors) + successors.append((pos, tuple(house_list))) return successors + def cost(self, current_node, succ_state): + if succ_state[0] not in current_node.state[1]: + cost = current_node.cost + self.weights[current_node.state[0], succ_state[0]] + else: + cost = float(1) + return cost - '''def A_star(self): + def heuristic(self, succ_state, goal_state): + position = succ_state[0] + if len(succ_state[1]) != 0: + estimated_cost = 0 + for house in succ_state[1]: + estimated_cost += abs(position[0] - house[0]) + abs(position[1] - house[1]) + else: + goal_position = goal_state[0] + estimated_cost = abs(position[0] - goal_position[0]) + abs(position[1] - goal_position[1]) + return estimated_cost + + def a_star(self): fringe = [] explored = set() - istate = self.get_start_state() - goaltest = self.get_end_state() - node = (istate, None) - actions = [] + initial_state = (self.current_pos, tuple(self.houses)) + goal_state = (self.current_pos, ()) + start_node = Node(initial_state, None, 0) - heapq.heappush(fringe, (self.heuristic(istate[0], goaltest[0]), node)) + heapq.heappush(fringe, start_node) while fringe: - _, el = heapq.heappop(fringe) - elem = el[0] - parent = el[1] + current_node = heapq.heappop(fringe) - if elem == goaltest: - while parent is not None: - actions.append(elem[0]) - elem = parent - actions.reverse() - return actions + if current_node.state == goal_state: + actions = [] + while current_node: + actions.append(current_node.state[0]) + current_node = current_node.parent + c = (4, 0) in actions + return list(reversed(actions)) - explored.add(elem) + explored.add(current_node.state) - succs = self.succesor(elem) - for succ in succs: + succ_states = self.successors(current_node.state) - node = (succ, elem) - p = self.heuristic(succ[0], goaltest[0]) + self.weight_cost(elem[0], succ[0]) + for succ_state in succ_states: + if succ_state in explored: + continue - if succ not in explored and not any(tup[1][0] == succ for tup in fringe): - heapq.heappush(fringe, (p,node)) - elif any(tup[1] == succ for tup in fringe): - i = next(i for node in enumerate(fringe) if node[1][0] == succ) - if fringe[i][0] > p: - fringe[i] = (p,node) - return actions''' + g = self.cost(current_node, succ_state) + h = self.heuristic(succ_state, goal_state) + succ_cost = g + h + succ_node = Node(succ_state, current_node, succ_cost) - def A_star(self): - fringe = [] - explored = set() - istate = self.get_start_state() - goaltest = self.get_end_state() - node = (istate, None) - actions = [] - - heapq.heappush(fringe, (self.heuristic(istate, goaltest), node)) - - while fringe: - _, el = heapq.heappop(fringe) - elem = el[0] - parent = el[1] - - if elem == goaltest: - while parent is not None: - actions.append(elem[0]) - elem = parent[0] - parent = parent[1] - actions.reverse() - return actions - - explored.add(elem) - - succs = self.succesor(elem) - for succ in succs: - node = (succ, el) - heuristic = self.heuristic(succ, goaltest) - cost = 7*self.weight_cost(elem[0], succ[0]) - p = heuristic + cost - - if succ not in explored and not any(tup[1][0] == succ for tup in fringe): - heapq.heappush(fringe, (p, node)) - elif any(tup[1][0] == succ for tup in fringe): - i = next(i for i, node in enumerate(fringe) if node[1][0] == succ) - if fringe[i][0] > p: - fringe[i] = (p, node) - - return actions + heapq.heappush(fringe, succ_node) + return None def discover(self): if self.current_pos in self.houses.keys():