From 58042ba4f24fdf983a4616cc5743d430701710a9 Mon Sep 17 00:00:00 2001 From: Daniel Rosel Date: Fri, 27 Mar 2026 17:19:27 +0100 Subject: [PATCH] updating node positinoing --- paper/src/chapters/mdp_agent.pdf | Bin 10743 -> 11308 bytes paper/src/chapters/mdp_human.pdf | Bin 12194 -> 12049 bytes sim/rl/behavior_loader/models.py | 95 ++++++++++++++++++++++++------- 3 files changed, 76 insertions(+), 19 deletions(-) diff --git a/paper/src/chapters/mdp_agent.pdf b/paper/src/chapters/mdp_agent.pdf index 0566be9e926934d4b553b90623800f40acac21ea..6845eb5e38a36c814ccf729d04281671097dd95c 100644 GIT binary patch delta 9665 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 Dqd%DZ delta 9154 zcmV;zBR$-#Soc$qPJhdeB)1W~*H_fB`!EzUlh3OF!+-!CEYD34jCE_YlDuQdl5G9H zBa+2x?9{ZjM_BA`kxeF9!N|y9$r|zJLGVwCvR*}J&D|8zAw47NV3@wS^LOeZKaT5~}1?QVpWAYJaa7(N~E*#Mt)sWvwx^ zo|nBR#eFg#x5yVZq{ooDZc|ptJ>;JDm|J_n;JNHRWZTw^@N(mq_3ztj|MGtQ{BeX2Q0Em!`3T- z){qkD)61Yu>l3C3!juI)IS59mVq^pNnh-9v9EuqNgUn(dzw^EkwS@3^yPAT?<@-B90 z>qgDJr+*C+>^i<}>x-ksa&m-9n9{TsCGCnkS6{d5*% zZ@%)C4E`rE_uu|YttjIc=*F@M$IF8tBC#glLVqoV8i5y%8JTUMDuk_fS5r+xD`$GE zwa~INS!=LNjX;+aNOG*96?5kGlAZLa*1>6L>FZqfQR2&r_L)-@BapQ<193T|TXU=> zHK+1n+MP@W-l0RmWh~I6z6yWbnXG(D2LPM2kQ=qYHYU#=hUG3RGQ4sb3L%iIKu~Jg z+kdQF5H=-(TUUX=R43I4G23&I%e99L&V7bh1zL)1U-nhD4z9B8WA^Mj-$J~6le?K* z8q`E{ZPdATlgZ@gw?xwanZ$Hng2IE=UgidK!D1bwE@#a?n^~~n=cAf<1x1l6&Pk{V z)fCiI!Mi|JOQO1>iAn=1m4fOO&6$dNbbo`91(}c_<`@a3qe>PUh6=XD?9}|=kuviK zkqH1Pd7O7AC%J1a;$-0pg;M)RoGg4Q$E21Vx)xXKmRO$>UbNJ4wp~$Dk<}@VGS0Ly z{O`iprj0S^8?ufC3e1A=S;?pspihgTXIqU9hING%s-+tkS_VFSRy8^h_z1O8pMM$= zw9LcvQpBSmfG;QA2_HlVTQ1J=T7sbsvG@b{(r!@Rd+Xn&B@94jsAr!YLqV!_!BaVa=w&z;Qb07DJSfeKqJ zdi@mEP1uROu4>sJ%z~{%Kqw$@0%=nR>SP?eXp8w;&G#vWVqi4%im3`GSw=+?RHCRA zRv`gxkX5J$z1$>i94;UYH%Hn6WAhHK4A!RR0wb(DNjBQPoOUPZ3E3AnpMMG+fht9l zKauwWz3?QGI354Bi*Epd>M%#7tQ%q&#Ewmuer;dYjv4N&W*7M2&T)p=+j08w*#o$# zE?WfNw6^ff1BTuf=M`*jY@2h~``zWIq2@rxT+ZTcmyarvPTxPB(|Gz9E6u?v{fbBR z0#x^k^Gd;KWFUPbk}wrv(SJv!&c=IUa_wkfdvT&+1m310Nl_uem*mWRop=p8Bb9zs z+$kY07+sC?$Su&UA+h{s0jY_Wop{G-cM`85FLHC4^Ab_d2hcFY1BJ>r18m)mvu8pR~t9RT<2w-o)1tZ zb5Y`Di>ufa>gq;eAZXC~0bumIsG(RHZMcktLUdPJmAcJ%Rr}x!Oq7`R$s8il(`8SUaXK!(flrs07E@k0Oxv+5bZ^Y26eJtp4AEp84ddOdXP zKA!XT8%(DR(Q1AQwpZ>ikmTA?2ga4^8P^0yiC+fbcrq5zR8rQ|KDttO-779e!`3YP z6e8xgN2Q#=cmsOYO|n9?dPTT_Sz@?Rwu^sHF;jO%bO+TxW6)YgcbFbY0C3UhRFWnpa!c%0pN3wRXQ zmFB&5>UKT)Ro&GOsfDC&HBuwddeE`}@epM!Fb^XufU%4tXh0G|0t4YKEQ{FTEs%Lw zfTI|K8F@k+BS_51fP+kAY{zz(jB)rJ+mkrR53-7u*3 zf4=Ij`>I>#+;h(VpIai75F(RJ1W0hvvIQ$XKJ!8rA^sjhxVekgt`4>o{`dwV0gVv4 zzh=eaWnXUkmu^B*F5_K07cbpV^XQq@$Fcr0-ZQ$kdO_8v8@(3^84}07k+s;NOcFL> z`yjT5)-GGUe%nd;F>Ig1_Ufg}7cF@Be;*&YNl0n|w#O}7uzm$!W*Lj^rPvOx_)hhT zH5)8nW4oCUHji+mMsMY7*fEq=K%s2>Tg37f6y(5Tnx%YB!f$9pmGDEIV z4Nv-4K}!GUdaL00=D&Q$l1=Dsd>-G#M~H)TYQ?g|iHGeDyKvYdIPg*;3WO4#e{q%) zO34g?*hB`jL54QsuuGy~;VF@vR?ewhe$VAE9zpW^$MyPSuHu5}vnm9I{mCB_6!A}q zuhDuecdSd-O z#x~~n#`=3NzgKXo#gDSn=^ftL6|WQD?JnFL9~N!2Yt-n+)cZyj#(Z9ne^7^6ZUr1APUi5USD8*Vu78~AR{p=~SH|zXJ?Lj~pW$b>f%>UW z4yZ$ER34@l((!V!T1uzMQ`JZ1d1@71A}>)_qf0laJ7k}Q2vp?kVCR`ANETVJ$~KEf zB??tI6;xhfibWCpf1)BPl3VszlWaa!^<{sKuViWD=buPLd|eldV&2Q|wceDXuB*De7d;w@5iH=gOg+ zFK6YJa-m!-muAYdtrhM$>MT#WZy|}(I9CN#e4NECaUm|of2D6y;@!8*&%J0yL{_0ek7_UBF6}! zL=dSIu2ALr^YpuG_3lIZP5saN^f%Yh&tC4MZa&g~f&0LSB?C*$*vf?x!!L-Q$`gGV z;*s-JvW4=5f6IT*1fc?o;ehCagXQH39~yi6Dn!^y;wQCQs$V9Gy~V?eq`|_qdE!Ze z;-XQBMS$cdDL2OT#(FNlS8RGb*1HwG+f`g#fPrW?0x^kbxL^`Vy4__4qUL1+6TO00 z%o4K1{N$$OmgK|9awTe6=qhxDydl>;F_BgD>CvOFf6=*m`+bwAOyqWoyZ0Ra9%@CW z>8I;&Rc?Lgk@WgoZq5 z4*MjMtjgnU8PTAKh+>)GADqbw1&yC(51&hmVI{Uc3 zSf4+pfA=YUhR37NYt{*|`LX4(XJZ{Pb{Bs}nD{dSO9Fp1HDAuR=KJ%LF3Fdym;9HK zx?)l#EujV~xe|bMUls=b|FB`0-JHs27X955FCA;wxg+uA8^3!*7YD9fJEB+N3sq0H zL&chPmwtWgVqG1V`QnZ;*#&l#BJmZuBZWX!hP-ggV?0 z1vdrvq`2T`O_?2;9PUK|-HJ?AB7-`(y&et?8%d}}kL_#TwP(++=6#(f>5`EzZS4N$ zf1B=&FO7WV*0qz|lqFs7{Na;NfB(x@>)Wg5>%Y8tQ-5cEm7Y>Rh|4=sewhp-Pigrn zA!{;GY_uVHpV*>?c87PRwPZD`aU>2dnUPR#hCLc^l8BWBGJHAN%8hPhU(^C+b{89_ z?d#F|zWze#`??R^*Hvtw_E05fdCvM_e_c6z!>}&e#dSe9-_5!$-QI3rx4$c?E4eFR zH*mbju$8H-YO0lRU8I~)LU|!vWSS51|FnI}w$-b4bsp1?jXzR<@*n#?qTIgCPdu&6 zkH0$S(=Tb+XKNdlKfRltyY)|XtENppcjWI*Pu;M&YT=da?2nDuH1djK{wnI7e@>#L zMk|aGCsmapLC7WzsoDEg@dd%w!iV=Kqwf30%9oRC`1Xy2 z?sv`i&tDAK4|l`RT_Sl(UQ=F29*_FDOx}zX6{evUBga!iKd$ILH>!kw;iU;@O<0>R z?7z08t0L~+(s=ZMVbDK+^ClXUf7a>;_cia{vuAhnJ~-F^_~(Dl%KBYx{2#hos^-&C zH*eCB^Q+qH_2%=x{Qak&{NbH06NfPWfg9{P+IYP-gs);222~a|12DB=mL(!xMI^z6 zNM=HDZ5Bdo zikaoz=q(s^PxA4`L&c-Y%0?AGR6Dw?Z1kwI8HP=_qA$0go>oNMu%?n~o2A;l#1>Bi z+*Qfqv?9);$qbCepzABhe~h_Z3Pus%mg^n*%lc3Bjz#n!eS$8h2lZNgkG@y0O<+C>GSlKA645lbr9oWDlLn4P zNko7sE07Zj*Fd_3$(Hq=WJ@;pOvaMfv&=iFMUNSQjFDYeSI4xve*v6^572*;$a7kT zD5(t7i3S&8zGl1B;A*qVB9}{)s9TKKqK<;(1Q1{DRSfI)^~Lmy7tv8Knl{!(D<=CZ zpcw4$ReXwHNy^6~fJQY=1C7^MsaNx9el5w1kLHZYK^o*Nm3M_tHib{dk`SJ{!e$2c zZ?G3WsAFZ*x9$1xf7bg3*p58jkh_S_*1vwZ>|Dnnv@WlA4Cu)Bp^m9!g_bASJpmpw zoy{^du(lMp!${Jb72+DN4vAWvQ8i*8!$$*_2#In9X#>QQARU8o`jBt>jnH%>+nml% zZ%Xe-hr8mZnc}BmNr+!~ugL#~OlF%j@#4~s_G3DKIKE-if0iRgn)~|FCw}=GlQPIJ z_MH7GYBPW}=$Cb(wtM@;Y! zCbnJ=;cE9EIIw^JfrIuIulc&&NE3 z??j*UU{?E}f0h|yE-#R@{bJI72W^0rq`?svo82h^Ymv%Dy)Mjp3o`DIli{m9y@p%^ zymYDw&mWbejO}sV%S5vG8fLK3kO6f@9?ifE{8b4r6OZaZ+9{Mr$Oz7nbb05-*SM=u#kJg`jsh!TB z-+-3KT=9Xrb9Kw#xxy9K-+J!Cv*&(FubNn}6aBXg@n{H{p@nQ7;dWoZVLZDf@LPaUh|CBTWig}ChC zw2GWtxp8?MlEyfcGqL@b(Ex*oV}9_Uk}sjloDNDsd(Z(1l9=9MoBg01@oZ>{Eb ze_y1j`qk_7CItGw&@FW|a~a&|m+SS92jlVTKs-FGW%+mo;~{y!J$=96YEUsAgt)z# zb4R@jL=d`*h6LmsBOnYXGrjDu0|H4ttc07w9bqK-%t6l?BzD7ppy(cI=LXINfv1tHe#uEl4@`If6}xK z;p&tn-gs6}PV<4q?X_7XmSoLB$$IZHu(5@|=`#o@Q?f~R*TB)!C8{>nt~eB@qPSey zwrqP@dRee61S0|rFbtc-9YT$~rbZn1!mfh{ceS)0e6955rN5(~U%PfozfLF8 z%!glje5LK_CocSa@}&zGF1`Kwe_Oxdu1}w)-}ve(()e7=*I*h6H@2g!#^$NL4^$FB>b1CM>1{FD*T5f z(RbMElSJoX#VJan=p-cSe&A2fAt7Hx1`Fd)$k;@LveVWDV`*+-#1JeCJ(b_IkKI(N{%bX zJ=_!ZX8ZC}M%qT&M>>j?BDL5%A!V{uYAdyuIwq-)NfmO1^-<>>*Btj8wN|RJ)z}w1 zs-26K1+E3|g=)2@#ura9U(;C|l=ZIl?zL)zcc;43v)#Mh*OJoee{5A=lg`Lztew8u zh+5fnz_5d_^Ae{w0nuyPt^RgoOxksbes)^#ruz@wx^Ymyu&3QHZNHWNpuS%J1dlUy z^wq8UKbdx2b^9uuLOjSOA8Gfa=MN2)*sN*kTxzhyYO~I;+JYh8M}J6;u$GALhu$Lr z%sL|RoS@YfN)`RNf8Nv*rx@{09?Io9$)p_fEZ38OHFvSeK?Z;rnex|tckJgdZD;8Bf&^0k`W2dmFHUL+UDBlrq2z|4b9D{2yaQ>65JBnlCdS+n%)|04Yg*p zhTGHIgYBXAjP`Jf9I3VCp&P*Mh%>nF!1wf z9xXD@00W_J;6OS}qlqKIsycqxjwhd{I)f#*UjC!_rT^a-(B22 z_M3HUD<7LYXGCuFdo_F8qd8wKUOjW>1K-NY&EK{Bz)zxySZPB{YeG!RLCzj7rBU3xJe`->lRSip=@!`QVDK(reld#1Su-H5@adX2HC*eW*F1~|s7Y!2cD=tt+ z4jf(tj4lr!GLP=Q!E`BHbSG~T!f&m)GVkNBkGFNctAD9~v*veCtdL)M;n2y`9rI%+ zPCUDH>vQ%MtTmeV`rmJTH5j<^<6r+SR!B3R-GB1=e~wpc_UwIT=ccDjO~80tMQnuU z%J7;-6zp-3CUP5(F$?H=`V`&EUF1FqW(5m^V}dV-GH%~C-ocY2bS91Cc;mphisQw1 z#{c%mz^_l}^R$h=faS^AR)Ven2{DHqPUWLi34{J^UQkDa5hQaefW9kC27t_)U1smwk^S?b6__Mus>lW&_(Hu~z=hscyiNFC~V4p%>x=%?9qCd8qJR-lF) zJq}Z_cQdKu<5(hQDK+&==)iFs@%aP#lJ~i9bJ=`^9>?bx&v+l#KTgJ@yfrB46#R0A zfBbNb904N|lGz(%nlQ~`!}Pw9%*N4;P)MJ*q>?ykgxR=48TRcWW%LR@1%u|ah4IEe z6rw?;gUg&+)uDZ>BKY=Wq1@bb5J3u;ZOcr30%@ikD*FtO~3ee=Y3B{z;{|<~wpDvbt}**f8HY?!S_B(e#@$ zr>5^RuU$>2^zC}8{E)B=o1!`2bSy%IWqK-x<~bbSEO zsj+-SLWWIY6d5bDl4&fRjOE`XHF&LIesYuBN#4NgR-8W;KEUw^-uG*Bd@R;Sf8p3p z{7x|D^Bc{3wwrT4!gW%}Dr~pm@)`KsL&tGbxOrSB`eO$l<&W}TGasv9%}lo}v>dhE z6y^!1#T;>q_$#SIIx6qBj<&X$8l;j(5Md@EqHu^a8rBJKW%CSt?&LOUzkf@Iiz>X? zJ(Rs!1#fD6_fYtS9WJ~PVHc|4e~k!qRl@m3IA?{kRygyThndKhfc32mJWBjs4gI$8GSV82o(|yp#sVV({Y8D)yod zN2}n6tq%6XOgOS$W=AsN@N{@Vfgj{S+qN{;ro;E2SJ?Mc;duoP9dximf0=L)=N)vw zL5)9vHy-f7flYj?16noyxlGvqy#lshhkbihwl5R*?yt$HCHptf9gtcpiu(d&0GXz%SO{>#jl@8z0 zVdV-tTdBheJFL+7<&E&fvJ&=0JuEAMrS&$pRDq?N_<9@EYkVC(f3of-EU7)qmgrEs zxRTYLh1yO0;+jmhxDpm?d`%`)vvV4}2>IkxE0{3eYyWa|$1e&prv-kZf0(x(JgUk(9`I!h>p@SV4uqT0C z<83-vv0>Fl*Mp36 z9sd99hy33b;NSfqll(V-nY@q+Wo~41baG{3Z3<;>liec{12Zx*lky`-e^Se8!!QuM z>nn6j55W&5atg*!(u)s$P`4joORLmS%R+Vz{`>A~Lkd0EI~vU_!>+P(``r3*mDzio zO$V!Vqqh;3`5Fz#0WPB#MJerQ*4rul&C~~xp}E_Z6{gm^S=6=6KJao`<0f}cb{^nC zNGY?oXd#aNB6nZsj;Zb%f5Hz;;8&T8rjZsLwtMNrYd?X^l6l`+ydT$XkG4O>=N3Sg z>0EFmGh0|fZy@&m0;10IM%Kwhqh^vY< z72=~y7z^?T<`1N|thdDH%;&@x%ol{YkET9~c}08)31dN?y()PPf9nnPEV*Y%JnJ>- zHRsWkN3%wgrsDh+WN%_>3NbVw zFd%PYY6>7AATu>F3JPUzWN%_>3Nba4@Fo?L;w2ddK}J+jR$8+GCMf|1K}J+jR$7w* zCLfbeC&H5_C=HWAC`gmPCkV5NC~*OQQEP)R6oudY73XElGSFPDb`xFp|Wv{`)0b9V1Wot z3|mHP>)txO!FDyAv>FE#g&+JphfH)q7e_Vk&EUhtZNV?FdX&plI#ngVJ0Z`fqld1v z=VxiusD(60*UXDE3OjcnRsjk1Xb@{ZkWjn`B3=Rs<>??| z9mEty5W&o-@eC-Y@t1)C0A;5PqzYwjWOHsRPFeQ28BWL*se0Sx4jWNwBLY})p&lkRM?PVB#* zSH&-l)ap?$47vCx!GDZ3cD~%E|4dqpfBED5%?CYy{B<((@34J` zfB!Lk|HG`6o`0N-p8qr(ldN*u%u#D)W1Md=Wv7hKFd6(Qz<)sa8#x#p=GdhnVrG~x z)6$ky4!kNSl@c3BS#Qg}KBPGsE&E>PzgADbe4M+>nC6u=@W?oYvz*1UI*Mp2a7YOIamOb1WjzEQVz3ELHV3v&|U?aJz&Y2X37>X zoLxxDy1WAlB~r-*%*rZfJ{nta;j{Buz`SB3yfb4;RPbLA*)BVX2mwixaD(vMSrz#? zKLW(_Q@8_&4k{-z2f2?7cme__;Ow68Yv4Tma>*!-;C~YkfRzJ8&e?6=oBIWc1Y>|=`k@dRg5lOha#1MbcOoIvhj#>i9Nr;y0$jN>gRBsoCBgj^{k zBWQf~jY7b>N{2mOt@MxqtIl!3AUQfknM0(}MSl(;YEu|wz3O=akpM}~AAn;UAYd&; zggmwx8N+BKWCZ894_+eMb9{jBlE+oj?0^wZ#GA2jmqJ{Y+LUqC*nktpmN4TN>c|Df zIR{j6sfdwKD$I7-K{!HUXFYEmacKsJ$afgTyoEz=;D`je;NogEd}0DgsL9xui@(Hl zLVx`V9zo7Aj({HHhy>&MQY|Riz|k$8VO}(Mbbn>RI5aiTz`@4Ppd?nTrQ^)Pn&fIvG6D)njD}A%ne+h zA3_oDL*d{H*C88mYAtmmdeK#odAP%Z2iG4Py_|oHK}DI#w^}BcGDrzUIC7F;NOHft zBkJXB8CmSOgJ2BEVysHOB_#4YWr77E@1&-SZw5Oj#AV^9?Ye^qR<})v;#mkF?0<(9 zY$uu;F%5$1#8iJPG1Z^OOON@f5lrQtTc@Q#PxVi2CWEnAb+nqZjJM$-HN6{47NVPF ze(MQvgJcv{jn0-tRAhV|6E_Ghk1k@TZt*NH&PCams9DOo>tYVcoKm^g>z?82B6y<# zIk4D!*bMAMhC#TJ1|YaHP8Ae#6n|4fD!?rT`U7O#uTTMolge=cClQ5Uw;e#xB`8Bo zBt~)g-oz46opTf^hT~hXLd?Q7%;b#6cG=PH2o|3MGxB~P;BW9lVD9qYhBy@Y#UK{=?GJPK8M!@OhJ^UO;@w>IK= zrOXHh6fMS!%O99GYY`r}5r6qjcxeg{qYljz^CDpKHp&XW&%Kz1pd<*%a<0rhSh<%d zI+g$pltNI(;1&t)uKM=B>Ast;K9DWot28OW9h?9r~^9Vrw67 zy`^j|=C!wvt(_G5-K;w*^So!CV$O{y{n2JRKsOJhvgW8TcBz$hHh-d2yExWdRuM}J z17IY>U$z!D5SO+?FYBD;w!2`~q-EcC6f-CTji_5nW(_V0j+UAk{gxcyjc6WAzd|*$ zdqLWeM|j%%pK@A1+8fl{q93gdYHLV)gIYV%+Mw>_Tj@4i^LgtHX=_lgz5T4+s3hEa z)f3@mt&M@hfWIe7?teWGM@Fo(P!b9wFKAc@peTgM)yt#U@Rjno>R_Bq7VLl8V$BeF zP3b+Ei-X8!Ud9^jDtvAD!y&ks=M*wtuX|qXpiSY=v+wW^@srz%9sZ8I{3Lu^nAj-j>1@NxFDI*C z{(G|N<)_m*zuaI<^-p5`%+K!Sa>9xarwMy}IoXWAZ9gO-DLFe^t9BbEXS^^OflWB5 zM2sw?MH^q{On=;==Bb;|CY468Zqdf0A?y|)YgmMqEuelilf%^CQVnv0#gAqgzSliA zhdFo|1gf@~x3-C^!2Ld1!2ElO|ML`IKK~D3Qvtr*!LO&YvBe-4xC4HV@cPx| zHY`XurqLG8)|4vU!nutvH4vw6>5*D@=;Qunr&-Vj@_$!_8p&Rd7{>FZzncG0y{aqL zZXZNBKnZB6+42nuV)gFFzJl=Q-|*uK(1Kn8cE|j0NsR$@3Hgs=tp<$CtWWnvc3!4H zv$XK-zpI%e18NA43}`{xmbUQ-&2FjD+oQN;K$|);V7*!Qr!HOlckpIV=vvf2N`SAq z8RS4*uz%I{G~w~5JD&yK#`kSlT3Kiru?oIk6l!!%-NJ#ph~ZucFsL!#GGLV=b}B}1d%kqo^Iv>;rwZ8t2^q1#%>u1S3KsejGVDnYLdrBaN1Xr<$_DKEYJ)GgMB zIhqe>lX8xn1kxlsc6f6?3(_e}v$%xc#PCbM!Qc0}zp0J|`F91>CDBSYbpxc(T8Rv) zvequWTUnT@jA~V6Et}f-vK3a{|CJJJuQ@D*LgN2PFaNU?YjKh2`S0N^39yhmOU8K{ z+<&o6+f_Rwx`(L-W)INy+!5Z>P%F*WBCxIQ;~sg<(w273w4OS`d%f9s+xqo&?P1Kh z?=E5eAi%dl45oQkf3DKPPlN9NJpCV|gW;|UWo~41baG{3Z3<;>WN%_>3N;`wAa7!7 z3LqdLGBi0f3T19&Z(?c+GaxV^Z(?c+JhNpBI{|+Vma%Ev{3V59Dd3ksg z*Ol+Rb?a7FRWDWD)tg#K-L00?NVFDO2oQ@XKwu2EtN_6>woC((5E2*&tAu6n!oG+_ z7Q&G&*=FzrJ0OV7$QWap$k>j}ki^z6ypSjBF&V}~6j98nY6+Nm$$ay@?|t8U zf4qObl&bDhRp;FEJHK;IfiOZyL>m!7frU%wFaPwj=N>~SQALQEyKv2_KttZk*APl- zK?pZiE?>0tn~ne6g^)iN?%J_vNo{38!M?}g`W1wHja3!%%RgW5ItTNoVQgd-49HVV zPeC7^fl{lMu3Go3)$%4n0Wb8QTC!~6{P};st9l0d@O)IXbpE>K>`ZPf^nVZi!15ne zEMHyAeUDHOy7Xbhph~TYt)z!QS`+fA7WQ4ly^DET#;_=->tfGvBwy^g*psW+gZ8wb zJy^-2{*@%L|0}J@WV`;SA8{G*j4d}WvkmkrG9wQPsS2vFa21ZlmYA1tE~mgrX0LyI zt>>EltnO<)a&K;0)M1yIPzqz09i9|qmr-6+|I6$+*xYRXzki7+E2Cig}50%f|ucDtxDUg?bE726^!1#c^Q9zdO-%KDvcAEz7h zqf39M-Nc?NH?X9g(LTHH=!46xPb@uqMmw|nz=7Sn4>U8+&X|rZ-(JRcZHxATwoaRw zoP51v2~J~EE}T94%lF@W_cut_Z304UJLtwBJ8D(am~ufBaJeW7_hQk4R@zK5T`4Xm z49{}NZY7eLXB_gii{rYw`p18D*$alFobLW{7svHPLAM#RN=-8R9o+KW11TqR1dPj0 z284h$U?XLCM!R|TjCRZH2WPZf^*_?=2TR{Xj+>oeAO|#cw0+d*2UM>a`|xOdH)c7; z%?uSsGNZ-2m}#P^43%NKfP?vY_Fz7SKdzuXkNH4j$jKX}S8uFhcAtO4N!sPBxR3by zzt*^FoVJu)>lbUZPjw6&1sm4VkC7k!R81pX(mG!SC$Ew!oE4k}uSE+iu|SfY5tEUJ z6O!$s!~_5u0P-%~Y6IvzryEi0b`<1-Ho|OOqg#pu3`GLa;)=iu2dq%ylSqwE-t3HP znJy8Dm8ir?CW)64B%gnjC=HR4q-2YPB?~r;@Q-Nn}G;|A%Xzy4om6dhWLU$Z;Zd{!Cu0Y2_RR{6|x7}CvS8- z&1BsuUQI61Wqo_;@DBVC$Vbq&0e;XqE(aB=DXCsk;Sws6rHahO$+6s2uf;*b7Mg{) zL>I?}gXUaa&}%@RI=Tko)%%;?0)Uob*|@KhJFZP`peTPfl#-f1V&tgw^!!26BBxsS z>}l1HjO~xE-?3x;quZApIir1l{ok~IJ@fK`=dXYA$@S-PbKCLbZOXX3T$*4JtaetWGAEntykb$TvQ3s`*>2CUWLS&+ z#ew3WqbzL@%b+D01bWCI{$SMYafPyh5gF#WUCqtA8k(A4FM4Ik7no>QuH4YB;z>9S zm~VyUiATJQ zIn_mR84ek4%DSAGGYzs-A&%>Yx#cyVR9(R~?H|1sZ40w(b^mz$PSeI`w>Pw~E3jBF z?hk)wKh-XHV6Hezr0`%Cy76I1`MUSaDi9vG$k}bF{VL#uX1b2saB{!t+ zRAQDo8K+vcsSR_^LJq#YXHR&)H9y`Nxa|E5Qtkmto-oAdcMxcJL8b<3XEjZfeBb@j^W zQ%|@3-O0OaHc@$T6?BBV2@7~=z_g7aRE}w@-_4VPA^U8mjjOxF9 zu=uTC{QmRL{_wuxCrC?Tk+u}rO?nM&#t;Q^J~R@(T!={dkmNl9GC>F_5;F9T<| z(A}zs2#z{uiwvejgtJC0VMU7AbKQ^gE7rTO_X<;TztAIozF?wkkF9Onjn@b;4$`iQetfUsJwqTs6Kz;h1c<1 z?eK`H(F!@hIiE={vd6z zcpK1<9Xl$OUu(Utlh{E+kSN z??KlcG7V&xCY@I~6FYyW|C<+{tNpRRG4kEpSG2FN`w#z&nTy=stsC~q4B{_+x}pA9 zJI>Sk@d)kG@l$V}c|9JJ!RDriLEc>S6Ln(1r&w8T7$T-5c@qiOWwfLPy-qVV)n${N zA-8}M6mh&IB@*BP4cr9J_=K=4qD&YX$qa;3Bk8%r^>jJf4VZrilIoVBftLeL#*OQZ z_Ijc^V?_b}9-Vb3MCV19MfXJ8qx3d*h8x%!4s9TfRC2@|bB-s+dqKQlzTmmw?TiX# z*zjtXJr1V0oBXv7z|3VVWz+Ki?va-c9oCq(*s}GHw`u&qnK=x|%X_Z;(Zi&4_1X)+ zx^b?$nn`B5unh&lbty|((WcK1WtCz1Iux~Z&m!2aGgF2|e!Zqk-^%9?}NC2bW zu7h-U&wVwJuq=VW{~F)mH zLa>;IquM`ens(l>m;U}Fc)t(jt3Gtl(?F~TEKl1Tgq?pRmT1ee_>j}bWhR0U7eBl> zAV$BAtlSgJhUi{;8#_AB80Z;*6`K_PUAr!Y@7s#^Dr#K2o_xCbK-1dYK0M*b2@vEa z9-fn{UER6yo3FqA_R;!V_#q#GJYMv)n!*bT#Yn2NBkJC173%CQW|3#IkQ{OFVN1l8 zn-B*Ggfo9V3+?TVYUj=YC!RBMQFXM8WGpi>k@a-LCA(#h?9K71NX06n5|veHkxO-} z9@Xp8lSh4V00$VZ>^6cD3arHH8QS;v z6`yV&H2Ja`+klR2FK~YnTBb&PPLmaTHi@K;u1J4$*a)r@cgn~j$tD{ zE{q~fZt{RT#9cx6gI@50{@#IDo_jLKzro+`C%2_fHl$C67MDIRF0uWu1AexF-WQj& zA3mh9t@G+OZf>ilYW0mdOCI^fZwx4-pEno)j@xQ1=~538 zj!?v73eyP5^~rj~>y|q^9R&_g!GQnw^nl(yaqo|3^SqJGLpPq-Ll^$(Rmce`5n!tR z*2D{v;O0GU-Y5Co>3oKi;T|m&xC=bfq&a{5{n8?Sk+jHNTc`qxNM3b3X zsFkxJ8z=FK*=ce+1VvQLde-W&$u^gi==8cg?xDg^ai}@nmLX-ynf6S_FlWS-;m%1M zX&Gr9X)BQPl>*m<#Hm7&rN~-jo1#1*l!~S1`=vSdIgU9>l~8G^v@Wt$NQ>n8_W6H~ z1xkgp(j7}&C#)0Knd{_r_H~XmN}X$mvctK}wawj-*d#T{uM4NdQ|1o$Y^Vk^@PJ{l zj>nLI4a;H^RKnA5^dCNs7vs)@_{)=87j8Uw<65(JcJE=`wEbrMY)y^!8Kf!I__ZzC zuMNA70#5jp4Fl#^t0^8kXR$h&O@e>dS|_0vA;yAjAWBB?7+XXRTXMicJ>7Loq11n1p~al+ zXOaSiW{de=vn3E@-S~ObMjOKJ=Ur_+VBT;nGhns^lXy>-E2&W8!>*~ROqPVEWE#0< zcRb~C4Cc=LJ$ixmeeW$C+6)XDe*t@eVLJ9o!~Sp}91N#~LvzKs=DC)+*17(_2S!Oba~LrwmsKvRFPDWxfN*nc>1ICwbaa41O~wqe*Y=P}nY_c6~g@3Dlp zoNu|_a=+zy%llS>4Jil*wk&Od)?$%(RV0x$-o0m-Q~&{ixKo2vynEuxsdAZXItplXVDeS#Z!v zj1$IvT5T=9as&^rc%%?Rq{Y82XHddR%b^wknD1?5fMliA`5i8s1 z1BXaSt_z5b&Yiwk;0dWE)gM77pC>(kz!SFR=2)EM7u3)ssbzaK?VrJ5H(5?16P0g{30k}?_< z{yCGSfeke#K%IZZKAY5%C1jbBBY`1O80Dw?OrzYHS@F-7MxAwAjo*Depa*z^!ze+r z7+^$M+mDW61m5|f@ z4}SIM^z<*PV*k+9aJxV`T%+wAC{H>EV-hnHVv>MV)xm$&@hezV$3OuUHjxO;730Om zK&b(RhWU;{Lo{eegchfvv|AA#AJR7&cD=eI+%Aciw~O~iH#)S-8&X+dg-IyAYF_cq#a9f3O3 z7UOq15`BN>e1(a)?BMyiDYroVzm%aTHh@2sjk=X%3?djr#CIUv)$<<^tR29M2eEA= z97}IQ_;58|Jpk>u^nDK^#GL^toVZJU(A=sx6|q$iop35Ni~4suoq1ToFs&xugj*5j zd6QD;R4i7DY-b#WR;%S+MZ|=+TRF%*Bo?)pd8dEkkgXQ82oyyaNI0p@1q@{n)Ho=& zb&B%*O^&*ia14w9XT{t)XWaxuV7KT~QgK8as^sDEVu4bGr;B$h_lplJ<#@5USXl)~ zsZ+L#ZVs6+&sc$2C~p!tNIgUg=TwXgRw2s32Qv>Z^RnO&oo27attifPG!$nD>0-#7 z35kD4nv(7ugT~?s%mgxloj@mW6HH_Hu|k13)-u{U+A&5ca85;2@DzTEpns*h+cM2M zO`c|-=9s2Tb^ZXA;1Z^Ul&~eVgex(X@Fl`bakjY>Qj}TF688cW!!f3ul(R7!<6@>5 z9}^ac<>pFdfivb_jn?5>rk>QZwX~M2HPwIds=roPBd##7wyd$Pv8|ET%4_Xw9jlbJ z&h5fBvD3W{xLCkSoP~8djuWzi$t5gbeFi_iM(aAL^=W_Juf4MtfB8x;c0jB@%Y3Bs zvi|=`22W>^!gw~SfB!|m(JWI8=VTpQO|F=*Zo{3{HUq3Lfz?sUGg*h3~s^CL2Dam=b*iZ-}^7`)csDsp988f zBNkC$D-+^D-v4tyC^TR%{NUGC1nD#yg4{@gvj-T<0g@{y5qd7j@nopAe6SDy|Mypa zSVSwqULEKIXdl7VJ*XP3KwD57Tz`Ls)*It*v%KD5BK;U-sYVOv$40w~9x~pnk5zxukAeN$ zP&Mdz8lHYAK8`c+OcEoNxD+&G@DVZ%MmM2qHU=$hv?4>lxDE`n9^OBoFFMaW#AL8x zd<5R3zvDbS{|Fin@>YVR)8Jrq`NPSFtXVUI2Z&!a%8hG!4U{>Tmbpx^~(2h#lt+j!U zn>R~JA!B@?oepUyX?#1I7W(pUO@5gbnNd<2Xn%i7(ZExu#EM{SRw-QSJs5`ZDMeYv zH&NZ6U;X0Y$L2}n{uTLo12?Bm%-Cg|J2#xrwrNS?J*K75<&E_Qun>PTE!C0`5>LbY zHu0WYGlRb%3p++VXbZCgy$$Eb;g|r&Q8@bGcmNoN^(tDc-TlQ+!d)ay=qDoS2=l8z|(2aTN6$ZLNZ`I$yeXykbNUG#V# zX}^mc)5y_!@>7kxVk0jfvCx;DqOd?Mp|c(=VbD1HfhNo-0T?@+kugKH@in9dpg;M zW%ab-4YK=jGu>?`yH$1oNm;}h9xrHkU$=*x6#L< zq~1mzT`$o`6|!C;bxow!PS%NJ?V12x+eg-{9zxdy$m$_v72LEcnXJ^vk2JDkxs|Ta z$Z{)LuCmMO$sh3di!9K{e2v8BWz(2O=4F$IHBzRLhh~rm>&aY= zJWxbRHFCd3=Db0EsF7LaWTun+AWBN^lW0jjxlba+6V*xN9y6ID^6aT9n*H zWO|oEraH(JMx;{`NYP}47S)i+lVmzsA(JMW=_G%dOjHFr(M(iU62qKin962?=$YjtV`whTm`H|#U_*0B7*1i0q>mwKRxeE}BdH+=O`SzTa9hYh zLMofWlVHG0gJmS(x6^=^1Ugwiyv%PW{*7$1NRm}HDMW@yBr%ov5^||;7D<4oCgc*Y zMm+FRk4D@waXFpTRYRPLLY+?HR9QtK4p?UAc!Stsd+i#L;UrHY638z#5gW|eG-8DZ zSiQumvKEb)p<`A@*ANlbi1kD$C%nl{c_%U12}h%pt0xrhqfx@b!`LhW4`oDxXAz_k z+=0tC?ZU(UpZ%f#+XDQTKZr2@4v1aH(UU+Y9|JiwHj`o}Nq@_3!yphv_k0D*bP@TH zWN0MIQk8DJ=tE8W0XB?NOAWS&v+&=S;YO*{h0Oux&RiI>L-XADVb2J^Nq_QYJE|;0ljqgWQRXY2Ko0mB(diCVSjvtiPI(rL_ z!{ASP^>sL6>3?{grXN1DpLMS4T08Dzx|eo(ZO^Q;BwjZz?ho^_jA z2^Zi(*no}jBluC6z$9FPOW_T86Pb{QBoCn$Nv&Oi~XEAaXgL^Y_Z-ldxoSiJ#3gbRW?vqfL zq^?1H9Hc?FPDrcdP2Jysy@n9mpB`T7yL5c;e1DtMIEgBKzXOuFj0$CLWOHaDJcO4T0uomQB;$4DIb%=D&v!oD;Tr2E4cxG zQEP)R6oudOEAGpfGSJ-EYAMo(DwHt>#rAFNA;e$dUABrJ^^cEB{X>@fb`04XyLVn-VY4buMvnuOWf;OdyG(RJ z7f%iE?GW6=eZjBb%qW+s@>{k1RzfzXV}L$&;El9;G(uX)R?mwU3O9$h{to{W3Rc|l zFWo)*`5Qdy`K4d;4R1S>fG!{bHpgP6hyBA6NV7=dDX5)2Fg@s0^FlX@>63OFz@3MC~)Peuwc C?lHaq delta 10510 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 QE*=UwG&Kq(B}Gq03MMgmB>(^b diff --git a/sim/rl/behavior_loader/models.py b/sim/rl/behavior_loader/models.py index cb67cbf..0b1a285 100644 --- a/sim/rl/behavior_loader/models.py +++ b/sim/rl/behavior_loader/models.py @@ -3,7 +3,7 @@ try: except ImportError: from sim.rl.behavior_loader.loader import Loader, AgentLoader, JointLoader from collections import defaultdict -from typing import Dict, List, Tuple, Set +from typing import Dict, List, Optional, Set, Tuple import numpy as np import graphviz import sys @@ -195,6 +195,35 @@ def aggregate_event_transitions(mdp: Dict) -> Dict[str, Dict[str, float]]: return dict(evt_trans) +def _resolve_event_order( + evt_trans: Dict[str, Dict[str, float]], + event_order: Optional[List[str]] = None, +) -> List[str]: + observed = set(evt_trans.keys()) | { + dst for transitions in evt_trans.values() for dst in transitions + } + if event_order: + ordered = list(dict.fromkeys(event_order)) + missing = sorted(observed - set(ordered)) + return ordered + missing + return sorted(observed) + + +def _fixed_circle_positions( + events: List[str], radius: float +) -> Dict[str, Tuple[float, float]]: + if not events: + return {} + step = (2 * np.pi) / len(events) + return { + evt: ( + float(radius * np.cos(idx * step)), + float(radius * np.sin(idx * step)), + ) + for idx, evt in enumerate(events) + } + + def visualize_mdp( model: BehaviorModel, threshold: float = 0.05, @@ -202,20 +231,31 @@ def visualize_mdp( fmt: str = "svg", view: bool = False, export_dot: bool = False, + event_order: Optional[List[str]] = None, + layout_radius: float = 6.0, + node_diameter: float = 2.4, ): if not model.mdp: raise ValueError("build MDP first") evt_trans = aggregate_event_transitions(model.mdp) - g = graphviz.Digraph(format=fmt) - g.attr(rankdir="LR", size="30") - g.attr("node", shape="circle", width="1", height="1") + ordered_events = _resolve_event_order(evt_trans, event_order=event_order) + positions = _fixed_circle_positions(ordered_events, radius=layout_radius) - events = set(evt_trans.keys()) | { - e for trans in evt_trans.values() for e in trans.keys() - } - for evt in events: - g.node(evt) + g = graphviz.Digraph(format=fmt, engine="neato") + g.attr(overlap="false", splines="true", outputorder="edgesfirst") + g.attr( + "node", + shape="circle", + width=f"{node_diameter:.2f}", + height=f"{node_diameter:.2f}", + fixedsize="true", + fontsize="10", + ) + + for evt in ordered_events: + x_pos, y_pos = positions[evt] + g.node(evt, pos=f"{x_pos:.3f},{y_pos:.3f}!", pin="true") for src, dsts in evt_trans.items(): for dst, prob in dsts.items(): @@ -342,11 +382,6 @@ if __name__ == "__main__": f"Built MDP: {human_mdp['num_states']} states, " f"{sum(len(t) for t in human_mdp['transitions'].values())} transitions" ) - if not human_mdp["states"]: - exit("No states found") - visualize_mdp( - human_model, threshold=0.05, output="human_mdp_viz", fmt="pdf", export_dot=True - ) agent_model = AgentBehaviorModel(agent_dir) agent_mdp = agent_model.build_MDP() @@ -355,14 +390,35 @@ if __name__ == "__main__": f"AGENT... Built MDP: {agent_mdp['num_states']} states, " f"{sum(len(t) for t in agent_mdp['transitions'].values())} transitions" ) - if not agent_mdp["states"]: - exit("No states found") - visualize_mdp( - agent_model, threshold=0.05, output="agent_mdp_viz", fmt="pdf", export_dot=True - ) human_evt = aggregate_event_transitions(human_mdp) agent_evt = aggregate_event_transitions(agent_mdp) + canonical_events = sorted( + (set(human_evt.keys()) | {e for tr in human_evt.values() for e in tr.keys()}) + | (set(agent_evt.keys()) | {e for tr in agent_evt.values() for e in tr.keys()}) + ) + + if not human_mdp["states"]: + exit("No states found") + visualize_mdp( + human_model, + threshold=0.05, + output="human_mdp_viz", + fmt="pdf", + export_dot=True, + event_order=canonical_events, + ) + + if not agent_mdp["states"]: + exit("No states found") + visualize_mdp( + agent_model, + threshold=0.05, + output="agent_mdp_viz", + fmt="pdf", + export_dot=True, + event_order=canonical_events, + ) common = set(human_evt.keys()) & set(agent_evt.keys()) @@ -394,6 +450,7 @@ if __name__ == "__main__": output="joint_mdp_viz", fmt="pdf", export_dot=True, + event_order=canonical_events, ) inter_class_avg = float(np.mean([kl for _, kl in kl_divs]))