TSP/0000755000176200001440000000000014413041204010711 5ustar liggesusersTSP/NAMESPACE0000644000176200001440000000350514402152764012147 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method(as.ATSP,dist) S3method(as.ATSP,matrix) S3method(as.ETSP,data.frame) S3method(as.ETSP,matrix) S3method(as.TOUR,integer) S3method(as.TOUR,numeric) S3method(as.TSP,ETSP) S3method(as.TSP,dist) S3method(as.TSP,matrix) S3method(as.dist,TSP) S3method(as.matrix,ATSP) S3method(as.matrix,ETSP) S3method(cut_tour,TOUR) S3method(image,ATSP) S3method(image,ETSP) S3method(image,TSP) S3method(insert_dummy,ATSP) S3method(insert_dummy,ETSP) S3method(insert_dummy,TSP) S3method(labels,ATSP) S3method(labels,ETSP) S3method(labels,TSP) S3method(n_of_cities,ATSP) S3method(n_of_cities,ETSP) S3method(n_of_cities,TSP) S3method(n_of_cities,default) S3method(plot,ETSP) S3method(print,ATSP) S3method(print,ETSP) S3method(print,TOUR) S3method(print,TSP) S3method(solve_TSP,ATSP) S3method(solve_TSP,ETSP) S3method(solve_TSP,TSP) S3method(tour_length,ATSP) S3method(tour_length,ETSP) S3method(tour_length,TOUR) S3method(tour_length,TSP) S3method(tour_length,integer) S3method(write_TSPLIB,ATSP) S3method(write_TSPLIB,ETSP) S3method(write_TSPLIB,TSP) export(ATSP) export(ETSP) export(TOUR) export(TSP) export(as.ATSP) export(as.ETSP) export(as.TOUR) export(as.TSP) export(concorde_help) export(concorde_path) export(cut_tour) export(filter_ATSP_as_TSP_dummies) export(insert_dummy) export(linkern_help) export(n_of_cities) export(read_TSPLIB) export(reformulate_ATSP_as_TSP) export(solve_TSP) export(tour_length) export(write_TSPLIB) importFrom(foreach,"%dopar%") importFrom(foreach,foreach) importFrom(grDevices,gray.colors) importFrom(graphics,image.default) importFrom(graphics,plot) importFrom(graphics,polygon) importFrom(graphics,text) importFrom(stats,as.dist) importFrom(stats,dist) importFrom(utils,head) importFrom(utils,read.table) importFrom(utils,tail) importFrom(utils,write.table) useDynLib(TSP, .registration=TRUE) TSP/README.md0000644000176200001440000000511014402144250012170 0ustar liggesusers # R package TSP - Traveling Salesperson Problem (TSP) [![CRAN version](http://www.r-pkg.org/badges/version/TSP)](https://CRAN.R-project.org/package=TSP) [![stream r-universe status](https://mhahsler.r-universe.dev/badges/TSP)](https://mhahsler.r-universe.dev/TSP) [![CRAN RStudio mirror downloads](http://cranlogs.r-pkg.org/badges/TSP)](https://CRAN.R-project.org/package=TSP) This package provides the basic infrastructure and some algorithms for the traveling salesman problems (symmetric, asymmetric and Euclidean TSPs). The package provides some simple algorithms and an interface to the [Concorde TSP solver](http://www.math.uwaterloo.ca/tsp/concorde/) and its implementation of the Chained-Lin-Kernighan heuristic. ## Installation **Stable CRAN version:** Install from within R with ``` r install.packages("TSP") ``` **Current development version:** Install from [r-universe.](https://mhahsler.r-universe.dev/TSP) ``` r install.packages("TSP", repos = "https://mhahsler.r-universe.dev") ``` ## Usage Load a data set with 312 cities (USA and Canada) and create a TSP object. ``` r library("TSP") data("USCA312") tsp <- TSP(USCA312) tsp ``` ## object of class 'TSP' ## 312 cities (distance 'euclidean') Find a tour using the default heuristic. ``` r tour <- solve_TSP(tsp) tour ``` ## object of class 'TOUR' ## result of method 'arbitrary_insertion+two_opt' for 312 cities ## tour length: 41389 Show the first few cities in the tour. ``` r head(tour, n = 10) ``` ## Jacksonville, FL Gainesville, FL Daytona Beach, FL ## 127 101 72 ## Orlando, FL Tampa, FL Saint Petersburg, FL ## 190 275 234 ## Sarasota, FL West Palm Beach, FL Miami, FL ## 247 296 164 ## Key West, FL ## 136 An online example application of TSP can be found on [shinyapps](https://shrinidhee.shinyapps.io/SimpleTSP). ## References - Michael Hahsler and Kurt Hornik, [TSP - Infrastructure for the Traveling Salesperson Problem,](http://dx.doi.org/10.18637/jss.v023.i02) *Journal of Statistical Software,* 22(2), 2007. - [TSP package vignette](https://cran.r-project.org/package=TSP/vignettes/TSP.pdf) with complete examples. - [Reference manual](https://cran.r-project.org/package=TSP/TSP.pdf) - [Concorde TSP solver home page.](http://www.math.uwaterloo.ca/tsp/concorde/) TSP/data/0000755000176200001440000000000013623555031011634 5ustar liggesusersTSP/data/USCA312.rda0000644000176200001440000022604412606077054013321 0ustar liggesusers7zXZi"6!XS])TW"nRʟXS#&'ƯNP7ϡBDxo"ZZk_^Cl'תᙧ38_efTaWFon됤1>C}CqR=/x AcGy)4myNc5G_fS B-/'>(f(=Q4uR5ɪ6B.#HAr!CZxCTQ`IsdESaX7¡wuf%Ί4uĕqd QDId!w+n/߰-heBc̕3օ:-U@r "l6{(Ey_mTizu B%ew24,ڗJ {"*'c5E(vzD:1V$:D*knnxz7ҟ(3Dd%+ILѯOd"ݝW xh}dcXc*$"CI2,Ujث- ih"-rDP)8)X7$o:6-Ge }?q_ni|A P’j ;ۃM̙&tX Y5$lD/H6#4xpXæWi6NFMk|c  חlr}Nh7ȘZ;W0?|h1;(%o+q6`B&uyO*bmN^O53o_D[ h'+t%*Nc`ypyӯUS"77K'o2Q`(d<5J+_Q7do]EIXW#-q1BrbR.dk-y v]ptp$@P9Xd7@cLnh̡IUܺ=l|"jW ^on@jJһ_Bg46'*ɵ ]BeK;[ƽRBcV*#G%#1hc]O4GV9Y$/elqƪɾKQl28WUUV;uNا] rK%43]&7x(B{'Ib%BnէX7{YeY2u#یV}ZdKN5a"ݕ+h)逗"5|MwUs0\^B(CYߧ531^ym|Y őWJ#!ScLM b]c~u\[sLy&w8V~#b Ym[OY`#!DN=>☃݃U!! |; @ǰ޹e 3mO߱%›uDSG'OӨ&(<epDX=1`N:\ ga]!]1ro*RYSJJj:l)0H[S@ hǦ^l)$gb s9ێ@v &ƟRub|T\dώUcR A42Z@=@5';ܘ;Y-Ο^_'I&*l/ g Zf"Ie9[}Ro ÇmV/Z(e1r P~gSqT(f+7d}azc,=^J/͝z-Q&cѲzOhť;=D֙&f'M?IKPWl5z܉R!/9A QG'6 Џg+ꢰĔDQ PO6WM398!<'@S}+0%'w8CC#:*H oHsy2";2!kG?+N-]pl1&7"Tbl-J&X5i32Б :[%^,M >|tU[6 JŢHs@6O^qLCYEL#*=?ʪ 2༐'8nMѸǬǬO`+E @(ikz$tir˱yX)}> aֱɋO7W2VA JZ&(*=i~Q+RPkM] @]qS^~4`~M̆ϳ H|諝n-oJbL1Dl>^gtl]O5qT2D~odiQ'W-<&YY~w3X-P*^mgnfdB/8$-΀ץW`HBIeCb>'xB>ps4Y9H }CP[CV*Ro[v2ze둎 һPHu}Ân%Hxq|2yk. a{)6 ȣU. ;y z#TQzLভ fs I@ICSߚY,Ǒb|?P1R 6jp,Դ*l;upd' Ԅ5 AM ݪQY86Z9L^t(j:ڛ[Qdl Ma4R=vϿTai|)b;-O@C?> 8kwݐW:2jG\ ,yH 2GR;qYdV tM*-fAsiu0·?f';lS`oCk.x<AP.L%X,O ngߴTEy0,1>;l*\|$ D un"gDk$NzA< '\Pvs0ɁEpIk ϸ+$EtE=p:hrٜH/n\I_#ã @3 s?h{\wf:휷b~bhndo,ࣆ5kK3ΠT5H 5ɕS@YǦ~ۃ؛Bc~ԑ0TOb3AtF:B2#WUyG-Nj78xDfMؐfs$Chuc ,Ϫُcê e4y3a>_Hv0xBS!h P 1tKU'`)]͓mȵж!Oi˵~җH&C_O+"VhXp-ڰِF dMHJ  itZ.J9p;_^^}һĪָy0xYޠjB_g>ٛ}#ڝ-(cxk)uF^w_78VuSecp*Zm G[96PL"6 ]+MusH0C2==njVPfH^+CNufCedy`lV {󂪘@6r_ŵaoUxI C!@'%7,}W`}#Q!t\[n-gS#+xf`bJz3nwyP ӟkX6ٺƪD/ȜynHGeE쌶}WxvUW6l 6>"k IX,.r ߙK@kbO0c%vD 9?uчy-c-pM&1DBٸwH⼾0qiNR͞5֛C5.(#DNʛrqgS&T>/D4 A~]fT_? R(tlHA&Y B^p[O9HE*膿M|g"; !<[5[$Cdr*A#C_z>>Ìx嘾"WoZHXpG=I\gaIiP~[7XIߺx২'0c^vx}, :FO[!YSGT~%TՒ~cXl "KH_j& hzՕeĜ# }KzGy=R^8T!M8h! \MQ3e5@5$,=绪ǺVFNZVoJ@Mu{bh4aWRXqmݮZGE/C*-vkv7 n |L"96]w?H9U}NH獙a*bWxϭ:Zbár"K |QcUjcC:%!onxjWH1G7;v%*R\ G6k؞S8!>!m5e"~i9|);{cĭ],1=F;hdB.fn!v |W⍦J@/ TI}~;زT-ܮ9Gsdhcd+CQ ?mdؑ|)OY&\.Q!ZF>\YD7-wÃb\./<C7d%H3F9~@Տc#x45sX0[`fЀA΃: kTVD$0+ Μ1eLpw/\")zmKb*yMO|okt)j]X"hIUftIJFWxjUEJ)}4XUk;qs\Tgz G{hw͔СT|-D'U:ks{k|5Iށ/܀F/ewœIjlƎ3Dj4Jn-Sƌ98 9>T k D歐Z m>|\˜zd4Cr~wc "Gؔ{O0ix_-8n˞ IcO$]]%& *gU1ySVPG!Oƒ%d2d)J!ݴuRM;wx4pXU^$V9RzH:Q2ޯ8W+ojS;]ڑy'A4{S[^7:٬3S=͐+B8waZ唝h}A_)trcW#6xΆq'vVr"G!-Ahܻc4)CS.stTr`*<pwˮ6\.L'H 3b6;ۇGM"0ZviDdzngGl!>I,Ǥyv'6M]0o.Y{i_Ky as(K u]lHTO9yq(CYFӎ kA#Yg>Z/3Ѹh]=W >O (>K3wݙTCpàg4]mm"  +OJoumƗL+ gX0fABߓگʓEIP۸)8ViT6B*qiAeC'K_Gq%O줯{ǞG?eۋKPB ƅLdUiE@ŶL}0/cDB2rhR38,]LUȔ$ͼ^ n\qY dƛ$їJ_"1 ""Fygߩ, Z|'U`<}(=H%~ 9]֌=KJR?$ir$u)/cR& Ȣ{JF!{.bvd}/qzpLҪltiݑ61S; + zJscϣɖmPq@[]URKҪ(a\PhA3P5_x&Elݯ~E)5˅Xo"d8 D44"ORZX#pltdwe("e(H*KZ/9 pԜ-)Y[qjWFΗt |vX9" \/c\rOn3w`yg/bb Kς  :fW*Ls?#䷄Be=H2峅-cR_p善~]/宏ORߘՄ'/ o1+X"HAkffH!r}ܹ%eV6OF>o"锋r0JyO7r0m‰?3w1 FYD{z ;``V_qjJ($Dw{yp>AZI)M!6ʆ髇ThoO!Hϓ*[ux=dvܰv|;H~XZBE=gi'SC ~1s$^XfMuN GhӄqmŚ{yA8>ZLšHTs3;"nQg{OtOAG>XPBh' fуwk4y[fK\o L A{4! ʁ([ܚ>-M5]Dm.K^E/7EvˢRV_iw8 #Zd;6?fc "Q8MrcT^ CJ3r21Ab>jNΚ+Ü /_sk60$s^44:IsIHQm\;QByGQ9_ 'nHbVuʗ (4 ! ^3-QR~}6k yt9#Ȼ8R.ta{hc;}J43wvGfjhnt@(ZsD:X&y;-rĿk媠TQ} CVSY .,Zc#pxf^Q}$(Nh.&\=,_r3ŗּO7~ІRjbjtB(!7fXіX biB?J%7 ;zNT[) ktq" eu5#J7f=("klcߣr$XgZBоwC\NlVBTYt1%gorutNERYaGɫo ]*㺱y5y^sQ@.1:25j6Ȫ:1H~Xf3=b2q L/m5=}~74?$3vJ?bQq҉%Ms zOBMҦ|v@Kdg⒒xb)(g_1kkDkK;'Ha€OZ?";}x !:0"EvRL찀Ļ?hH1:"S wrR'j!ߣyӝA{X߹e$#:~m$ST9U$;<ZCs ^.ψ{8+pi.a\:3\<#ހR/]Ep ;ȹj澨FF(gՙW,|ϭq.SU-?PU n_Ԟ %q*gpo>E`O %<6|j\1wz2WLZc$vϞ sUy\ é"sh&S- Ux?Irs9/vi` ]~zu\PP,SgSi:Mܮ'P,lobOD鱊`yt]b; /F#V CGx<0?XC+T[tIs :)G7kfԺͧk 6eA`8D&|%)?c)>J1N֥۾'YR2',TvS7ra}҂1AQl߲%׵H%W25K-u π/t%k$D+aXJz Ŗ l[-O)2OZ,OhNmVvp8RYQKre^~$ԫ;)r*O ˛)^o-%]ΰw^~#h :(Xp%SzAlE&%DjcMQu{Zx7=te:o6A9rAE"0Bl'G4!>t@/_Er =E269+>d)DB5]"1N6Jk<az&ë2D SLz2Ym{irʕ^Vh*ZqX0ruU+F\{tfQ7 -1k:db\ޫ~va_=UZ'? ^o.﮶ƃ4AۜʞpTy4Qj_m7d}LDO2y;z-g2B:?kR=׮A}T K}Sv|S~Y8 ̸$q:JdqQiu4&@ z"Z9$lրb"-+Hw}]񵌜if-eyAG9QTg/!L;J#};N# 2&t \!k[ь;Mn;goU >mlHÌyj`Ub*71xZ3c&+~*-ݗFz'S]Gf"Y{6!O3<sS:A/\hyVb.~@sEC]Uf"_ Q5K4N"R:aO ]=E{Hb:,Ss8Oi>6g;NɥR;[ꃞXs^[\z:OX*lqx7Ds# oOo :U/AMgV5'QHce( dG]~Zo4 hUBnmS(DXL#0h Qjq6"2p@ل၀_ULueЊAڿ$=6aF6#> \P>^'W_ڶ9AR7 uyNCkRj- _#?L`yL%◎mN /hbֶ5LwQ<'g\%@r'żtՖKg&1fHeu{J!:q*yEg;[<}uك8-{3Zz C8㏽-ou-ȷUUٽ6d>$NXLsҎ m)O_"\n+;=;{3#\9}0 -7 @i z0HڏK9/~ y5Y᱇n跄](Qz9;nL0F,@BxEYCՉ/ NAl ("gE>;ڞv$mwd RLmG-r+j@J9<Û&Y,WIr=2Ty kU_+|O$޵h/0]aaL5@1OLߞ*,Si{Ȥ7'vZԃyqZ-ux#~'d$`$#&9nlOݵqKRfR DtG|ꩀq=^"ҷk{Hr2'`DR v"3#^j?+*li^͑Y-x_g4x;ʛ⤈![FMÁ2BO!Ezt/D<ᓇːu)nG"5Qb #dcKMQb{\r̈́q@.lxj={GP'C ~tΐ BNdl~)s.$W2h&'DAd]p)ZdEё8W|Mw +5+Kh]ikj[`1h %?f{%8$V^4-.^9Dݟv6ˌ# Bc/$:70/#㏵8[DiYN߮{{_)6B'(PȳcWiЯ Ϭ.+9T3KTr!{5⧏w[yk6序ȈIo]d&WUoUFIL *>g'DΪxe3mŖHvS =VʰlN̽ %e 6 }]iW^ԑ,!5;Ðߴ95 S0K rKl5QZoxv LQG!E3\} 3X5PZz~?Kp@ dռbs7.J\j\Ŧ;lʉ~zyOc5"P:6vZ2N)5LnЯH0{Oe~* 2?MJ_Z`LuLyc<d'fat׈łp k}^}U0&ac6 N3`PV>Kng90Eo`e=nL̢JNSOC}şXi}B[NoELNџΡ(~' ݓ]o:2:-K.9W-.F5GT rm .έ;"S5!;{d~r"9>ħݑ7Sc\=z1" O0Ď R;A272.P"*X%ན>Gt3Jv_}@ex89[Dk[ >Vۚlf>cs#wbRNռOsAcq9;=!kp|Q W&SGGbo-pt+ b\pXj 9}r'k=GwΕOc:" /l {]ӣ2W%ł)~yFnG`i,e䖈LrG؋O$qQwn{{ G[F KcI ּ[A,;-NMX}8GPӨmVdsY lV(8^-O8V#A w t< @[NrBPTwHzgi[V 5۠XO8}5W u%CLC;w1mmrJfqf 3-_rTë:^|o /PW[?G{vm5n?(mHpuo:Dz2X2qx̅yUpYFie3Wz3`.wbMU1oKBd SnSBʋQri0=x]E;%1OPafpF}[>+R?cqAO8>,f^%kU&w,ng51Cv<y0?@t%1+xo/)#kh $@YŠG;|2_gG=>( ~&5GQZ eLlg%| `ҌZ)^gJ.vC\'^=dڦt(@g-0#2Nqqx&٧t䔪l4ףt= lA 6O\l 7~4P\ ΊȲUʜʑfcZ$i @[:U-Y}2KY!ogPJz%f$Cxv() VYL>-s*Q2Ͻybzo_ۯQHg]K>TnbĞhqq? (9M!Y|e7PK6DR ;/f݌22DT@*xmkʩ Ӓ'Dz5ӿ6MfP' O=di8k!>Hj]AP~E1ÂrfT\rLuà!\ri~Kޣ|m/M^v3ɢx` VSd rb ePzu3\{b+C8݊RBIv"a(arcBceq ê# ĪГ6a_Q‡HS0pi?$}C"%g暾rDrw_at^^CLaQv$EDn A0c+!Ŋxt-Oi'B$7Ai$[ڒ+w-"]dƔ~3^q\,Hc8>xx?{ vKwR$xPQce4mdMMm.pՇ[; R{~W~g@js0y #bka>6*Hv{:S7t8ha c= a{L_ 'OGmj+T+?h?_1'=m=;.RnwpGN u0WT])HqP_` ~ȑhmbwr]JK;JB#K4%-tD"gV J.MqE}*r h x@Lm2.Nr r9L~'w)5.WpU;ÌL;{ VX47MI-nAA)ށc+PٔYH YIZRbw?_SUUBpGhzTCb K;bCxIy&m+[_飺NIJA>ҖV7okB.|,AfDr|r#sf)v_;N2n߻Yɷחcڪw-rҮ*_`r&ؼ2 iÃV3tOY N 5wI9-= K=v4_uN!cobWFWf^F$S$lnߞ^I hi/P݋SX!!v=C9Q+X''%<"Ùqi!`k.|Kq񆂱\MN<Չ aET0aiɻLgӉ`X28檰 8L>mGNgo1b9?ğ2`(y\G-ORIM ㋾vZ Y@[Vg$HP:wI.4`) B^]wMomxt<ċC νm/R0l%WUo{ҌP|YF&Ɓ%4U6n%k*0ç*[ z:}VBu3_?j"n;$0Laz{1.:L]dfXB%xxQt)…y<%úQZ0Hy@W ^0$\dVu}܊%Fbޏq:XsItq/3yCh.7Q ])30"~Gl ͘YUNOl Z]B!ӥFX9SAX˕: :Y(n ٚHpQS}HsT{y/Ze:@vm[ӧEd?k0+NFm:j1~#E"Fu 1 !tZ֒0plBVeW:e#{v4Rm2%=_?0%$mL!Ѓ3&a:9E "r[[(7eED??ve{q.prd;ہlv9q*.99\f+\/+<-OMEdeb,SϭR hFfDI@);F p L,*Q-qJ8۲n@Ox=BhY161Z`ssV;zpFq_Htuةa$nBkGqkGmdeegg'5eJ#uZg;2q_ )(t//$|eaģ.ƉM i0h͘H,瞍l2{+gxijV$Lnn* ) QDƭ<GX^4p6I=꛾# q 6 tn cNlkRx";8 m/JY$ABg$v` r8ntE˿t-QʃEbZZV)@ӋoKm&f-B=)F,Q$ ZXCTFzI) a qLG9CeѮZ#w}{% oxۍuo~C2\RoY:]qt3ظyfI,ȇ?*Ǧm u8 Gʍ1s,^%\AB6\g:iS5ٺI^ӣ-@//t @ʝDc@3AUU%̸dI\ MpI {a#x6$~"esGoeTBi- 6[J"Z\1mIǭnn7ݓ!j \%y N/HVN]2/2.1C KĵOܘVzʼnkNDJ?8t:ϥn4oᏇ/0b=_JVJm*I?AoRS@28bzlufѓuL4,2|zʱGulnYr"T. !Õqux)#Ph_{6CH9p?x%L/,Ͱ{L@SȜ{>a&ƟoH8썳y(J58>9My]Ǚ ԳZ19wIxt>_] C $םX:l׶\p/:ܼJ%WE^ @~rNpeh72~N Wb& q mgHQylk2%BR}yχHkR !tc?wwgDG”b>KH#1j?lpDt<7 f<ήyL & fghLci1VS҂xuD)DnHs۫Ҋ/]Ңxm-Nzvp2By֝0,i>)rnր}hC;=8lGcũf]ӋLG;WyVU.0UZ4#Νx__tEMk5i3 yR דz?iϳΩ;ߍȇR R/Z.?O/ιݛ|Y_w,q/M]߀]c>@qb B~4 ayIE#H:A [%Y@=a`|G1 ,@X,JWLG,"rKlnSzE,0}݄%~ |4&@)}i ˳%U<+@G8S^%pW| 4PՠR@8sT|o2rNxINm6Anzk+>2P3[ŭOݳ>oPVY\DܑerN8r6n*܅8~cH1lb1;wFxx+}GބlCAj$;V yj8 WhiXS \͸O93EM!9 +<>.f%oo<UX <~69UPmvGzze.fxQ~x;\]px鼳/J$)S>o -o|aF^;eߒ3ܰCϺO+MRd󆸙P%|սZju8ȪБu_UX^5<Bl,ebë]7ТO>>;kpOHD"Ii æT!FPjȝG0r+FMqN)j5:|%6юq pMpl'[`}ƔG%SM6Rq&,(7E_jRctQ,)^l!e]V?uvFCL)eY>E9 7b f9閕@:ʮ5^]2q܊0WE_u!R}@-<HBr}B ۡi?A:'L.k?ZpkPLV_f'' iòxD݋̡=aU-ԻILu)ANZJ jn16tY?"tHŐL_G_MIm(B{MryOTm1Gי[ZK;&>}%';A/`+' ? AEj-{=wW>aG!@Dڈ %Lp F&ZӐ-oq!| MUCl;IASrwXڎx!';8ϦG3=(JR_]sRLR1/zb[}h$ 1$o'<1,>8@a3F(&C(3t/X0QX;Ϯ0я~Pn'RߪKK?S LrEFa9bC&8ӏ,x_-t$F^Hu$tP?lܖD$`Ƥ+K*9R[rAՄTm}l+_"ivbg_v((KD;jhowniⷒ\pHεe';똛3`X>H.q@U΃1n/BU3%1diQb,?쩚2#zP j;ou:e|w_ZkZ)ynD/-HGDjBWWH(0E}U7A(j` _DŴmJʾwu4͊L/s9li*~l"'\=6EU g"?+Sk"|%805C+MF1+#V82O0LC iy]RadY~9HcWS ZDLxX뜭l5zJ*݅uYFyihBjњ0}5)ˢix&x|tw!f8 MtOw2Enva$c#?Mg hxGyNSj+07`pPlɵe|೎vdoH[`& =o}ӊ3YC? fu fs  tڼ)݇ФlzF =+X8-71/SO{Fڂ9E_݋,!跚d_MW[nQQg;uf=2+Up3 @#`r3 $?մ]NSWIHt{Oa_ª@!B? Vv Z&=)m#"+drqj GB[oaM|"lrXCK(ԋ4V4.*M:"+Rba}/\.p9X8fiL1퀡V<]ӳ;s9|$X9gW\7"ׁ'q+B\!u^';VZoPxm5&]$e&]BB,S?>U@r$xN9asdYPjvC*[@}Q?(z+"$luopQ)0690V7-yr1#>UmIze9\J0nK-'hiEAjEv0U~B"~L{kxXΒMwt9U@y(\5{ZՏa?R9m4{fcPվܡPUQk5X4ipƛpl XL!c0RƱ>UlT 2e*)*OFɵzMkô\x4˃6h`9# l.+4T/rر +7 uSk_.Aܛ#Jk@Dg{PA܃ y"އ =ĨJvz4NYOOXO)$jkfʃݺL6MHa %mKa<̋4Px09WjD9^U5;B-Tw9[}i) B:XF궈ZJe7G <}J9@uW:XթY^Cw{5Oi,^H~u|zÍ@O* ?:]S9hoD*Bu!EךUUPdcZLj*,쐂?  x$涞u>Դ4傏d*- ,RrbIE4RW'p7L^Q}↮]׻c=vׁk]"@Rs}\@ "l~mtڋbR/T_X0-%] 'IV^jkjPX])b3Ԥ픵,ChbNi GI i~;Lp{v{gnVVNB,[FXGH|S߯n%t;Hqh_r#]6Bx.ww1X0'\j{=LpZПzECfcHc%[/ "(1z㏓|N 9ud-!s|jQ34C`E|R#yS&(Li`Ͳ6¯/řtGrBO^&+zw |/̯V[ ~ʟh̩'t/j=nx uإ݇[5ޓ@'s.pn(U "t<`0 _55 ⼯%")/=cdJunsW k>]Z_mI HDD L•E0$9*нtdlkTف[]-  N] JiI8)oh㭅f58~@K,zG VyiF e]kD )k gГ?& wK{P3 mV=23ܜ~D[S&zi*f.JbprFʷmN9P/\ [ݝKZ/tml:܇0ܵ83K2Ɣ hmkGL!\/@ȑ󄅢z*v\24ufr`ܭCk &K \Byٸ K >++*h Y*QewWhpTDH5t>RY,oĖYFJqu8ħ$a~F̷Z0_C$&Aԋ_O֚݋x$= o7$Y݁B7%ɯd1|Lu˾d1r^%#zː [Q)߂̇ㅳr蘘S͚s7H hG1` l;1 GOKK?n"."v>!_PWѭ8i2in/~>7d2I]VY {mo]0ZPDg3p%&kGc[WLeUbtl| NK-Je@uHLCteG 8#GuZ??^_ C?@,l2/%!\mPPD'cy(j4.c,0ٟts\|,1Ndž?W!` To#O:* jd]pEdbZ6jKAnnd@]m9}[†)z!Gf| ` ,ϭ.)1:o!~zSՀBs!t p|q&lF‰y;R![Qfr%h1#kpfJZ M{I>Se~&l(p-ncj;]Mqxq d714ؼ!cA(&OHSKPgQz$2Dx lD~J-Jʄ!8$OA`ھxz[mj7@>qm[_z+01$́8Eg|@E4ti'GȴߙeH͐p&EޘSyF8"VKZK^Ui)j` ?XHQWJnabq 'Pgл $|-p J3:BTn'ʂ3Y]2#+"Yl6+[PD|IBk0;-N-S5uUF4J+L( S])څ_S7ାZ䨤vDMJ hHQaDxӡTfl [i[̱ QcyyUw|6#f'ZZ'amӏM>kp= De [^6BN-)ܟݑ{6>Y ɜCx$^kJc_\:SYؚW*k) Bi"Fo2B*Q͊`#Rj1ႋ:hb. Y5qzwQ9 4ӳneѽ{Tzz$B489a4ɑ{ZK}VjyKeSrH7;}&_Lx9_ݫH[bJ7VI`鞕LOF9jb݂ܭ~lЯ& X I|Ob8=@|P٨'6=ڕ3 6S ݋٠b9R/'ךF4)ȅNuăѩ+jJ ^b|J3v ꍆyX={]H?P k&r5쯕ڲ)7J.薌vVU*|3Ts4&KBerВ"^oddMkQrYG)HߵqMX@|N0lKGt(2L*->@_ zkIQTVS}4xW2oYI !i= |j<[k55ߪiuLc.~ /ՍWάn?(Xi#IQ!}z?tzaBY{AY rseKU-(Θ (~xauWOr$hzcj>}x9iЬTlу6YN$r> 6ok O@qs}6p8C\.ւ=JWd̠:;'n.?5*MPW*1𹖉ϺS+Q|`7u.&<|L\ʧ笘pN)]ܥOgiw[vV ^K)lpG7 2P1j}W ! n2Rpmk&23֬$IN2dNJuDr}c|B(Ԥf!l޵GqPx;hK ]U,a.6(7Oޢ`C{=%E?6ZC+;# jt(!;yMcF /)GDX%R`oBYVe3Ym90\ؤ ѓ1o{QKV!g2cQO9;/sK@+u{@ FDInt#?6} ܺīQ& uk{rSP?[@?QXqkl*pR+pǬ2&=VWŽB#h=%4,LT0TSܶJ iręu.Yz$<~$ a,+j=NPs5BsjB~lws+Ӻ^k.OGc*F3ܥSgK +4xGP#P7_YK4y))k4| n Dw){};Ik+8Ġq5>4 gv1][J~j?mW.$dI# ]_D޳F{Iy8_For~"bz,Gw)#I9ZsX3 Y}zuuC:"٤fKU)+*9GECO0'qryAgeޠˬ+Hl˯z˝mJ2p'_($|XQ$LLKQ!+W"tO y/xB< U#e( ]Cث{QlgEJ3uIHz7p |8 由0xoޓ^j}[gL!VTB@Îm݉I(ac&d$LJ#{FiP|׹dd)kA!g;Rw,ceSاVlS`ꚰfjK1B.bqAO<,p'30S#d|F!Z&.XM9@9PHƂX.0UzIGaVhX~ZU N64\띺*4 KCukbs 6U3y~L+K cjޔ:@b#o֥z3T/`iĄds-Gw/6iynR24#T^)UCK']U#p,-SG.Ʉ}V(_USh[Z k*4;NĺXY4~Ad*(7PK/;, V2Ou.Ue>] v`VRlL,\Q#jacޓF# A6>ʆw1{A핶#NEH-:{]Qx$?;(;yiIFA$k,/H|RUSڑ&gSa~\o9;U fѼOQSRMT׎¾MhO1 1Il ѼCCr$iX[\ɍND.[v|#~ FU{D" ]pVp=$B.͛9\3^H;KЁN|#nv 5v DUų&U 7\>CI=k0&xe! t|jethD۵8E3CFօԛ(`P:9{L٤*'\MiY 3wEsW$9bз({F #O0E"mvR&w4ͨqE6dJZ\m"̒y& K.~;V 9vi7O /o"XJM_C set7kkeTO(rqU_Q?j= lXWݖ []dhhɯ S<Ȅa ؾMC3Ds"p- Xf7_L1MVC&{%ZAAխ{!:] 춯"Iަ4hě+k-VCFT(I$˷=UaoAk6Ge RpfhzLėruX D-%N, !Av ^c<[%F9P>u袆9=E? fa "ϛC٦g'?c;#P[ Lx+`ۀ,0L=<6h\]A_t8PD -d1yM6|gF{J^)0z$"PfBZԒ%)Ɵk栱Ȱ]:Wk˞O۔3pBJ"6RZbQ} p=ۣ-D`g%up6y^0% ބ4hW\pF |Uf}jPVlцì84[Vƍr ߨL0.D5 ] |qQx|1AN/haB<ĥgT }@:{k)66~+ܐO٨TjʖG>.&'q.4̖Uﭺ|$;y F'a*fl3,˻,pfB HЛ_xyw3;Dfo7o:&/,Y:+2`s/8qn.T3Y/#E!hAN~9q!W~gp I 'fGGFaF\3Ĉ0"Wu5n5 #gS  ߻C 2 T=iE = Tg/jR&Ҏ7&[,q.Anm 3pĆ[2|&#YQ/1@4S${暗L`R&0=.i3)A,z{r&+S"}P>PSHt.|.'qP fPX2+4E|Le'FBw8z$S;Yt17`5DM<C7d/FBo/?U&'W)]&`E)ȹq8]4HÎ~κ9$IxA~eWU/ȬI-Eri7>퍲<8AD.;*aE Kզ{sj)1K&9k$ -;}5xH)6L SVBP4'}!/ nj65 h[hG؄n[m>0YSWcf'D,J$+h%t"CyA0Z$"=KRzeͤDrF&#cn6P"Yjau*r, 6O㟘G)D8{ݥ.m UG] a /K?р?G34kQ{KAaOs`?*\T]pKo{C=$WդPOu\LԪLw8)S&&r\5~!A`m(w/;'3*pcQ#1!ٹ{}g4?#8Zz?Ht_,+d~7Gh ]k b/:8+8,ģJz }1/@Yo I..Dᐬ 06daYrG,#YtҷK!{7c)"_@#[W6A<4Z >Y4iLE-fP8+H\[o*tSu`-!Yp;xD.WfkP $[8 ^T1oDvʅ9Q[G|f&KK@R?5vz*esDHn`];D'W]M^f("dTp.DX.A+D,[;2toIOGkY 嗼/y`" ZуӵVfn/- z4]U'ZvDEf!QjW$*y2Y]+ӏHYMQS8Iu*ކreZu2wQ8$prs@ؠ 0س kUco-kGbu<2T;(&|_ȇTvD75ڵϝfuE-pH Ka{B-xSX_8-)kH+iY|$ߗ&-RIbsoKsaU,oX\nD[( |= [ťtj9a;yZT^WLgRo>E sY[2/ YiQ1{ `1Go=/%M7!/wh4~jB ЁA:3>ok&4k2 7ѧߋYg9;j x"CB㥖Co 9Ё]V uUJߔ|)) rɮ~Rlv*Eh)%rfx? jVC ew*OdH1X= ׯ"RbB ~!]{{5p1$}T̴/{0n5ѣ؟H( XS}@%(#&P@X8@WQ;4w ۋR u̝9Qfe{*^2V;bOukrȁO6fdq2k̚ѭ:"IɄd_`(߱\,El裏$.>A22k+ j S(TM]Ҙ@Kv™6-Fzt~XgА)b DCtwjW'?qgqR+'bbYs+!S[QcDH~7w5 ܎۝Qd=jtZ^e?fc35ѻ!;)jdߟ %juYCW]U6S I#)\ۧ+1[ &xGW "yH3 k֊l$tlgqF%EE-@W<"*.DE P$LNUdsiEx4ebu9Z {6MAZMGhkKC ](xBBC B'GnA6XΝu8=rqsj|Bs0޼ }ԾT;B:HGf鍒ŴމV^otGzSۥ$.x'1\Umfl, qem[܁>F! hb^P T2EQkc.dIL bA%:H߾nFlNe +)CˌS?R7PU/` /VcsJ@\BL*tNDũ#Iy !.~Q_C+uL]vJrc1) H w󼪩2[E4^a%d[z|~ ,["+Qe DJL0| LIe8G8q>huJ0)%]Jأ}gfLiVMP|6ĵTx;f^@ e0=.Mq*JHGg/=G:N<,C' ۞2_l=./^ !ƛ+kW4|k'z$ܤ^uJ3fyso3q}JיFjɊy6㸲p{\iO*v`u;?gp#e66+?,]߭>.F>t˿{/' &JڭBRlzeG=pV~3kO2:_>h9OF/q9w_nkl_Ʈ55wNair.zp |VFP=?!9OQ2IdT62FI {7uSuȆC'\t (q1+=X(4-p2%$߬Ջ */&# P\"3'7Z|L%7pt @{Alzҿᤦ 7L@%)5򻓼ю>zIw =agTd&9 kjkd-Ϩlk j5o{h_2W9'D7v} $^4+D:\}p3dC[`Zj6a `@n4]^:#BMm{X zimxv9`ק+ffyKFP >qD-bФ:hZ8y5 B8OrZ͎/; ٟ:'wcNH? 8` 56*DFK^km+ukXq; s#ahy:?fJ5<lAӭmg]Ԙ[,s>X)4!,7rAYMp+6E$Z)97ӥv|`+ }H Ъ> ^&,S`ωVbEo?lwa0I3UEt0Q t;̗{a坕/Ȉ-x}v 1JwvMA5hwǃ kH& !"#=)X[`^Sk@N1` a q aR>UBiKE۬NCd}JFl[( ؄fvF?ܣn\jEW#rB@s(5q[G jGU #jWЪo ӭÆ*IQgρDkmٻ ¢(8S1IW/ǬEiDwùz3$ ѣч؋!gY gRqJ2v#m$:kF0 jg警<kUw 3|60g$ol.[tUNz)×i0O.~ęjC8ZkE/ 3 ɨԌ>Gm,KY 2"[3b7y]؁ B~S9Eo *bBa)*3!]mރDO]q#B'5dzrק`*͖Z[S҈, 5}Og"^4Eԫfk6CFcr| .WOZ!X;%b Q.^L]jc'h;Y1  -W 冉`><4K{ƱE\L״߃ s@ZI\GY{T@Y"P0/+x9ukOa~OWUD/Xm:)Sut( VJn\z6Z̑[OM`dd&WQUpKVLbzA<\It^ X3ˡlhJeGkAs%tۤH,&ƁuRY:Q}7W]:lxe.+u#138"B TҜ#¬kFj*$Z6 nT ΌP"+۹m@C/}ǗRзj[ b(D[k$" V%vũ۟d3\ BFB9~.kI`S,e~庑wD8yaj m:2SZ$CŠ.[[L} @-?u†¦&,ԺyUv%Ex:d~;sZnIt\y,)TnT 6g.Ba}硊oB%!Gb|ח.5\E@DiBfa\|y``2%U^^sy# Mcbz ̆Dd9s+[GU)A K%"k4LgOE`2I qhioٛ"="R$&00KWf4e:8@"lڅKHgdp!F;)UiGz ^Umwr!N~Mu7Ae (Ma%}ӡ%{}3rǭ R;9@k?qN|cL4J h%dZzIQo6X{:] QU9"k۪RHix@"^ DF>#m{1Bg<^˚r$\}W&bkr"J[-*Bqc̨+̙ ]lwK.1Ӵ ^{mNqrak4NzkOvFR곖n qtHUZ&AI\}dB8Bgscuյ:;A4@5Y2>/SRHH#;`mڒQ*m'#v6w RZ{7û9iF|3?ŻmhΒpMU/ 0'vM'蔜rdaO/j`#EChwS U&h'y'0;НJmBAbT5)_ ^.,V TF xxrdؾz`o2Y@w'qʩV:~qrzy)˛w |C]5ǣa$&.9N(H1T C fV4"INT8Ҩ_3 dm^4+blmuI@BJzUGR&$Bk08VgjɝP?tKR5ֱB!+ "W8\ 1Հw-;GC]S*7warLb"g0g|* 0#8Y'OYyyp3 k+Evkg~q;jJ_!I$yߺ#Aa> aNRo.G05oc1K$אC-/Wܕ3\.z>}ʫإ.ղ)‡*.YEFq<|^j_)K8ϤO?ϽЂWFRP82p{*0]ە5٦_MCAE2u*ɦP% HΤ:K&RDe- Yc(NJzog̵/;ג4<2V:&nV'Fpy>8U ]M͖mTԵFys1&}w5mJ_rZ_5aMWŔ?>*>!Ps@% 6 1zd@ѹjO̮ܸ0ǹӧ0GKEX-h>Pr[.ՊŎT܏}+Hqm} ?zLY~zRw6jԖTFr=ú910=4Ҽ-_0e&V&19 //"ʤ^#3Wwڔ6)5ɐ_<[0;[],'3A6JY*IJ=s"ـ5 0#ҀIhaԶLO±Ss' 8aBmr -\83|FY?ip1tR=ƀ-cBerG|uF޴Je<@7xy)/M+A_u4 RF2mz z5ĤOU|ɕ"JŦViDT.C?cSNUɩcMW=wT%@RE x i#v7/x{kv8ͨL% ]&cض_c60n-h?yr^Kx&?uـg3҃zM 38d1 os %`g5D) >.ƈ5s!e Pjv{ /~icRMQ ^+ͤvo(F؃gWܦL RqBJ ɻG^1 {tk@\T<UE> P}_>?3!.;0~)OhR{YnWnl:Vl& :BB{0JUxeH<R`@BS#A1ERD2JEMHյo!s̤8tP;p7e5 D6AQM#MC"CM-doN~fUS'!C jYrhc$i/uh~ͺ4Hj]߮fn.;rqKZx*$Jcy E:dndb e84 g&$#Rx]}tkԖWĿMڋ${W>KO7 B:C_>A Faߗ GΌTE`0-ˡt9,S֙׮Y#@_}])nmGg'xSLNƵBͺ̭D b>q%*:F=BϣKA~>Da}Zj)Y:I;q 8 qZ@)|!U<&h ٭jw:r1<(a 8&$;-:aoX-pҟ0ơ]5י/d,8% xo=n-6S@-e@.Xuȳ L" b!gYCbX>B" CAtSz&Q g"׌$Z&qFx?lfDs* Ck{^7;\q95tT ͿZKy؍0@ղzD@Uw҄MtDeyxEˌ*.33p~It"EAjKVulZU|%>Ƞt#t^U} a /X1!بP7-'=x ʸϯr$>(\|ʏ9T 5wY k6-1"FNEHf,e(93`:=JH ښ-yM<(Ua/c7`S3wlQyNcD7'o > g.4LQ#\ ٭P d#ejSy-AL#z69NVU7D> 5g`[]P7Պ%nɭ [Z7%8ݪTU..$5ITl*w޵uz2҆s3O Kc*ZI6.uzad{rcP]C䠐T]VX(Y-'c|%ԗK/ pʮgz?a60L:jŤoX{/޻Ekl{ӈz|KBJDfu&t]T훃lw^Ah©PSynWSl`t!-TP(E8x\'wl#xgM᫧=F&/5ڑW{Z!1rS 3t8orXqIp̦\ڈ!e(JY DX\74|.Z6 MٺtpS]O2g3"] nbvHJy QT0֥ ^taNCC3Fa9]xywP .GiuQ573Єh, @N(愻s*B٭rYFJdkL|Wy_Eb*9R2@jfO`߀CZE9/ m?Aixm>|k-{e=):Q7I(@9`.cJE <<+v/ⱸ?K)J;AV?,=,$IXd;O e%3@Q"3rJq` NprVZy:n4p&2B$.Bٶoi{V# z5bCCjUG1k:fw)Y :Jul:N]mª88+BxnA+ e6M>#{|n9Yr]}co]<;bu-NeXoɈeT]&lPw}H5tVp? 5uLg^ #{ -{e P-m:hDVP:Pvo/"!\ %֧W:c5\s-&}<^JvE6HH6GzxcQ Ȫ7''BlIXfo4)! Ո딫V,gޜ# wiy6!G0IkVmg@ ވ֏0i\ hti-L2h!/z!\Z6DxVW;5CF-RxVLlQA91]X'~ltub0g xH"kn@w졺(5]Wݵ-gwMbץVTIEpF>^@>m  0 w֡8#lW׈Y Vwlц,L D൪i;a<H(e\<:Ӭ.40taI=K+> LZ( xoy4䙂'eEmЏC0!C[ 3kۗ(t&+Qh%1 QDtVW `7a jdL _]&!~KN(Y}rAmȩsǔ>OZh$lT$\DZ0iEZɡeHمQnJ| 0"R ~Omf@KcPPAC@ὣ9LH9naNaz!n(wRU4ݒWًcr۫8Q5<$Кk?5$L8- %چ:I}fc_l.9R* X^>]U y=^xuc0jqj;k'#;DumA/n,(":Ĺ.+vmc Bz4FQ;nmH3?~1SR/ȿFN ,j6'9U}gTpT0UeI!J/^ : ~X3ǼCXbcflHun8wiûh1x(Ӟ\ŧ9\@"mQߩ#d۱|^%e+ᎂ1VfuT$5/ [ c]nL63SXC!!BSsf{pMcb6틫䑨pcN?"&bv!{vBh~&>n|r a'INrk'j?1cgB#o1܉4[7M3B`RڮRDŽ+w,orWŦInb^lJ i6W<Ȣp)#~ⲇ"7IsS(kA"YΉ*"H lv3X{y?!l?O#؂ HȊ Bi @"bi [vN@џ/4`lKduojN@, kZf@. gC b]G=,^JZ!D%m MF0i"AνqQXv'VU=گ;>4q\d!5e#Z]-d9bωVLV%&O&}%Wkd brS#$K7"~cTHYIh9zn٪oFC0]kh _ #eR8nWTE ;WNՕy;\1pQTxt@$IjO6IjA+8dnbdЎ"xb' "8Q?WuE;zu2=.vտ#wZ#,x,A7\/_&kymPԈjuXP&hZ=T. AMl {ڔA\3jJ 4N,t28 L}|J3Kj?# 6!Al 'vCE-̈́ʣep;ڭD`\#ёBmH ^z:) VL-Qp,<8 T,Iqkq-^)?iy"/׆@@PEn:$8myH"߰HN28CګB L| qݿK2RFuNa,DAɍrX52JCr*3b.dHm2 ay()|ulڡYFK%iyvJ\coLg&az.T2Z㫪vB!$j,XJ1\Z!Yڜ+|̖uyd+(uFYFXQ#XaaH94V-y$k v줹];e5S_N^G; ep'Fe[\T17+΃="O"^S ,b[ fOlV9,\Ř> QĦ4z7Rl L6E3NQӘ2f(JbY|ί\/je4N$Ugk$!]}4o 3~B v0!5 27w}X~0.ѵl})@(y׀V^$vcM1(b/;Nu^va2XfP dbjDBVވp#v XY;'2Jm5Ƹ.B0 9^̊EO)`hAES\yiL|1o&DÍ8B*8xpX!2B%B&BmZhQ9;PJL9:&#J^eNRƴ@)W[Mk 6f"$ꛔb;4ڴ ć7GbH,x;eɰd]0q)CԵM+q$sU! :1ݼH%_i ӛ8p; Ɗ 4f] lURp&b&t89~M$t? md[VB)"GHf{$5a x[ 6Wru*h˄ӘyũzfCmK VB00gzə;P98m]٧\> l$LKyHO\#AƷtu|`)Qd%h+dN&U18/NXX”驍e|ɛvVzLEI{#+xpݶZ&=|SN,aO.OX۱f"H-X<3?po%4LEls|\i@{(z!Ӻ$-wyx_!V1kIETtǨ| W2qiC+~@B \)9LcpdAm3ԧ3kP5*a֋07:>(GpL!z.WأuiHDR +"Uz ɷge'ja:8ʔT##.(@IɂFRZd+َglf|Z@vp+7;ah4x*Y#2\[Ec)5VhdL,Woq[y !/݇‘Rh)0 s:"!0MD*4%_J>X3.b qay*W9+! 8ɹdS QDC#aK<%_elD%F!LPA}48]脁ڕ'%"UގWѕ~3 O#\guH{(㇕&ۀDXk|4T ֹ%\ÂO#zJ^rg$#*fؕ ͥB<ory>i~ $km8"F 0vtl>f M`Èu%b{ޖr<_;ƈ{I͆2;آtLm{95iH(B$q4q\:IB wM lHDQfAXSEFJu~23.Te_5GI+f%dV"Lc֣hϾL|:QzhܬB'%)9++ԉ)&>v& FHD`ľ{rtV΋COoˊ9 zccg\F;QB)AWd KDS#3ՃMlA6_X3_DfKT.;kMНuL*$HkϥS{1kѽp_p$Nxq3xSoyھr,}yGʇl3C |p@jc zWuqXzuڽ] dÅ5['_;3m]j%{u.ڴAĬ59//6JC${Kg#/c_`}))w0ċ's,$5 L_r7 &87 ,xٍ {떶W>P`"@݄d23<\{RkV,/wa~d&Y)Eɜ}F6S!8R##ԻGV>^;GTrj8`^8LJgherD5z,zZ2 ?)c;Vdx'8  h/QP!B^^ɉc =dsGpxMvhA[x0ihHhys˵oCɪvL [=MߣE 7h 5( z6KxP ɒ% F5q⿰7&u@7xT\TOzw3 #uɅ/E [P;"]Y!v-4 _l*v{|* 3; $]ŇTIJjD_mQs<2݁L',JJ"PNltw (w*BRuvyݹ&A%x3[||~Yh^y*3QzAW?즮b^v35+rЅk\ٟkZD)1 6W zW-ccɫQ Pz@U"oswn8nc! H-^ }+yfUsP A[7}t0-ANO"2uzjH=Qf~d/Tp9vdψ~]&(HMKIUi2+ ]2hݷp-]ZqJ-s|5na+vSɭé20?d&GNNX)ʋ0)q_AC o{f@^Zۅ!Zwo{'fi ÷I ZLw88M]zE){}NwJWknYIfĘpxϫ_of 3U{w/,䙻N!Xښ&G\\p'8w*fK8!9EQ=[j&j#{ ?w"@Sj*[b&ϒ0Ts n"MI7<apOy\3H_)ӞtKZFpBZ3ؙ#Mrw9i(n%^>c\%gM՟Ơ 8qcAuа|9ݑ rʱ!u;k@ٹdClA@\ ;iJJax`fiK7NvXmKLlI41?@>#teZӘ^Cq.-mV$ 4%J]uҤs*Bn:Qj_C GBάPYIJ $Nl-V:_>noVMJ{/'%<%!`pa6EpE"GW{TJ64 !]|5#s.pxO aNKf 6%SU>J t[/Árþ6"%Ut+;[#3?^=HkTޝcH?)Am ak63jEz.}L CΔEC=Dq$t{Ax9d? <ü>_2&gw=SPG득"c|:)J*ı`?;>n NݓY8ICm|cB mw9(ѰsPSdqБxہI\.:/@TLae' G !~Ǹ@5U=q.pi>|n:Əbn:5/r,rÃ7K|kVDWɏpWX:r- 0g[IzE֜Wإ*kE)O(ᡆ~z1OY7KeKCsLG,k݋4jv^{ݞdF;%r))ႣK1V0 O.Հ_. SuNepQK'ʒG3=W5*5r iS 4n.&%tiRM;!BW# .I$f Xt0B 4^ d?4W#5HOˤ$qL )noy y"e/ d&sw4>8 q&1"ztCӡ@OkpX\袛_BM5!c ,t0ۂ.; ٝGG @xUǿwMfc+$%AM=v JiYo!/8CQ@n<b6EC<~3J e#BY/'{cb$S;=, ;"8 #]1N4RW֥Vk0B&~/;wF3l[aZpX,KRd:oHW?ԈuU2/C9.y<d 4̹EA@@UoR4LsmȢNjxL9,ZxMZ zR;#Ez@r;z I͙iT 3k]ͅZ(Rk )f/ow6f/ˇ1eQ,m0"剶̩C״lGIG#܍lg67hߋ2hd@Z,C{R%"3ӗ2?@'So^'~ӼrτOKUS jur;IWsD$)'bjN+ESm@!w~AaR!Ȯp[%1p3jȱcd)@.O.O!RLp٩0#Z @\2&U_ːbheqan0 TNjjYi;f dѩԳy#/dT 91S;iv|,l8mb pmp8*!bF gxeZ>yb( 8.L6[ 34usz9||˾M"KI: ' xpJxwM^E[NuH`K1;]nTxQ9]OVbZm^6<%D^&EpO'Ⰸjʹc$][5!v& etVa!E#'<^ ~I>> զLʱ~Oe[]}{[6$/^c ?s'.s8ґ}7æW>1MsyQD(7.Cj y;L`n:1 5$:I5@x޲@.'Ak`kDl0*8ulfOҴ=74a'!p';@U9cͧU7pac"Ǹ7FwQ+6{?4 x=S?L(ɄYgH@Uu,"^s:N/b^TnyW^׆l;&Ie>"[gBL=7wqafzLj-DIRI%R6~Z|LM`NJ3-H]-vKO[{6VM*qt;S剚|(f&|EeykމlK?yl&KI{f=ͅ62sG=} s@)`קث~>|;xצ $![}6U1v4L;:y8<*zɿ)!ɠi1`g iE51# kt/ 3qZ!X|? H֘y& _M"tWt/Ñb7щi.ǫV^ br&ج P\<'GbOǰ: -Igxw؍iqܾ3 -@ӂh(,2PU (Ә.5|2r0P! T'@zԷQt͌rHiPKHyeY1 =t)FK󜙢-~܎~6^10xp8sg_QkOTzKHRiǵtHb fj`հUDM{ĻM[g?і$l!u(GȻ ωB:=Z6nl >DL_"²I|PjwVu0O viXq%J?Gd璡17xN3c效X%^=95 M%oE{祀CL@*9 ]G $NCa Y[s MwIeoMt>]m4pHgJwk!"+yȆ 2>,27ÂIR]>0n`gG,4ծ$u6z i z> p9%P%Y^QH;{WIz\8UKvHdQ:˱b u/Pyd_)#oAyYBυym3 =|!?:gͷfd/^J?/[- ?8# ՗r&?oFL;F~4!tdqhM$MmeU f[(J7U`]=\bCY9C02ό逎{VS' {@ɋ6.t9 ~?y5# Tn064<$mI .-r6_sS~/TNUt _-Yq[IDzZ#\ %@&П2-LBF7pt#S~| `u 3QjҶgs6}c}!ci!EoT@7n#6-̼]iV2I-GsN3R .ӐصѽIzגQ!%V\^q Hc'MJY[S88U-+[b^"t 'I:;EwEta@[)p3ReFq l7 &d q:{6<{8D8++}&=:^E8kgU3fFTXSdŃ {/&<^BRMr8C,egΘ]2`ܘiq5J&|s&6MQ^ }6 E9E3>E l~^+ƒ:}1Z+VaȬhq{Ӆ!4ȰamֽH"pԼnynEj'n<'ԟdK(8p5k9)󍱅qw[{iAL0v$#L3Ewk;(l(z#ޟ7m NU!iIR)$H@%%_Fi@4OKodgFDD ÇM[LWbNgޥ }rj>CU9k e=:e)×Щ>l{̹u )"zB1e ,//`)ǜSVrJU1*In>;I7ڌl=[ԲP*S \jyیҺV_B0 rk:Ay;aRVp Nd=B]Do  )e./@X%&>>(),zh2΁T|ʊQu͋tIU{pkay?0.8&Py1'L,/6ޠjvSu2֥s#-5sΡx(jHI]{kpJHxy}ߕ]ڽQ->)ȬV1f.rFbwew1v+nͱ5U>.VISFWS``Pn#_'7%ɢ]p>yl8'HӨp&UHu5-%GYh˳|\+vBveo7 Cci-u<榣7!6[۵r4{wV8~is ߜaGщε-9 v#E:0esO(>6ta(r{c!xԵa[6z㠆 V.N+z*lə~tr:N| +'K09v{r鮴6([ޱm/3^Ԃz@IU}O. ɍY߹vm1{'յn!cku7S 1Tv@洍q_a*6i!G;3 3զ;3IWq|@H=,?pR iJZ"70saLc1wct( ?us5VψR!яlffF%pV"pTV/o`Q+h^yG1rze_3o3AYnlcsvN mZ7Ц " !Y1pF3|uphkQr{RcҤ(̓>cOqdIF3 tT+>" dkCP@rbm ;`7Tc4@DI{zUUCӂH(5p%w1Q;L=-h=E$eamV[w.Mdv&õǜ2T4tI9$ԑ:²@Z^Ot=Fơa2EKD_pA &)ډEQH]v}?>loOb7e[5>D&%{5,sXSh $'sFN_XIgk#6;~GȲ%qiw!Y'cL23HApmptDK–-eV&Cmyv;' 0(WQWm9Rv0H!fY-% E1֩ Q^F@Zxudyv`֒kQPDzyX4>ISip&'M#-X Ck0hpd<,c>CvX2xxA}: Rֈr?*[/Y AkT z!ã@cioV[\K; }mxGuo /Ķ8e^ˑ\"1G9<^Zvp2O9|&Hh4| a'>xY; d擕'k](6\jۭRٵXsBo;-$E!H{EhW 1)mL7T;8QbX7)zh2u=.;PSi:?2)4 4g6K55RV*|UЅt2λsv߮}!z,偔岈9NFuNc#qI.a.&NҬ-g+w(i S$]$$(+2AN:@Fx-Cy3ŘT:0vxuvBA9'fA :pybfRߦmKXpK wS v[$>G]8YV@,V¥6}XȋHc^qGj \$|u޼-|\Xb@G/V07K`Oʙ9V2lKg6x( K8h_Hd̲8[> BiE'^(yݙ= I!s#3pdhϽ:o UjE#s)ү$h@o!~; ,. )ׁawܕ> p+o6ke _&C!R^AG :>[(O"HC0}}2ɟk ay=Q3)%Zl1ZG}cE$/4{MGEEmt $`Eg(QNR"WKkHf4xW)NE戓o;vq7#/r`nWYph^ŕNrڡ~ɽP/ja8kb=*_)Z!sѣv? E">]0A'j{xS[M-LY !͗^Zwa5JuP?N]`Cp8t׬DžY4 I?ʋuӕ`N1.%0V (5*MV `y[En5"%=ϬY7\0|!عJ>^+ؑPaD͵V6hZp3،kPT.> ?9CzH+|`R ڙq'2Ah(M EV).ndޠ)N }0~YTiXRvvϋ//&[Ճ#WF|\9Rg``sGҹH&4gukڀhNKB1Eck|K[i:0Fɩ}<'_L|~|FsԯHdX5S\&%g+)“:Mx8|SWk40x@s@) Y<9TSu0 JD vuT&N_7ѵl>c3rW(WpqF34"nPQbf%Ŋ_3E|ot[nك_x!NR]nkD82.VM~qOso*܄ʤ5^ /H}a%(:MKr c*Ę\6=ˎGݳ1I8=q Tx v*"w n 2-)hNS_P{ωCpJ"&YXB2nX |AYf Rtwl<w'E 7gH^zC3gIWO'@kcA1׮a"Ғ5-%:S*[p kv46%՚;;қubͰ(UՃW-T#7kb1 7MKgcvlA'5Qjw ~5^p6Z ):?MM_.&ﻊj'Ě~G[GU< z;WK-_'))qgʄ8NnG/*d8C\j"*H)uy(M*޲(XɈFp2TQ&V.Cy @/mdzPr@^@|[ՁQ (r A*ye;E~Yg,x.4W[f`\5z)7 t,Nrx&^w}GٟZT}{!tgw2QQ|@H"恷2]'&y35f_Qi3%~&*,^߇ɱ&:Qy ܂ukO~orn#CfR:r1U@p~#+ϑ` pW/I9}TF7w&|"r{dJx8 2~[Vlr_ÅCA L}SFS>P0pG.k +k0@;e~YS4MWVh,@v6،~ɵqꢹ-{ H޸9a ~Gȁ@R݇z_@:*ͅSa=|]\}u ) 63ygpBrɵ9=cTq~UQy&1km\ Dv w wYAǰhkz==@M+'%%Rf彺ڊ>\="rAq%=f&i{-Lſ4KP~{U31p)Z֝S4fe iXOp{ c >O$Pz1N4AT G o2>2-&ԟ5u"EMxj1y,4k/NG2.J/]WފB@^{ gz.ܱ'ڦl 6\~s~WH'xa!gEgMӻSay vN=WF14*nZ4pEV$7b8ƪwltsrF $?b-yt*Z2F]bἀ!ڪ$684O!^mI?!ՄCyhB=AF{tip!s)K?@>mcAڕ@xc|E{lXc.ND 2*UØd2$Zh7w$-Z=~?))5p2#VIMO|N\8"p 8_dJ̞q.^#pkfRͥsヌP$2u naf<7YX6IiiEZe CIrV F}tQ/( |=OArFXUY"Qls}[ذNa<3u/ns)0[ayZUMqޞJ:F֭SJ`Ըm5`!XO4ľi?qFV<%E:O ;͡W!vnٚARI<JISQ|fTx֟ %ZgC.X#JO&tX/`$U/ܼٻbW㝄%kKxr_chvj2X"9NSw(p|Z-5V+R|m!d'Ixi]4h /5ퟤ./H ؃Cm9%)<2H<g} Z enձ.]["\${Į\HN{=-(88 E%]4+`JbPf]H;W&`c̔(rBrpKk:}Bk-j#n7&׈ x})(4S8peOa[rĪ0UPDwsD{u4omXӨ0{C#IƁragNS?grT; \ &x*\\wW)^&& 6V@@OrZ_ 4# ξIR}&\19`n=f/?4ffFd9CA_omMlrX_Rýy[9Kv&w"3_'ZÌ !AVVZlC WMwr_%a=_X2h1a _JqPKEihu疟\#\K)[]`Uf:?:H?{cQ|J_pѽgIjŎ* "~\V],.`57XݴpviǢWJ)jp^TBf#8ǢUL[q~II2C*Z(/; q.Wj{#mSy|=9r?_T~b]+vq\3ij♸Qx챁*b s:/RTO{0=*~؏`:mYQd_lShC|lv5fme﵋<$d2G zp1v ~|+sNy-e:V&;J?WWq>wa[#$I)|󄃏+MIaޑ){^mxa$h!/Z5RA ]xb# n%RS{) 1\KOξLL)^R:Z)13EĽ7s[.UbY&>;OE4H WJX/mNC`x9`X *X.ai=1" M8:'LRabsH@T+~XWB| K\ 71m~$ЛJ įk"~ol+&-$d.ʥXe&^A.ih:̢}H׿`C ĢT=("xa{tP3P _ǩQ|M:gE_h.ԔXq[#Mx,AuI?dTyoDͮx  ԐF`8=N'cbor% N׆H}#m|Q\ E7tH^hGd_$\Ao22ZE[ ?4D|]3*02bf2[y'^?׳SH,>`O?'T!FdA 2#I~q?77 1$yI^90v=ɁQX28.ߑa`a[U v5AQȃ9<.;¥~+Qr׼3_,m5ٖ;-DuI@.a!&|`bMi aCc9VSH}@cD׷l)ҵn'ĤKXI2 -GP㘿 \8FY~h[$[E9x&H-' $*˓U/~ٸ' yZmU  tª2(}L;xJ~Y&3~'.UŤؚbM]'6'jX3 ߷`Vsk뙛ϵ*E?ك,guf}178p4W0p01R2B,r$l? jZVuy7cOՇjY+yT`~妳_o (0F0',vbgLI]ޗ@ &+Y}VX/aIو#9"t/3y ʑڴ%Tͬd@[%ԀNylDуڛY{4kwֹv3eŹ=*RܻF =0.$B}xXw" *|I)#wl'f u_p7RA%jJq2(h\g7uk(͈bpڕɴoCFEh-z'XyWMe4lĐ)ݦ5m pvIwK:#Hz;(g+ n%0Smo _zI6SxY)zӹ s2⳸/fdQ -P G]QD:ܠ BQ :pf-`; KwP> ^RժQ s m/!x2Hi&9Q|(ymhqbkdaPHYlq;*fTuRзH/Tւyuhʚ/ew-y,$W@:Mn3wܑR.;n\z e:Z#kUDN+>t75/i'_}7D W~ycOd&DnjA:R^,Υ/I .Ygbfd$aa@U~.Wiί` C*dnֳ-UIz 6ٝwZ<Æeq+ &ӚGײs^5 Ep1'Ɲ'6x= KpyЂTte;۲Fɒ:HB_8,#+]7J@Uq+-gzrͧ[M(nׅ HfDF6ߧvL1@mM hsY:+ txJ禮.+yDD, ~=E87waUذn#)zS6C5G&̓pǛ҅O kd}9LHiAhC6rXTL`R*g>q)v+]k5~MXh ?riOdNq"u8E@E!eD7j2BVo~dVJ3~o`FKw3ce?fuyuy`JGΕX_jYl+3It%E1 YiUi6N~b!*'=q{VZjĝUfv^D6Eatis"4 ,~V#|HlΚ7n-fv[pNj̋^c"){  F\;BmNZT7ZaUOFdJ,S 66Dm,h62xT|mщO5cقybS8\x93=!{c؊%GV1ۯAAf6s׃L1Ba$j N'wԘc"P>0 YZTSP/data/USCA50.rda0000644000176200001440000000627312606077054013240 0ustar liggesusersBZh91AY&SYnI UUU_uUUTtEUDUUU` Uh๾{vnzsT|DIS4cM&52mS@'zh&@jiF# @hhh 404i2z6L~  MhhF A?E1L&SO@MM1?Pɦh d 4&ОITP=OP2!P52ixMM46QQ=LPPh M4i3JzL?I<Ч4ا4=OQyM  4F@2V{L521;No*TΕL#dju_2ڕ6؞l

o'sX@gDְA@ qD/þuAq%.meC%TlY# E v[3Pؽo &3wF8mLΉ ⅉ"DFR1>aw(Şl~ ln1 'es3S`WL;e}[gOI1ޘh@1 9b# C[y C*; ,5s_3GխM.[ԒPR d2 о6"*QJqfdz։Ɔ 1gz B+3VMM'D(@#bV0@vBg(4 ,H(`CѸ啪u0Ĕ(\0=A  @u{ -|յv#E[ Y|^U*'9kP HS $OBy#V&`d[n e*aIC&:ݧUuDV6 N EMS ޒ$Ml3xo7J$87mLKQu* `KʮJ&Be-k#3J2tf C!vDRd̋ A&*8XE;&F2BOIO-hZ䨤J Jp&B<Β}m xPhTh*r$o)[{Y-h@ܘej+tzN#4$LR:֮ [ 2 G>L oFڵk`n2"+D⸞Fz`k˿cP]}Mss,I%/R;հRhDX0I h!f  6Aǿog{F=vuM W<ʶ;)zxK_@!\Kzt2kLbTŖ{ D++M1G 9a>Lwvvt8kq!IbϬK  P.lG!YIsT=y56ȬQ,q#rjWj&Ee[UZ?_,XOo"f^,jQwj(\*dݒnҘ ",3Zw`"1Z>\{zs.]h+Lx*тh[kInMX\rZdYv{e D8Dҹ͂ʇzA۝]`8ų ͨ:6E3< .feDFFhvYhlrE8PnITSP/data/USCA312_GPS.rda0000644000176200001440000001562113623555010014020 0ustar liggesusers[U QADQ^nzK'wNWwNJB8*#.:}}ܝQ\Fe~羗T_}SU{9W!oܒE#8FƯE#Q#hTQ1~Fܣ, ø|WM<и0kx~-\o7LbE_,4s9;sO;yebo}7qpeo/ޏG?CWݧpn|zx[o2ҿ&ǧzÇΥoI?2GjV_pOqe'r]Wa}Lwl~w\󥳟NCuЎ~"?qos}xte2X獛%\. ɔd9дy|7~~`M|>W򶃎8mkjqXk]}+MNi~ɣ_sM񍭒h|N֫oe9|7rԇ'M=yvyF9N{H%2:cPցZY'ڿXC:Lp:ߖ۟ S Bew\"t!ƯHGo-bC_~Mʺ4S[\uU-gha<& PTHr_+s%bcg1O;y\WSr]5Dޑ~.6 G&re.ߖ~!J<^[ң\y4O75py] Uu:WkYcj1Ncx^̻´έ̵^[\'ty^0BWXUwWz՚?3B2E/0_=" ޳E( 8sI?ynzlQ$|>^}[4YěEݘƪTѯ0;H#?EL'; Ǽ s|/|cYr}S>mDg|m̗^" +, {]~?Q^( %ݢ3}j'[ٖ\X\ēyfnW35BX ϙuy/ϼ_ J}|+39gA'3WU tyv g+Oln1%uy>p*3]ٛ7CCScr@yݢd?%ϡڮyOzsd| ]c^gm T4e+o+[{>6QW[I{~Znfugag1*),c~뙻X'{Z-[!<43ϽBRiNxżQ P_=zW 7:\n1Bow{+> [$d\M׋z eC$<d\=H?Px$AO=$˵/d;*};a?k(̽E5zv0.y;i.:x]K~3Jѧ1W.&9yv:ʣW;Dcެע^ǘI ?U{P?^;^'lD/Pso[G>}[3T'cU sQzdeK(,71 o1fgi0r2}},#Yw23Tf_ԗ~,_]_Ai<|N=TXC5̻cw6ɤwPA@I2|kemDzK=<,'U5[oYU_$/=kE|6R!dD_D #S$_:+#uBB2#Q+1ϣ [L_N?Kc׷vq!~K'ލR=ȟ)8M?Ϡq~f(yՙ-Xü9+vJᾁ{veڿTOeQjZʅ]%m#ʩ'GF 00gb){ɢJ`0Й$`27/k`?` 08i!tP0p`p0 :B`R x/@%@ P @@  Ā&hZ6TKe@@1z'@R'4r`X +U)oS5iZwY:`=p6pp.88  = p3  #pp'pgn^O}C#_<<l^^^^^^ l    O K`+@_~~l~v;:oԀݒw΀;࿃tc;w;w';w;}4;Gw;qR߆ԖkIb8m凫SOj)mSiʙ]lJ\N558YߜT’=9u֝I $1+/ܮ>ԓI6f+Oڃǹj ƔevLg]eL'帝XH'jk2e`ɨ3I;=zĺ6ۓM`YnAOf]V{53ݭkI [V01:on+)gҪkw9ԜSzm /sl3Rۤ*PCݪzjLgUՒڠmen]\85y=ia [ϓ}ˏ-<1DZzaХJnCOciqIE1@sࠔ=n) u[)m]6WTHF^!5wS `b4CgPvwBf23mfkbw6l-D\=j_mV3L#r GRMgH׻jwTtRͿ܃z=0IM?%k,j{4ĺ,Z9 R_d2j0z0%2OBRF1+W{ ۼ0V֌'PWxT\OԌnOG8c$5]3oL4XS0پN 6 9[6m c" ϦiuKj2Zf`EuB ≙NO^-fu%^-\3m jig4{֌iTx dc.jօYQ lxl/XL! VfTԬӓTuȘ%g.3ZER_TC/T;5𱾔NA6uVuJ|YʬPbjM*|T:'ٗ1M޴6U*gHδZWMJUKIeXWA쮭ZfqK`N 63pN wl:OY d JjWʀJq-ʛ֖rX(o=pl@H5sI6tc7y9*fJ{)DF0hHXs YjMdvVI[]MeUjJ/ͪU vf{ckX 5V7JQe%}n$6[iUT&*+S]Rl1Z 5+Ċ͔iϬ\VGܳw*_b$R=Z%FZ%KCKU]TԕaψPM2CCKkNv cHUjHFFs1eȭ*Jj:Vm3j:C[.1l)UA!UuDy^ժۋ}E-.ZmE:Z=AlZOWZG#IbZ]!2KMJj CڥZ#tziVY=Lp&r)N1FaQiB]v" tU:$Tzڸ:KGלUj^8괾 %L'I:%KyP0U֡,nNܗW14ڭZR[bY!Xpǚa5uWc ՇhN̥*J{'_ 8fP fZ~)'k|*؀yn۱0{m e lb|Uro%z& m$qoQS1A핝 ="7їB=(nSI8,>b]}}Ƞڕ [Ɨ9QtPEފ.d yT#5äj5JU.c/`w1]_М`R [{QDQ_ΧeE\*aUZsWAM&.2c+IP7iQ2֮f: ZdbB=><]UꃦK*3-%IFXߢQIH%հ4&5|T/DϒgiH`쵿$#dž4  ]Ŗ lz5{Cg hQ[-[Xj4liRt8=j&MAs%lmLަf C5Ĭ{6sA5 D۲SF< "V0 -V`)5n/̔j"v7^]Ǔя6Ct?J}R 6n*搝cfWX37Ll2vYdӽj|>N ÷>d4'n?3IY52,ڣxF5qxb;D*'NcGRa4;MC$Ź2]•&9-8@7+`+5WA &A\Յ4G?d FR"Ps/_mKl}gԾ=6lo_?lq7ۅ  iNKƒ.:+eƒR Daa 9$tZ7 ٻj :>XV̫D±b2Z]iJ#)YbMyAA1zf{cNPLCO†ŏʹfpqQ q%L$B}{Y.dj?0FVlU-(mlL%2Fwmq[7^1j$E80v7d:K|0 j=a VC3v^-= "eT*`p_8S]iþ*)k=3>mVNڭcE6dne7wkFVlYʂp@o?M(7*v C~2e;w(EPߡ C~2Eߡ C~R4EaJ>Pߡ C~2e;w(ޡ (IpH9뿥t"e)#sQI#Փ}dRt=F(R3ݦuMi zӳ{gtvIGLTSP/man/0000755000176200001440000000000014264561154011503 5ustar liggesusersTSP/man/TSP-package.Rd0000644000176200001440000000166114204734704014032 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/AAA_TSP-package.R \docType{package} \name{TSP-package} \alias{TSP-package} \title{TSP: Traveling Salesperson Problem (TSP)} \description{ Basic infrastructure and some algorithms for the traveling salesperson problem (also traveling salesman problem; TSP). The package provides some simple algorithms and an interface to the Concorde TSP solver and its implementation of the Chained-Lin-Kernighan heuristic. The code for \href{https://www.math.uwaterloo.ca/tsp/concorde/}{Concorde} itself is not included in the package and has to be obtained separately. } \section{Key functions}{ \itemize{ \item \code{\link[=solve_TSP]{solve_TSP()}} } } \references{ Michael Hahsler and Kurt Hornik. TSP -- Infrastructure for the traveling salesperson problem. Journal of Statistical Software, 23(2):1--21, December 2007. \doi{10.18637/jss.v023.i02} } \author{ Michael Hahsler } TSP/man/insert_dummy.Rd0000644000176200001440000000663314204735111014507 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/insert_dummy.R \name{insert_dummy} \alias{insert_dummy} \alias{insert_dummy.TSP} \alias{insert_dummy.ATSP} \alias{insert_dummy.ETSP} \title{Insert dummy cities into a distance matrix} \usage{ insert_dummy(x, n = 1, const = 0, inf = Inf, label = "dummy") \method{insert_dummy}{TSP}(x, n = 1, const = 0, inf = Inf, label = "dummy") \method{insert_dummy}{ATSP}(x, n = 1, const = 0, inf = Inf, label = "dummy") \method{insert_dummy}{ETSP}(x, n = 1, const = 0, inf = Inf, label = "dummy") } \arguments{ \item{x}{an object with a TSP problem.} \item{n}{number of dummy cities.} \item{const}{distance of the dummy cities to all other cities.} \item{inf}{distance between dummy cities.} \item{label}{labels for the dummy cities. If only one label is given, it is reused for all dummy cities.} } \value{ returns an object of the same class as \code{x}. } \description{ Inserts dummy cities into a TSP problem. A dummy city has the same, constant distance (0) to all other cities and is infinitely far from other dummy cities. A dummy city can be used to transform a shortest Hamiltonian path problem (i.e., finding an optimal linear order) into a shortest Hamiltonian cycle problem which can be solved by a TSP solvers (Garfinkel 1985). } \details{ Several dummy cities can be used together with a TSP solvers to perform rearrangement clustering (Climer and Zhang 2006). The dummy cities are inserted after the other cities in \code{x}. A \code{const} of 0 is guaranteed to work if the TSP finds the optimal solution. For heuristics returning suboptimal solutions, a higher \code{const} (e.g., \code{2 * max(x)}) might provide better results. } \examples{ ## Example 1: Find a short Hamiltonian path set.seed(1000) x <- data.frame(x = runif(20), y = runif(20), row.names = LETTERS[1:20]) tsp <- TSP(dist(x)) ## add a dummy city to cut the tour into a path tsp <- insert_dummy(tsp, label = "cut") tour <- solve_TSP(tsp) tour plot(x) lines(x[cut_tour(tour, cut = "cut"),]) ## Example 2: Rearrangement clustering of the iris dataset set.seed(1000) data("iris") tsp <- TSP(dist(iris[-5])) ## insert 2 dummy cities to creates 2 clusters tsp_dummy <- insert_dummy(tsp, n = 3, label = "boundary") ## get a solution for the TSP tour <- solve_TSP(tsp_dummy) ## plot the reordered distance matrix with the dummy cities as lines separating ## the clusters image(tsp_dummy, tour) abline(h = which(labels(tour)=="boundary"), col = "red") abline(v = which(labels(tour)=="boundary"), col = "red") ## plot the original data with paths connecting the points in each cluster plot(iris[,c(2,3)], col = iris[,5]) paths <- cut_tour(tour, cut = "boundary") for(p in paths) lines(iris[p, c(2,3)]) ## Note: The clustering is not perfect! } \references{ Sharlee Climer, Weixiong Zhang (2006): Rearrangement Clustering: Pitfalls, Remedies, and Applications, \emph{Journal of Machine Learning Research} \bold{7}(Jun), pp. 919--943. R.S. Garfinkel (1985): Motivation and modelling (chapter 2). In: E. L. Lawler, J. K. Lenstra, A.H.G. Rinnooy Kan, D. B. Shmoys (eds.) The traveling salesman problem - A guided tour of combinatorial optimization, Wiley & Sons. } \seealso{ Other TSP: \code{\link{ATSP}()}, \code{\link{Concorde}}, \code{\link{ETSP}()}, \code{\link{TSPLIB}}, \code{\link{TSP}()}, \code{\link{reformulate_ATSP_as_TSP}()}, \code{\link{solve_TSP}()} } \author{ Michael Hahsler } \concept{TSP} \keyword{manip} TSP/man/reformulate_ATSP_as_TSP.Rd0000644000176200001440000001026514261153161016353 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/reformulare_ATSP_as_TSP.R \name{reformulate_ATSP_as_TSP} \alias{reformulate_ATSP_as_TSP} \alias{filter_ATSP_as_TSP_dummies} \title{Reformulate a ATSP as a symmetric TSP} \usage{ reformulate_ATSP_as_TSP(x, infeasible = Inf, cheap = -Inf) filter_ATSP_as_TSP_dummies(tour, atsp) } \arguments{ \item{x}{an \link{ATSP}.} \item{infeasible}{value for infeasible connections.} \item{cheap}{value for distance between a city and its corresponding dummy city.} \item{tour}{a \link{TOUR} created for a ATSP reformulated as a TSP.} \item{atsp}{the original \link{ATSP}.} } \value{ \code{reformulate_ATSP_as_TSP()} returns a \link{TSP} object. \code{filter_ATSP_as_TSP_dummies()} returns a \link{TOUR} object. } \description{ A ATSP can be formulated as a symmetric TSP by doubling the number of cities (Jonker and Volgenant 1983). The solution of the TSP also represents the solution of the original ATSP. } \details{ To reformulate a \link{ATSP} as a \link{TSP}, for each city a dummy city (e.g, for 'New York' a dummy city 'New York*') is added. Between each city and its corresponding dummy city a very small (or negative) distance with value \code{cheap} is used. To ensure that the solver places each cities always occurs in the solution together with its dummy city, this cost has to be much smaller than the distances in the TSP. The original distances are used between the cities and the dummy cities, where each city is responsible for the distance going to the city and the dummy city is responsible for the distance coming from the city. The distances between all cities and the distances between all dummy cities are set to \code{infeasible}, a very large value which prevents the solver from using these links. We use infinite values here and \code{\link[=solve_TSP]{solve_TSP()}} treats them appropriately. \code{filter_ATSP_as_TSP_dummies()} can be used to extract the solution for the original ATSP from the tour found for an ATSP reformulated as a TSP. Note that the symmetric TSP tour does not reveal the direction for the ATSP. The filter function computed the tour length for both directions and returns the shorter tour. \code{\link[=solve_TSP]{solve_TSP()}} has a parameter \code{as_TSP} which preforms the reformulation and filtering the dummy cities automatically. \strong{Note on performance:} Doubling the problem size is a performance issue especially has a negative impact on solution quality for heuristics. It should only be used together with Concorde when the optimal solution is required. Most heuristics can solve ATSPs directly with good solution quality. } \examples{ data("USCA50") ## set the distances from anywhere to Austin to zero which makes it an ATSP austin <- which(labels(USCA50) == "Austin, TX") atsp <- as.ATSP(USCA50) atsp[, austin] <- 0 atsp ## reformulate as a TSP (by doubling the number of cities with dummy cities marked with *) tsp <- reformulate_ATSP_as_TSP(atsp) tsp ## create tour for the TSP. You should use Concorde to find the optimal solution. # tour_tsp <- solve_TSP(tsp, method = "concorde") # The standard heuristic is bad for this problem. We use it here because # Concord may not be installed. tour_tsp <- solve_TSP(tsp) head(labels(tour_tsp), n = 10) tour_tsp # The tour length is -Inf since it includes cheap links # from a city to its dummy city. ## get the solution for the original ATSP by filtering out the dummy cities. tour_atsp <- filter_ATSP_as_TSP_dummies(tour_tsp, atsp = atsp) tour_atsp head(labels(tour_atsp), n = 10) ## This process can also be done automatically by using as_TSP = TRUE: # solve_TSP(atsp, method = "concorde", as_TSP = TRUE) ## The default heuristic can directly solve ATSPs with results close to the # optimal solution of 12715. solve_TSP(atsp, control = list(rep = 10)) } \references{ Jonker, R. and Volgenant, T. (1983): Transforming asymmetric into symmetric traveling salesman problems, \emph{Operations Research Letters,} 2, 161--163. } \seealso{ Other TSP: \code{\link{ATSP}()}, \code{\link{Concorde}}, \code{\link{ETSP}()}, \code{\link{TSPLIB}}, \code{\link{TSP}()}, \code{\link{insert_dummy}()}, \code{\link{solve_TSP}()} } \author{ Michael Hahsler } \concept{TSP} \keyword{optimize} TSP/man/ETSP.Rd0000644000176200001440000000452414402152765012550 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ETSP.R \name{ETSP} \alias{ETSP} \alias{as.ETSP} \alias{as.ETSP.matrix} \alias{as.ETSP.data.frame} \alias{as.TSP.ETSP} \alias{as.matrix.ETSP} \alias{print.ETSP} \alias{n_of_cities.ETSP} \alias{labels.ETSP} \alias{image.ETSP} \alias{plot.ETSP} \title{Class ETSP -- Euclidean traveling salesperson problem} \usage{ ETSP(x, labels = NULL) as.ETSP(x) \method{as.ETSP}{matrix}(x) \method{as.ETSP}{data.frame}(x) \method{as.TSP}{ETSP}(x) \method{as.matrix}{ETSP}(x, ...) \method{print}{ETSP}(x, ...) \method{n_of_cities}{ETSP}(x) \method{labels}{ETSP}(object, ...) \method{image}{ETSP}(x, order, col = gray.colors(64), ...) \method{plot}{ETSP}(x, y = NULL, tour = NULL, tour_lty = 2, tour_col = 2, labels = TRUE, ...) } \arguments{ \item{x, object}{an object (data.frame or matrix) to be converted into a \code{ETSP} or, for the methods, an object of class \code{ETSP}.} \item{labels}{logical; plot city labels.} \item{...}{further arguments are passed on.} \item{order}{order of cities for the image as an integer vector or an object of class \link{TOUR}.} \item{col}{color scheme for image.} \item{tour, y}{a tour to be visualized.} \item{tour_lty, tour_col}{line type and color for tour.} } \value{ \itemize{ \item \code{ETSP()} returns \code{x} as an object of class \code{ETSP}. \item \code{n_of_cities()} returns the number of cities in \code{x}. \item \code{labels()} returns a vector with the names of the cities in \code{x}. } } \description{ Constructor to create an instance of a Euclidean traveling salesperson problem (TSP) represented by city coordinates and some auxiliary methods. } \details{ Objects of class \code{ETSP} are internally represented as a \code{matrix} objects (use \code{as.matrix()} to get the \code{matrix} object). } \examples{ ## create a random ETSP n <- 20 x <- data.frame(x = runif(n), y = runif(n), row.names = LETTERS[1:n]) etsp <- ETSP(x) etsp ## use some methods n_of_cities(etsp) labels(etsp) ## plot ETSP and solution tour <- solve_TSP(etsp) tour plot(etsp, tour, tour_col = "red") } \seealso{ Other TSP: \code{\link{ATSP}()}, \code{\link{Concorde}}, \code{\link{TSPLIB}}, \code{\link{TSP}()}, \code{\link{insert_dummy}()}, \code{\link{reformulate_ATSP_as_TSP}()}, \code{\link{solve_TSP}()} } \author{ Michael Hahsler } \concept{TSP} \keyword{classes} TSP/man/Concorde.Rd0000644000176200001440000000755414204736221013532 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/tsp_concorde.R \name{Concorde} \alias{Concorde} \alias{concorde} \alias{concorde_path} \alias{concorde_help} \alias{linkern_help} \title{Using the Concorde TSP Solver} \usage{ concorde_path(path) concorde_help() linkern_help() } \arguments{ \item{path}{a character string with the path to the directory where the executables are installed.} } \value{ Nothing. } \description{ The Concorde TSP Solver package contains several solvers. Currently, interfaces to the Concorde solver (Applegate et al. 2001), one of the most advanced and fastest TSP solvers using branch-and-cut, and the Chained Lin-Kernighan (Applegate et al. 2003) implementation are provided in \pkg{TSP}. Concorde can solve \link{TSP}s and \link{ETSP}s directly. \link{ATSP}s are reformulated as larger TSP's and then solved. } \details{ \strong{Installation of Concorde} The Concorde TSP Solver is freely available for academic research. It is not included in the \pkg{TSP} R package and has to be obtained separately from the \href{http://www.math.uwaterloo.ca/tsp/concorde/downloads/downloads.htm}{Concorde download page}. Either download the precompiled executables and place them in a suitable directory (make sure they are executable), or you can get the source code and compile the program on your own. \pkg{TSP} needs to know where the executables are. There are two options: \enumerate{ \item use \code{concorde_path()} to set the path to the directory containing the executables for concorde and linkern, or \item make sure that the executables are in the search path stored in the \code{PATH} environment variable (see \code{\link[=Sys.setenv]{Sys.setenv()}}). } \strong{Using Concorde for \code{solve_TSP()}} \code{\link[=solve_TSP]{solve_TSP()}} uses \code{\link[=write_TSPLIB]{write_TSPLIB()}} to write the TSP for Concorde and tries to find the appropriate \code{precision} value (digits after the decimal point) to convert the provided distances into the needed integer value range. The \code{precision} value can also be specified in \code{control} in \code{\link[=solve_TSP]{solve_TSP()}} with method Concorde. Warning messages will alert the user if the conversion to integer values results into rounding errors that are worse then what is specified in the \code{precision} control parameter. To get a list of all available command line options which can be used via the \code{clo} option for \code{solve_TSP} use \code{concorde_help()} and \code{linkern_help()}. Several options (\option{-x}, \option{-o}, \option{-N}, \option{-Q}) are not available via \code{\link[=solve_TSP]{solve_TSP()}} since they are used by the interface. If Concorde takes too long, then you can kill the 'concorde' process via your operating system and you can continue with R. } \examples{ \dontrun{ ## see if Concorde is correctly installed concorde_path() ## set path to the Concorde executible if it is not in the search PATH ## Example: ## concorde_path("~/concorde/") concorde_help() data("USCA312") ## run concorde in verbose mode (-v) with fast cuts only (-V) solve_TSP(USCA312, method = "concorde", control = list(clo = "-v -V")) } } \references{ Concorde home page, \url{http://www.math.uwaterloo.ca/tsp/concorde/} David Applegate, Robert Bixby, Vasek Chvatal, William Cook (2001): TSP cuts which do not conform to the template paradigm, Computational Combinatorial Optimization, M. Junger and D. Naddef (editors), Springer-Verlag. David Applegate and William Cook and Andre Rohe (2003): Chained Lin-Kernighan for Large Traveling Salesman Problems, \emph{INFORMS Journal on Computing}, \bold{15}, 82--92. } \seealso{ Other TSP: \code{\link{ATSP}()}, \code{\link{ETSP}()}, \code{\link{TSPLIB}}, \code{\link{TSP}()}, \code{\link{insert_dummy}()}, \code{\link{reformulate_ATSP_as_TSP}()}, \code{\link{solve_TSP}()} } \author{ Michael Hahsler } \concept{TSP} \keyword{documentation} TSP/man/TSP.Rd0000644000176200001440000000461114401437351012434 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TSP.R \name{TSP} \alias{TSP} \alias{as.TSP} \alias{as.TSP.dist} \alias{as.TSP.matrix} \alias{as.dist.TSP} \alias{print.TSP} \alias{n_of_cities} \alias{n_of_cities.TSP} \alias{labels.TSP} \alias{image.TSP} \title{Class TSP -- Symmetric traveling salesperson problem} \usage{ TSP(x, labels = NULL, method = NULL) as.TSP(x) \method{as.TSP}{dist}(x) \method{as.TSP}{matrix}(x) \method{as.dist}{TSP}(m, ...) \method{print}{TSP}(x, ...) n_of_cities(x) \method{n_of_cities}{TSP}(x) \method{labels}{TSP}(object, ...) \method{image}{TSP}(x, order, col = gray.colors(64), ...) } \arguments{ \item{x, object}{an object (currently \code{dist} or a symmetric matrix) to be converted into a \code{TSP} or, for the methods, an object of class \code{TSP}.} \item{labels}{optional city labels. If not given, labels are taken from \code{x}.} \item{method}{optional name of the distance metric. If \code{x} is a \code{dist} object, then the method is taken from that object.} \item{m}{a TSP object to be converted to a \link{dist} object.} \item{...}{further arguments are passed on.} \item{order}{order of cities for the image as an integer vector or an object of class \link{TOUR}.} \item{col}{color scheme for image.} } \value{ \itemize{ \item \code{TSP()} returns \code{x} as an object of class \code{TSP}. \item \code{n_of_cities()} returns the number of cities in \code{x}. \item \code{labels()} returns a vector with the names of the cities in \code{x}. } } \description{ Constructor to create an instance of a symmetric traveling salesperson problem (TSP) and some auxiliary methods. } \details{ Objects of class \code{TSP} are internally represented as \code{dist} objects (use \code{\link[=as.dist]{as.dist()}} to get the \code{dist} object). Not permissible paths can be set to a distance of \code{+Inf}. \code{NA}s are not allowed and \code{-Inf} will lead to the algorithm only being able to find an admissible tour, but not the best one. } \examples{ data("iris") d <- dist(iris[-5]) ## create a TSP tsp <- TSP(d) tsp ## use some methods n_of_cities(tsp) labels(tsp) image(tsp) } \seealso{ Other TSP: \code{\link{ATSP}()}, \code{\link{Concorde}}, \code{\link{ETSP}()}, \code{\link{TSPLIB}}, \code{\link{insert_dummy}()}, \code{\link{reformulate_ATSP_as_TSP}()}, \code{\link{solve_TSP}()} } \author{ Michael Hahsler } \concept{TSP} \keyword{classes} TSP/man/figures/0000755000176200001440000000000014264561301013141 5ustar liggesusersTSP/man/figures/logo.svg0000644000176200001440000002054514264560757014646 0ustar liggesusersTSPwith RDiscrete OptimizationTSP/man/USCA.Rd0000644000176200001440000000233214412657730012526 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/USCA312.R \docType{data} \name{USCA} \alias{USCA} \alias{USCA312} \alias{USCA312_GPS} \alias{USCA50} \title{USCA312/USCA50 -- 312/50 cities in the US and Canada} \format{ \code{USCA312} and \code{USCA50} are objects of class \code{TSP}. \code{USCA312_GPS} is a data.frame with city name, long and lat. } \source{ John Burkardt, CITIES -- City Distance Datasets, Florida State University, Department of Scientific Computing } \description{ The \code{USCA312} dataset contains the distances between 312 cities in the US and Canada as an object of class \code{TSP}. \code{USCA50} is a subset of \code{USCA312} containing only the first 50 cities. } \details{ The \code{USCA312_GPS} dataset contains the location (long/lat) of the 312 cities. } \examples{ data("USCA312") ## calculate a tour tour <- solve_TSP(USCA312) tour # Visualize the tour if package maps is installed if(require("maps")) { library(maps) data("USCA312_GPS") head(USCA312_GPS) plot((USCA312_GPS[, c("long", "lat")]), cex = .3) map("world", col = "gray", add = TRUE) polygon(USCA312_GPS[, c("long", "lat")][tour,], border = "red") } } \author{ Michael Hahsler } \keyword{datasets} TSP/man/solve_TSP.Rd0000644000176200001440000002416214261140405013642 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/solve_TSP.R \name{solve_TSP} \alias{solve_TSP} \alias{solve_TSP.TSP} \alias{solve_TSP.ATSP} \alias{solve_TSP.ETSP} \title{TSP solver interface} \usage{ solve_TSP(x, method = NULL, control = NULL, ...) \method{solve_TSP}{TSP}(x, method = NULL, control = NULL, ...) \method{solve_TSP}{ATSP}(x, method = NULL, control = NULL, as_TSP = FALSE, ...) \method{solve_TSP}{ETSP}(x, method = NULL, control = NULL, ...) } \arguments{ \item{x}{a TSP problem.} \item{method}{method to solve the TSP (default: "arbitrary insertion" algorithm with two_opt refinement.} \item{control}{a list of arguments passed on to the TSP solver selected by \code{method}.} \item{...}{additional arguments are added to \code{control}.} \item{as_TSP}{should the ATSP reformulated as a TSP for the solver?} } \value{ An object of class \link{TOUR}. } \description{ Common interface to all TSP solvers in this package. } \details{ \strong{TSP Methods} Currently the following methods are available: \itemize{ \item "identity", "random" return a tour representing the order in the data (identity order) or a random order. [TSP, ATSP] \item "nearest_insertion", "farthest_insertion", "cheapest_insertion", "arbitrary_insertion" Nearest, farthest, cheapest and arbitrary insertion algorithms for a symmetric and asymmetric TSP (Rosenkrantz et al. 1977). [TSP, ATSP] The distances between cities are stored in a distance matrix \eqn{D} with elements \eqn{d(i,j)}. All insertion algorithms start with a tour consisting of an arbitrary city and choose in each step a city \eqn{k} not yet on the tour. This city is inserted into the existing tour between two consecutive cities \eqn{i} and \eqn{j}, such that \deqn{d(i,k) + d(k,j) - d(i,j)} is minimized. The algorithms stops when all cities are on the tour. The nearest insertion algorithm chooses city \eqn{k} in each step as the city which is \emph{nearest} to a city on the tour. For farthest insertion, the city \eqn{k} is chosen in each step as the city which is \emph{farthest} to any city on the tour. Cheapest insertion chooses the city \eqn{k} such that the cost of inserting the new city (i.e., the increase in the tour's length) is minimal. Arbitrary insertion chooses the city \eqn{k} randomly from all cities not yet on the tour. Nearest and cheapest insertion tries to build the tour using cities which fit well into the partial tour constructed so far. The idea behind behind farthest insertion is to link cities far away into the tour fist to establish an outline of the whole tour early. Additional control options: \itemize{ \item "start" index of the first city (default: a random city). } \item "nn", "repetitive_nn" Nearest neighbor and repetitive nearest neighbor algorithms for symmetric and asymmetric TSPs (Rosenkrantz et al. 1977). [TSP, ATSP] The algorithm starts with a tour containing a random city. Then the algorithm always adds to the last city on the tour the nearest not yet visited city. The algorithm stops when all cities are on the tour. Repetitive nearest neighbor constructs a nearest neighbor tour for each city as the starting point and returns the shortest tour found. Additional control options: \itemize{ \item "start" index of the first city (default: a random city). } \item "two_opt" Two edge exchange improvement procedure (Croes 1958). [TSP, ATSP] This is a tour refinement procedure which systematically exchanges two edges in the graph represented by the distance matrix till no improvements are possible. Exchanging two edges is equal to reversing part of the tour. The resulting tour is called \emph{2-optimal.} This method can be applied to tours created by other methods or used as its own method. In this case improvement starts with a random tour. Additional control options: \itemize{ \item "tour" an existing tour which should be improved. If no tour is given, a random tour is used. \item "two_opt_repetitions" number of times to try two_opt with a different initial random tour (default: 1). } \item "concorde" Concorde algorithm (Applegate et al. 2001). [TSP, ETSP] Concorde is an advanced exact TSP solver for \emph{symmetric} TSPs based on branch-and-cut. ATSPs can be solved using \code{\link[=reformulate_ATSP_as_TSP]{reformulate_ATSP_as_TSP()}} done automatically with \code{as_TSP = TRUE}. The program is not included in this package and has to be obtained and installed separately. Additional control options: \itemize{ \item "exe" a character string containing the path to the executable (see \link{Concorde}). \item "clo" a character string containing command line options for Concorde, e.g., \code{control = list(clo = "-B -v")}. See \code{\link[=concorde_help]{concorde_help()}} on how to obtain a complete list of available command line options. \item "precision" an integer which controls the number of decimal places used for the internal representation of distances in Concorde. The values given in \code{x} are multiplied by \eqn{10^{precision}} before being passed on to Concorde. Note that therefore the results produced by Concorde (especially lower and upper bounds) need to be divided by \eqn{10^{precision}} (i.e., the decimal point has to be shifted \code{precision} placed to the left). The interface to Concorde uses \code{\link[=write_TSPLIB]{write_TSPLIB()}}. } \item "linkern" Concorde's Chained Lin-Kernighan heuristic (Applegate et al. 2003). [TSP, ETSP] The Lin-Kernighan (Lin and Kernighan 1973) heuristic uses variable \eqn{k} edge exchanges to improve an initial tour. The program is not included in this package and has to be obtained and installed separately (see \link{Concorde}). Additional control options: see Concorde above. } \strong{Treatment of \code{NA}s and infinite values in \code{x}} \link{TSP} and \link{ATSP} need to contain valid distances. \code{NA}s are not allowed. \code{Inf} is allowed and can be used to model the missing edges in incomplete graphs (i.e., the distance between the two objects is infinite) or unfeasable connections. Internally, \code{Inf} is replaced by a large value given by \eqn{max(x) + 2 range(x)}. Note that the solution might still place the two objects next to each other (e.g., if \code{x} contains several unconnected subgraphs) which results in a path length of \code{Inf}. \code{-Inf} is replaced by \eqn{min(x) - 2 range(x)} and can be used to encourage the solver to place two objects next to each other. \strong{Parallel execution support} All heuristics can be used with the control arguments \code{repetitions} (uses the best from that many repetitions with random starts) and \code{two_opt} (a logical indicating if two_opt refinement should be performed). If several repetitions are done (this includes method \code{"repetitive_nn"}) then \pkg{foreach} is used so they can be performed in parallel on multiple cores/machines. To enable parallel execution an appropriate parallel backend needs to be registered (e.g., load \pkg{doParallel} and register it with \code{\link[doParallel:registerDoParallel]{doParallel::registerDoParallel()}}). \strong{Solving ATSP and ETSP} Some solvers (including Concorde) cannot directly solve \link{ATSP} directly. \code{ATSP} can be reformulated as larger \code{TSP} and solved this way. For convenience, \code{solve_TSP()} has an extra argument \code{as_TSP} which can be set to \code{TRUE} to automatically solve the \code{ATSP} reformulated as a \code{TSP} (see \code{\link[=reformulate_ATSP_as_TSP]{reformulate_ATSP_as_TSP()}}). Only methods "concorde" and "linkern" can solve \link{ETSP}s directly. For all other methods, ETSPs are currently converted into TSPs by creating a distance matrix and then solved. } \examples{ ## solve a simple Euclidean TSP (using the default method) etsp <- ETSP(data.frame(x = runif(20), y = runif(20))) tour <- solve_TSP(etsp) tour tour_length(tour) plot(etsp, tour) ## compare methods data("USCA50") USCA50 methods <- c("identity", "random", "nearest_insertion", "cheapest_insertion", "farthest_insertion", "arbitrary_insertion", "nn", "repetitive_nn", "two_opt") ## calculate tours tours <- lapply(methods, FUN = function(m) solve_TSP(USCA50, method = m)) names(tours) <- methods ## use the external solver which has to be installed separately \dontrun{ tours$concorde <- solve_TSP(USCA50, method = "concorde") tours$linkern <- solve_TSP(USCA50, method = "linkern") } ## register a parallel backend to perform repetitions in parallel \dontrun{ library(doParallel) registerDoParallel() } ## add some tours using repetition and two_opt refinements tours$'nn+two_opt' <- solve_TSP(USCA50, method = "nn", two_opt = TRUE) tours$'nn+rep_10' <- solve_TSP(USCA50, method = "nn", rep = 10) tours$'nn+two_opt+rep_10' <- solve_TSP(USCA50, method = "nn", two_opt = TRUE, rep = 10) tours$'arbitrary_insertion+two_opt' <- solve_TSP(USCA50) ## show first tour tours[[1]] ## compare tour lengths opt <- 14497 # obtained by Concorde tour_lengths <- c(sort(sapply(tours, tour_length), decreasing = TRUE), optimal = opt) dotchart(tour_lengths / opt * 100 - 100, xlab = "percent excess over optimum") } \references{ David Applegate, Robert Bixby, Vasek Chvatal, William Cook (2001): TSP cuts which do not conform to the template paradigm, Computational Combinatorial Optimization, M. Junger and D. Naddef (editors), Springer. D. Applegate, W. Cook and A. Rohe (2003): Chained Lin-Kernighan for Large Traveling Salesman Problems. \emph{INFORMS Journal on Computing, 15(1):82--92.} G.A. Croes (1958): A method for solving traveling-salesman problems. \emph{Operations Research, 6(6):791--812.} S. Lin and B. Kernighan (1973): An effective heuristic algorithm for the traveling-salesman problem. \emph{Operations Research, 21(2): 498--516.} D.J. Rosenkrantz, R. E. Stearns, and Philip M. Lewis II (1977): An analysis of several heuristics for the traveling salesman problem. \emph{SIAM Journal on Computing, 6(3):563--581.} } \seealso{ Other TSP: \code{\link{ATSP}()}, \code{\link{Concorde}}, \code{\link{ETSP}()}, \code{\link{TSPLIB}}, \code{\link{TSP}()}, \code{\link{insert_dummy}()}, \code{\link{reformulate_ATSP_as_TSP}()} Other TOUR: \code{\link{TOUR}()}, \code{\link{cut_tour}()}, \code{\link{tour_length}()} } \author{ Michael Hahsler } \concept{TOUR} \concept{TSP} \keyword{optimize} TSP/man/tour_length.Rd0000644000176200001440000000310014260645005014310 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/tour_length.R \name{tour_length} \alias{tour_length} \alias{tour_length.TSP} \alias{tour_length.ATSP} \alias{tour_length.ETSP} \alias{tour_length.TOUR} \alias{tour_length.integer} \title{Calculate the length of a tour} \usage{ tour_length(x, ...) \method{tour_length}{TSP}(x, order, ...) \method{tour_length}{ATSP}(x, order, ...) \method{tour_length}{ETSP}(x, order, ...) \method{tour_length}{TOUR}(x, tsp = NULL, ...) \method{tour_length}{integer}(x, tsp = NULL, ...) } \arguments{ \item{x}{a TSP problem or a \link{TOUR}.} \item{...}{further arguments are currently unused.} \item{order}{an object of class \code{TOUR}} \item{tsp}{as TSP object.} } \description{ Calculate the length of a \link{TOUR} for a \link{TSP}. } \details{ If no \code{tsp} is specified, then the tour length stored in \code{x} as attribute \code{"tour_length"} is returned. If \code{tsp} is given then the tour length is recalculated using the specified TSP problem. If a distance in the tour is infinite, the result is also infinite. If the tour contains positive and negative infinite distances then the method returns \code{NA}. } \examples{ data("USCA50") ## original order tour_length(solve_TSP(USCA50, method="identity")) ## length of a manually created (random) tour tour <- TOUR(sample(seq(n_of_cities(USCA50)))) tour tour_length(tour) tour_length(tour, USCA50) } \seealso{ Other TOUR: \code{\link{TOUR}()}, \code{\link{cut_tour}()}, \code{\link{solve_TSP}()} } \author{ Michael Hahsler } \concept{TOUR} \keyword{optimize} TSP/man/TOUR.Rd0000644000176200001440000000406614260640317012564 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TOUR.R \name{TOUR} \alias{TOUR} \alias{as.TOUR} \alias{as.TOUR.numeric} \alias{as.TOUR.integer} \alias{print.TOUR} \title{Class TOUR -- Solution to a traveling salesperson problem} \usage{ TOUR(x, method = NA, tsp = NULL) as.TOUR(object) \method{as.TOUR}{numeric}(object) \method{as.TOUR}{integer}(object) \method{print}{TOUR}(x, ...) } \arguments{ \item{x}{an integer permutation vector or, for the methods an object of class \link{TOUR}.} \item{method}{character string; method used to create the tour.} \item{tsp}{\code{TSP} object the tour applies to. If available then the tour will include the tour length. Also the labels of the cities will be available in the tour (otherwise the labels of \code{x} are used).} \item{object}{data (an integer vector) which can be coerced to \code{TOUR}.} \item{...}{further arguments are passed on.} } \description{ Class to store the solution of a TSP. Objects of this class are returned by TSP solvers in this package. Essentially, an object of class \code{TOUR} is a permutation vector containing the order of cities to visit. } \details{ Since an object of class \code{TOUR} is an integer vector, it can be subsetted as an ordinary vector or coerced to an integer vector using \code{as.integer()}. It also contains the names of the objects as labels. Additionally, \code{TOUR} has the following attributes: \code{"method"}, \code{"tour_length"}. For most functions, e.g., \code{\link[=tour_length]{tour_length()}} or \code{\link[=image.TSP]{image.TSP()}}, the \code{TSP/ATSP} object used to find the tour is still needed, since the tour does not contain the distance information. } \examples{ TOUR(1:10) ## calculate a tour data("USCA50") tour <- solve_TSP(USCA50) tour ## get tour length directly from tour tour_length(tour) ## get permutation vector as.integer(tour) ## show labels labels(tour) } \seealso{ Other TOUR: \code{\link{cut_tour}()}, \code{\link{solve_TSP}()}, \code{\link{tour_length}()} } \author{ Michael Hahsler } \concept{TOUR} \keyword{classes} TSP/man/ATSP.Rd0000644000176200001440000000433314204735111012532 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ATSP.R \name{ATSP} \alias{ATSP} \alias{as.ATSP} \alias{as.ATSP.matrix} \alias{as.ATSP.dist} \alias{print.ATSP} \alias{n_of_cities.ATSP} \alias{labels.ATSP} \alias{image.ATSP} \alias{as.matrix.ATSP} \title{Class ATSP -- Asymmetric traveling salesperson problem} \usage{ ATSP(x, labels = NULL, method = NULL) as.ATSP(x) \method{as.ATSP}{matrix}(x) \method{as.ATSP}{dist}(x) \method{print}{ATSP}(x, ...) \method{n_of_cities}{ATSP}(x) \method{labels}{ATSP}(object, ...) \method{image}{ATSP}(x, order, col = gray.colors(64), ...) \method{as.matrix}{ATSP}(x, ...) } \arguments{ \item{x, object}{an object (a square matrix) to be converted into an \code{ATSP} or, for the methods, an object of class \code{ATSP}.} \item{labels}{optional city labels. If not given, labels are taken from \code{x}.} \item{method}{optional name of the distance metric.} \item{...}{further arguments are passed on.} \item{order}{order of cities as an integer vector or an object of class \code{TOUR}.} \item{col}{color scheme for image.} } \value{ \itemize{ \item \code{ATSP()} returns \code{x} as an object of class \code{ATSP}. \item \code{n_of_cities()} returns the number of cities in \code{x}. \item \code{labels()} returns a vector with the names of the cities in \code{x}. } } \description{ Constructor to create an instance of the asymmetric traveling salesperson problem (ATSP) and some auxiliary methods. } \details{ Objects of class \code{ATSP} are internally represented by a matrix (use \code{as.matrix()} to get just the matrix). ATSPs can be transformed into (larger) symmetric TSPs using \code{\link[=reformulate_ATSP_as_TSP]{reformulate_ATSP_as_TSP()}}. } \examples{ data <- matrix(runif(10^2), ncol = 10, dimnames = list(1:10, 1:10)) atsp <- ATSP(data) atsp ## use some methods n_of_cities(atsp) labels(atsp) ## calculate a tour tour <- solve_TSP(atsp, method = "nn") tour tour_length(tour) image(atsp, tour) } \seealso{ Other TSP: \code{\link{Concorde}}, \code{\link{ETSP}()}, \code{\link{TSPLIB}}, \code{\link{TSP}()}, \code{\link{insert_dummy}()}, \code{\link{reformulate_ATSP_as_TSP}()}, \code{\link{solve_TSP}()} } \author{ Michael Hahsler } \concept{TSP} \keyword{classes} TSP/man/TSPLIB.Rd0000644000176200001440000000632014204735111012756 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TSPLIB.R \name{TSPLIB} \alias{TSPLIB} \alias{read_TSPLIB} \alias{write_TSPLIB} \alias{write_TSPLIB.TSP} \alias{write_TSPLIB.ATSP} \alias{write_TSPLIB.ETSP} \title{Read and write TSPLIB files} \usage{ read_TSPLIB(file, precision = 0) write_TSPLIB(x, file, precision = 6, inf = NULL, neg_inf = NULL) \method{write_TSPLIB}{TSP}(x, file, precision = 6, inf = NULL, neg_inf = NULL) \method{write_TSPLIB}{ATSP}(x, file, precision = 6, inf = NULL, neg_inf = NULL) \method{write_TSPLIB}{ETSP}(x, file, precision = 6, inf = NULL, neg_inf = NULL) } \arguments{ \item{file}{file name or a \link{connection}.} \item{precision}{controls the number of decimal places used to represent distances (see details). If \code{x} already is \code{integer}, this argument is ignored and \code{x} is used as is.} \item{x}{an object with a TSP problem. \code{NA}s are not allowed.} \item{inf}{replacement value for \code{Inf} (TSPLIB format cannot handle \code{Inf}). If \code{inf} is \code{NULL}, a large value of \eqn{max(x) + 2 range(x)} (ignoring infinite entries) is used.} \item{neg_inf}{replacement value for \code{-Inf}. If no value is specified, a small value of \eqn{min(x) - 2 range(x)} (ignoring infinite entries) is used.} } \value{ returns an object of class \code{TSP} or \code{ATSP}. } \description{ Reads and writes TSPLIB format files. TSPLIB files can be used by most TSP solvers. Sample instances for the TSP in TSPLIB format are available on the TSPLIB homepage (see references). } \details{ In the TSPLIB format distances are represented by integer values. Therefore, if \code{x} contains \code{double} values (which is normal in R) the values given in \code{x} are multiplied by \eqn{10^{precision}} before coercion to \code{integer}. Note that therefore all results produced by programs using the TSPLIB file as input need to be divided by \eqn{10^{precision}} (i.e., the decimal point has to be shifted \code{precision} placed to the left). Currently only the following \code{EDGE_WEIGHT_TYPE}s are implemented: \code{EXPLICIT}, \code{EUC_2D} and \code{EUC_3D}. } \examples{ ## Drilling problem from TSP drill <- read_TSPLIB(system.file("examples/d493.tsp", package = "TSP")) drill tour <- solve_TSP(drill, method = "nn", two_opt = TRUE) tour plot(drill, tour, cex=.6, col = "red", pch= 3, main = "TSPLIB: d493") ## Write and read data in TSPLIB format x <- data.frame(x=runif(5), y=runif(5)) ## create TSP, ATSP and ETSP (2D) tsp <- TSP(dist(x)) atsp <- ATSP(dist(x)) etsp <- ETSP(x[,1:2]) write_TSPLIB(tsp, file="example.tsp") #file.show("example.tsp") r <- read_TSPLIB("example.tsp") r write_TSPLIB(atsp, file="example.tsp") #file.show("example.tsp") r <- read_TSPLIB("example.tsp") r write_TSPLIB(etsp, file="example.tsp") #file.show("example.tsp") r <- read_TSPLIB("example.tsp") r ## clean up unlink("example.tsp") } \references{ TSPLIB home page, \url{http://comopt.ifi.uni-heidelberg.de/software/TSPLIB95/} } \seealso{ Other TSP: \code{\link{ATSP}()}, \code{\link{Concorde}}, \code{\link{ETSP}()}, \code{\link{TSP}()}, \code{\link{insert_dummy}()}, \code{\link{reformulate_ATSP_as_TSP}()}, \code{\link{solve_TSP}()} } \author{ Michael Hahsler } \concept{TSP} \keyword{file} TSP/man/cut_tour.Rd0000644000176200001440000000256014260640317013634 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cut_tour.R \name{cut_tour} \alias{cut_tour} \alias{cut_tour.TOUR} \title{Cut a tour to form a path} \usage{ cut_tour(x, cut, exclude_cut = TRUE) \method{cut_tour}{TOUR}(x, cut, exclude_cut = TRUE) } \arguments{ \item{x}{an object of class \link{TOUR}.} \item{cut}{the index or label of the city/cities to cut the tour.} \item{exclude_cut}{exclude the city where we cut? If \code{FALSE}, the city at the cut is included in the path as the first city.} } \value{ Returns a named vector with city ids forming the path. If multiple cuts are used then a list with paths is returned. } \description{ Cuts a tour at a specified city to form a path. } \examples{ data("USCA50") ## find a path starting at Austin, TX tour <- solve_TSP(USCA50) path <- cut_tour(tour, cut = "Austin, TX", exclude_cut = FALSE) path ## cut the tours at two cities tour <- solve_TSP(USCA50) path <- cut_tour(tour, cut = c("Austin, TX", "Cambridge, MA"), exclude_cut = FALSE) path ## cut a tour at the largest gap using a dummy city tsp <- insert_dummy(USCA50, label = "cut") tour <- solve_TSP(tsp) ## cut tour into path at the dummy city path <- cut_tour(tour, "cut") path } \seealso{ Other TOUR: \code{\link{TOUR}()}, \code{\link{solve_TSP}()}, \code{\link{tour_length}()} } \author{ Michael Hahsler } \concept{TOUR} \keyword{optimize} TSP/DESCRIPTION0000644000176200001440000000275114413041204012424 0ustar liggesusersPackage: TSP Type: Package Title: Traveling Salesperson Problem (TSP) Version: 1.2-4 Date: 2023-04-03 Authors@R: c(person("Michael", "Hahsler", role = c("aut", "cre", "cph"), email = "mhahsler@lyle.smu.edu", comment = c(ORCID = "0000-0003-2716-1405")), person("Kurt", "Hornik", role = c("aut", "cph"), comment = c(ORCID = "0000-0003-4198-9911")) ) Description: Basic infrastructure and some algorithms for the traveling salesperson problem (also traveling salesman problem; TSP). The package provides some simple algorithms and an interface to the Concorde TSP solver and its implementation of the Chained-Lin-Kernighan heuristic. The code for Concorde itself is not included in the package and has to be obtained separately. Hahsler and Hornik (2007) . Classification/ACM: G.1.6, G.2.1, G.4 URL: https://github.com/mhahsler/TSP BugReports: https://github.com/mhahsler/TSP/issues Depends: R (>= 3.5.0) Imports: graphics, foreach, utils, stats, grDevices Suggests: maps, doParallel, testthat Encoding: UTF-8 RoxygenNote: 7.2.3 License: GPL-3 Copyright: All code is Copyright (C) Michael Hahsler and Kurt Hornik. NeedsCompilation: yes Packaged: 2023-04-04 01:12:42 UTC; hahsler Author: Michael Hahsler [aut, cre, cph] (), Kurt Hornik [aut, cph] () Maintainer: Michael Hahsler Repository: CRAN Date/Publication: 2023-04-04 15:30:12 UTC TSP/build/0000755000176200001440000000000014412674611012025 5ustar liggesusersTSP/build/vignette.rds0000644000176200001440000000031114412674611014357 0ustar liggesusersb```b`abf"fa @ Cф=JSJK2Jʰ,HICfX,&dEy楀aM wjey~L6̜T2K7(1 棸(\^P07@btr$$ }TSP/build/partial.rdb0000644000176200001440000000007414412674607014160 0ustar liggesusersb```b`abf" S X# 'fKM-2 Q7TSP/tests/0000755000176200001440000000000014204053416012061 5ustar liggesusersTSP/tests/testthat/0000755000176200001440000000000014413041204013713 5ustar liggesusersTSP/tests/testthat/test-ETSP.R0000644000176200001440000000070514204053416015576 0ustar liggesuserslibrary(TSP) library(testthat) context("ETSP") x <- data.frame(x = runif(20), y = runif(20), row.names = LETTERS[1:20]) ## create a TSP etsp <- ETSP(x) etsp ## use some methods expect_equal(n_of_cities(etsp), 20L) expect_equal(labels(etsp), LETTERS[1:20]) ## solve tour <- solve_TSP(etsp) tour ## compare tour_length expect_equal(tour_length(etsp), tour_length(as.TSP(etsp))) expect_equal(tour_length(tour, etsp), tour_length(tour, as.TSP(etsp))) TSP/tests/testthat/test-concorde.R0000644000176200001440000000563614363771147016645 0ustar liggesuserslibrary(TSP) library(testthat) context("solve_TSP (Concorde and Linkern)") m <- rbind( c(0, 1, 0, 1), c(1, 0, 1, Inf), c(0, 1, 0, 1), c(1, Inf, 1, 0) ) d <- as.dist(m) tsp <- TSP(d) tsp skip_if_not( Sys.which("concorde") != "" && Sys.which("linkern") != "", message = "skipped test for concorde/linkern. Not installed.") v <- FALSE o <- solve_TSP(tsp, method="concorde", verbose = v) expect_equivalent(tour_length(tsp, o), 4) # large numbers should be scaled right. expect_warning(o_large <- solve_TSP(tsp*2^15, method="concorde", verbose = v), regex = "Converting the provided distances to integers") expect_equivalent(o, o_large) expect_warning(o_large <- solve_TSP(tsp*10^10, method="concorde", verbose = v), regex = "Converting the provided distances to integers") expect_equivalent(o, o_large) # expect warning for rounding expect_warning(o_large <- solve_TSP(tsp*2^15+0.1, method="concorde", verbose = v), regex = "Converting the provided distances to integers") expect_equivalent(o, o_large) # expect a warning for rounding expect_warning(o_round <- solve_TSP(tsp/0.3, method="concorde", verbose = v), regex = "Converting the provided distances to integers") expect_equivalent(o, o_round) o <- solve_TSP(tsp, method="linkern", verbose = v) expect_equivalent(tour_length(tsp, o), 4) # test ATSP #data <- matrix(runif(5^2), ncol = 5, dimnames = list(1:5, 1:5)) data <- structure(c(0.13930352916941, 0.897691324818879, 0.509101516567171, 0.430898967897519, 0.141799068776891, 0.0334562903735787, 0.902805947931483, 0.203576791565865, 0.435874363640323, 0.0641707226168364, 0.101683554705232, 0.631239329231903, 0.555331876967102, 0.0829615572001785, 0.272443652851507, 0.215095571940765, 0.532841097796336, 0.795302660670131, 0.43256876245141, 0.582661165855825, 0.250269076088443, 0.164849652675912, 0.638499777996913, 0.857200765516609, 0.0134391817264259), .Dim = c(5L, 5L), .Dimnames = list( c("1", "2", "3", "4", "5"), c("1", "2", "3", "4", "5"))) atsp <- ATSP(data) ## Concorde (gives conversation warning for reformulation of ATSP to TSP) expect_warning(o1 <- solve_TSP(atsp, method = "concorde", verbose = v), regex = "Solver cannot solve the ATSP directly") o2 <- solve_TSP(atsp, method = "concorde", as_TSP = TRUE, verbose = v) expect_equal(length(o1), 5L) expect_equal(length(o2), 5L) # Concorde should find the optimal solution of 0.8082826 expect_equal(round(tour_length(o1), 7), 0.8082826) expect_equal(round(tour_length(o2), 7), 0.8082826) ## Linkern ## warning for reformulate as TSP automatically expect_warning(o1 <- solve_TSP(atsp, method = "linkern", verbose = v), regex = "Solver cannot solve the ATSP directly") o2 <- solve_TSP(atsp, method = "linkern", as_TSP = TRUE, verbose = v) expect_equal(length(o1), 5L) expect_equal(length(o2), 5L) # Linkern should find the optimal solution of 0.8082826 expect_equal(round(tour_length(o1), 7), 0.8082826) expect_equal(round(tour_length(o2), 7), 0.8082826) TSP/tests/testthat/test-solve_TSP.R0000644000176200001440000000451714204053416016706 0ustar liggesuserslibrary(TSP) library(testthat) context("solve_TSP") m <- rbind( c(0, 1, 0, 1), c(1, 0, 1, Inf), c(0, 1, 0, 1), c(1, Inf, 1, 0) ) d <- as.dist(m) tsp <- TSP(d) tsp ## from matrix should give the same result expect_equal(as.numeric(tsp), as.numeric(TSP(as.matrix(d)))) ## test error on NA tsp_na <- tsp tsp_na[4] <- NA expect_error(o <- solve_TSP(tsp_na)) ## test Inf methods <- c("nearest_insertion", "cheapest_insertion", "farthest_insertion", "arbitrary_insertion", "nn", "repetitive_nn", "two_opt", "random", "identity") tours <- lapply(methods, FUN = function(m) solve_TSP(tsp, method = m)) names(tours) <- methods #tours tl <- sapply(tours, attr, "tour_length") expect_true(all(tl == 4 | tl == Inf)) ## test rep res <- solve_TSP(tsp, rep=10) tl <- attr("res", "tour_length") expect_true(all(tl == 4 | tl == Inf)) ## no two_opt res <- solve_TSP(tsp, two_opt=FALSE) tl <- attr("res", "tour_length") expect_true(all(tl == 4 | tl == Inf)) ## test special case: two cities d <- dist(rbind(c(0,0), c(1,1))) tsp2 <- TSP(d) tours2 <- lapply(methods, FUN = function(m) solve_TSP(tsp2, method = m)) expect_true(all(sapply(tours2, attr, "tour_length") == as.numeric(d)*2)) ## test special case: one city tsp1 <- TSP(dist(1)) tours1 <- lapply(methods, FUN = function(m) solve_TSP(tsp1, method = m)) expect_true(all(sapply(tours1, attr, "tour_length") == 0)) ## test ATSP (just for errors) #data <- matrix(runif(5^2), ncol = 5, dimnames = list(1:5, 1:5)) data <- structure(c(0.13930352916941, 0.897691324818879, 0.509101516567171, 0.430898967897519, 0.141799068776891, 0.0334562903735787, 0.902805947931483, 0.203576791565865, 0.435874363640323, 0.0641707226168364, 0.101683554705232, 0.631239329231903, 0.555331876967102, 0.0829615572001785, 0.272443652851507, 0.215095571940765, 0.532841097796336, 0.795302660670131, 0.43256876245141, 0.582661165855825, 0.250269076088443, 0.164849652675912, 0.638499777996913, 0.857200765516609, 0.0134391817264259), .Dim = c(5L, 5L), .Dimnames = list( c("1", "2", "3", "4", "5"), c("1", "2", "3", "4", "5"))) # best solution is 0.8082826 atsp <- ATSP(data) methods <- c("nearest_insertion", "cheapest_insertion", "farthest_insertion", "arbitrary_insertion", "nn", "repetitive_nn", "two_opt", "random", "identity") tours <- lapply(methods, FUN = function(m) solve_TSP(atsp, method = m)) names(tours) <- methods TSP/tests/testthat/test-insert_cut_etc.R0000644000176200001440000000413314363771337020053 0ustar liggesuserslibrary("testthat") library("TSP") data("USCA50") context("insert_dummy") tsp <- insert_dummy(USCA50, label = "cut") #labels(tsp) expect_equal(n_of_cities(tsp), n_of_cities(USCA50) + 1L) expect_equal(labels(tsp), c(labels(USCA50), "cut")) tsp5 <- insert_dummy(USCA50, n = 5, label = "cut") #labels(tsp5) expect_equal(n_of_cities(tsp5), n_of_cities(USCA50) + 5L) expect_equal(labels(tsp5), c(labels(USCA50), rep("cut", 5))) context("cut_tour") tour <- solve_TSP(tsp5) path <- cut_tour(tour, "cut") expect_equal(sum(sapply(path, length)), n_of_cities(USCA50)) #labels(tour) #path ## border cases tour <- TOUR(1:10) expect_equal(cut_tour(tour, "1"), 2:10) expect_equal(cut_tour(tour, 1), 2:10) expect_equal(cut_tour(tour, "10"), 1:9) expect_equal(cut_tour(tour, 10), 1:9) path <- cut_tour(tour, 1:3) expect_equal(length(path), 3L) expect_equal(sum(sapply(path, length)), length(tour) - 3L) #path path <- cut_tour(tour, 1:3, exclude_cut = FALSE) expect_equal(length(path), 3L) expect_equal(sum(sapply(path, length)), length(tour)) #path path <- cut_tour(tour, 8:10) expect_equal(length(path), 3L) expect_equal(sum(sapply(path, length)), length(tour) - 3L) #path path <- cut_tour(tour, 8:10, exclude_cut = FALSE) expect_equal(length(path), 3L) expect_equal(sum(sapply(path, length)), length(tour)) #path tour <- TOUR(1) path <- cut_tour(tour, 1) expect_equal(length(path), 0L) #path path <- cut_tour(tour, 1, exclude_cut = FALSE) expect_equal(length(path), 1L) #path context("reformulate") ## reformulate atsp <- as.ATSP(USCA50) expect_equal(tour_length(USCA50), tour_length(atsp)) tsp <- reformulate_ATSP_as_TSP(atsp, cheap = 0) expect_equal(n_of_cities(atsp)*2, n_of_cities(tsp)) ## only Concorde guarantees to find the optimal solution skip_if_not( Sys.which("concorde") != "" && Sys.which("linkern") != "", message = "skipped test for concorde/linkern. Not installed.") v <- FALSE tour_tsp <- solve_TSP(tsp, method = "concorde", verbose = v) tour_atsp <- filter_ATSP_as_TSP_dummies(tour_tsp, atsp) expect_equal(length(tour_atsp), n_of_cities(USCA50)) expect_equal(tour_length(tour_tsp), tour_length(tour_atsp)) TSP/tests/testthat/test-TSPLIB.R0000644000176200001440000000173414363765655016050 0ustar liggesuserslibrary(TSP) library(testthat) context("TSPLIB") set.seed(1234) x <- data.frame(x=runif(5), y=runif(5)) ## create TSP, ATSP and ETSP (2D) d <- round(dist(x), 3) ## TSP tsp <- TSP(d) tsp write_TSPLIB(tsp, file="example.tsp", precision = 6) #file.show("example.tsp") r <- read_TSPLIB("example.tsp", precision = 6) expect_equivalent(tsp, r) ## ATSP atsp <- ATSP(d) atsp write_TSPLIB(atsp, file="example.tsp", precision = 6) #file.show("example.tsp") r <- read_TSPLIB("example.tsp", precision = 6) expect_equivalent(atsp, r) ## ETSP (2D) etsp <- ETSP(round(x[,1:2], 3)) etsp write_TSPLIB(etsp, file="example.tsp", precision = 6) #file.show("example.tsp") r <- read_TSPLIB("example.tsp", precision = 6) expect_equivalent(etsp, r) ## Infinity d[2] <- Inf tsp <- TSP(d) write_TSPLIB(tsp, file="example.tsp", precision = 6) r <- read_TSPLIB("example.tsp", precision = 6) expect_equivalent(tsp[-2], r[-2]) expect_gt(r[2], range(tsp, finite = TRUE)[2]) ## clean up unlink("example.tsp") TSP/tests/testthat.R0000644000176200001440000000007014204053416014041 0ustar liggesuserslibrary("testthat") library("TSP") test_check("TSP") TSP/src/0000755000176200001440000000000014412674612011516 5ustar liggesusersTSP/src/tour_length.c0000644000176200001440000000511314363765515014224 0ustar liggesusers#include #include #include #include "matrix_pos.h" /* * Calculate the tour length given a distance matrix and a permutation vector */ SEXP tour_length_dist(SEXP R_dist, SEXP R_order) { double tour_length = 0.0; SEXP R_tour_length; double segment; bool posinf = false; bool neginf = false; int *order = INTEGER(R_order); int n = INTEGER(getAttrib(R_dist, install("Size")))[0]; double *dist = REAL(R_dist); if (n != LENGTH(R_order)) error("length of distance matrix and tour do not match"); for (int i = 0; i < (n-1); i++) { segment = dist[LT_POS(n, order[i]-1, order[i+1]-1)]; // check Inf if (segment == R_PosInf) posinf = true; else if (segment == R_NegInf) neginf = true; else tour_length += segment; } // close tour if (n > 1) { segment = dist[LT_POS(n, order[n-1]-1, order[0]-1)]; // check Inf if (segment == R_PosInf) posinf = true; else if (segment == R_NegInf) neginf = true; else tour_length += segment; // inf if (posinf && neginf) tour_length = NA_REAL; else if (posinf) tour_length = R_PosInf; else if (neginf) tour_length = R_NegInf; } // create R object PROTECT(R_tour_length = NEW_NUMERIC(1)); REAL(R_tour_length)[0] = tour_length; UNPROTECT(1); return R_tour_length; } /* * Calculate tour length form a matrix */ SEXP tour_length_matrix(SEXP R_matrix, SEXP R_order) { double tour_length = 0.0; SEXP R_tour_length; double segment; bool posinf = false; bool neginf = false; int n = INTEGER(GET_DIM(R_matrix))[0]; double *matrix = REAL(R_matrix); int *order = INTEGER(R_order); if (n != LENGTH(R_order)) error("length of distance matrix and tour do not match"); for (int i = 0; i < (n-1); i++) { segment = matrix[M_POS(n, order[i]-1, order[i+1]-1)]; // check inf first if (segment == R_PosInf) posinf = true; else if (segment == R_NegInf) neginf = true; else tour_length += segment; } // close tour segment = matrix[M_POS(n, order[n-1]-1, order[0]-1)]; // check inf first if (segment == R_PosInf) posinf = true; else if (segment == R_NegInf) neginf = true; else tour_length += segment; // inf if (posinf && neginf) tour_length = NA_REAL; else if (posinf) tour_length = R_PosInf; else if (neginf) tour_length = R_NegInf; PROTECT(R_tour_length = NEW_NUMERIC(1)); REAL(R_tour_length)[0] = tour_length; UNPROTECT(1); return R_tour_length; } TSP/src/matrix_pos.h0000644000176200001440000000110614204301667014046 0ustar liggesusers /* LT_POS to access a lower triangle matrix by C. Buchta * modified by M. Hahsler * n ... number of rows/columns * i,j ... column and row index [0, (n-1)] * * Note: does not cover the case i==j! * * long vectors: we make now sure that the index id R_xlen_t */ #ifndef LT_POS #define LT_POS(n, i, j) \ (i)<(j) ? ((R_xlen_t)(n)*(i) - ((R_xlen_t)(i)+1)*(i)/2 + (j)-(i)) -1 \ : ((R_xlen_t)(n)*(j) - (((R_xlen_t)(j)+1))*(j)/2 + (i)-(j)) -1 #endif /* * access for matrix */ #ifndef M_POS #define M_POS(rows, i, j) \ (i) + (R_xlen_t)(j)*(rows) #endif TSP/src/dll.c0000644000176200001440000000237113053150677012440 0ustar liggesusers #include #include #include extern SEXP two_opt(SEXP R_matrix, SEXP R_t); extern SEXP two_opt_sym(SEXP R_matrix, SEXP R_t); extern SEXP insertion_cost(SEXP R_matrix, SEXP R_order, SEXP R_k); extern SEXP tour_length_dist(SEXP R_dist, SEXP R_order); extern SEXP tour_length_matrix(SEXP R_matrix, SEXP R_order); void R_init_TSP(DllInfo *dll) { const R_CallMethodDef CallEntries[] = { {"R_two_opt", (DL_FUNC) two_opt, 2}, {"R_two_opt_sym", (DL_FUNC) two_opt_sym, 2}, {"R_insertion_cost", (DL_FUNC) insertion_cost, 3}, {"R_tour_length_dist", (DL_FUNC) tour_length_dist, 2}, {"R_tour_length_matrix", (DL_FUNC) tour_length_matrix, 2}, {NULL, NULL, 0} }; R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); R_RegisterCCallable("arules", "R_two_opt", (DL_FUNC) two_opt); R_RegisterCCallable("arules", "R_two_opt_sym", (DL_FUNC) two_opt_sym); R_RegisterCCallable("arules", "R_insertion_cost", (DL_FUNC) insertion_cost); R_RegisterCCallable("arules", "R_tour_length_dist", (DL_FUNC) tour_length_dist); R_RegisterCCallable("arules", "R_tour_length_matrix", (DL_FUNC) tour_length_matrix); } TSP/src/insertion_cost.c0000644000176200001440000000372212606077054014730 0ustar liggesusers#include #include #include "matrix_pos.h" /* * Calculate insertion cost for the insertion algorithms */ SEXP insertion_cost(SEXP R_matrix, SEXP R_order, SEXP R_k) { int n = INTEGER(GET_DIM(R_matrix))[0]; int length = LENGTH(R_order); int *order = INTEGER(R_order); int k = INTEGER(R_k)[0]-1; SEXP R_cost; PROTECT(R_cost = NEW_NUMERIC(length)); double link_add1, link_add2, link_remove; double *matrix = REAL(R_matrix); double *cost = REAL(R_cost); if (length == 1) { cost[0] = matrix[M_POS(n, order[0]-1, k)]; }else{ for (int i = 0; i < (length-1); i++) { link_add1 = matrix[M_POS(n, order[i]-1, k)]; link_add2 = matrix[M_POS(n, k, order[i+1]-1)]; link_remove = matrix[M_POS(n, order[i]-1, order[i+1]-1)]; //Rprintf("Links: %f %f %f\n", link_add1, link_add2, link_remove); // check for infinity if(link_add1 == R_NegInf || link_add2 == R_NegInf || link_remove == R_PosInf) cost[i] = R_NegInf; else if(link_add1 == R_PosInf || link_add2 == R_PosInf || link_remove == R_NegInf) cost[i] = R_PosInf; else cost[i] = link_add1 + link_add2 - link_remove; } link_add1 = matrix[M_POS(n, order[length-1]-1, k)]; link_add2 = matrix[M_POS(n, k, order[0]-1)]; link_remove = matrix[M_POS(n, order[length-1]-1, order[0]-1)]; // check for infinity if(link_add1 == R_PosInf || link_add2 == R_PosInf) cost[length-1] = R_PosInf; else if(link_remove == R_PosInf) cost[length-1] = R_NegInf; // removing a inf is very good else cost[length-1] = link_add1 + link_add2 - link_remove; } UNPROTECT(1); return R_cost; } TSP/src/two_opt.c0000644000176200001440000001271414204302070013343 0ustar liggesusers #include #include #include "matrix_pos.h" //#define TWOOPT_DEBUG 1 // only improvements >EPSILON are used #define EPSILON 1.0e-7 /* 2-opt * * R_matrix ... matrix with distances * R_t .. initial tour * * inf and NA is not allowed! * */ // this implementation also works for asymetric TSPs SEXP two_opt(SEXP R_matrix, SEXP R_t) { int i, j, n; int swaps; int swap1, swap2; double imp, imp_tmp, imp_best; int tmp; double *matrix = REAL(R_matrix); // make a copy of the initial tour (Note: t is 1-based) int *t = INTEGER(R_t = PROTECT(duplicate(R_t))); // check n = INTEGER(GET_DIM(R_matrix))[0]; if (LENGTH(R_t) != n) error("tour has invalid length"); for (i = 0; i < n; i++) if (t[i] < 1 || t[i] > n) error("tour contains invalid values"); // main loop do{ swaps = 0; swap1 = swap2 = 0; imp_best = 0.0; // find the swap with largest improvement // i is first city to swap (0-based index) for (i = 1; i < n-1; i++){ imp = 0.0; // add gains for getting to the first city (i-1 -> i) imp += matrix[M_POS(n, t[i-1]-1, t[i]-1)]; // gains by adding one more city to the swap imp += matrix[M_POS(n, t[i]-1, t[i+1]-1)]; // j is the last city to swap (0-based index) for (j = i+1; j < n-1; j++){ // gains by adding one more city to the swap imp += matrix[M_POS(n, t[j]-1, t[j+1]-1)]; // increased cost for one more city imp -= matrix[M_POS(n, t[j]-1, t[j-1]-1)]; // include gains from closing the tour (i-1 -> j and i -> j+1) imp_tmp = imp - matrix[M_POS(n, t[i-1]-1, t[j]-1)] - matrix[M_POS(n, t[i]-1, t[j+1]-1)]; if(imp_tmp > EPSILON) { swaps++; if(imp_tmp > imp_best) { imp_best = imp_tmp; swap1 = i; swap2 = j; } } } // check the last city (needs distance to first city) j = n-1; // increased cost for one more city imp -= matrix[M_POS(n, t[j]-1, t[j-1]-1)]; // include gains from closing the tour (this time with first city) imp_tmp = imp - matrix[M_POS(n, t[i-1]-1, t[j]-1)] - matrix[M_POS(n, t[i]-1, t[0]-1)]; // check improvement if(imp_tmp > EPSILON) { swaps++; if(imp_tmp > imp_best) { imp_best = imp_tmp; swap1 = i; swap2 = j; } } } #ifdef TWOOPT_DEBUG printf("two_opt: %d possible swaps\n", swaps); #endif // reverse sub-tour if(swaps > 0){ #ifdef TWOOPT_DEBUG printf("two_opt: best improvement is %f\n", imp_best); printf("two_opt: reversing cities %d to %d\n", swap1+1, swap2+1); #endif for(i = 0; i < (swap2-swap1+1)/2; i++) { // +1 for even length tmp = t[swap1+i]; t[swap1+i] = t[swap2-i]; t[swap2-i] = tmp; } } R_CheckUserInterrupt(); }while (swaps > 0); UNPROTECT(1); return R_t; } // this implementation only works for symmetric TSPs // Note: code is slightly faster than the code above but is not used SEXP two_opt_sym(SEXP R_matrix, SEXP R_t) { int i, j, n; int swaps; int swap1, swap2; double e1, e2, e1_swap, e2_swap; double imp, cur_imp; int tmp; double *matrix = REAL(R_matrix); // make a copy of the initial tour int *t = INTEGER(R_t = PROTECT(duplicate(R_t))); // check n = INTEGER(GET_DIM(R_matrix))[0]; if (LENGTH(R_t) != n) error("tour has invalid length"); for (i = 0; i < n; i++) { if (t[i] < 1 || t[i] > n) error("tour contains invalid values"); } // main loop do{ swaps = 0; swap1 = swap2 = 0; imp = 0.0; // find the swap with largest improvement (works only for symetric TSPs) for (i = 0; i < (n-2); i++){ e1 = matrix[M_POS(n, t[i]-1, t[i+1]-1)]; for (j = (i+1); j < (n-1); j++){ e2 = matrix[M_POS(n, t[j]-1, t[j+1]-1)]; e1_swap = matrix[M_POS(n, t[i]-1, t[j]-1)]; e2_swap = matrix[M_POS(n, t[i+1]-1, t[j+1]-1)]; /* // handle pos inf (now handled in R code) if (e1_swap == R_PosInf || e2_swap == R_PosInf) cur_imp = 0; else if (e1 == R_PosInf || e2 == R_PosInf) cur_imp = R_PosInf; else */ cur_imp = (e1+e2) - (e1_swap+e2_swap); if(cur_imp > 0) { swaps++; if(cur_imp > imp) { imp = cur_imp; swap1 = i+1; swap2 = j; } } } // check the last city (needs distance to first city) e2 = matrix[M_POS(n, t[n-1]-1, t[0]-1)]; e1_swap = matrix[M_POS(n, t[i]-1, t[n-1]-1)]; e2_swap = matrix[M_POS(n, t[i+1]-1, t[0]-1)]; cur_imp = (e1+e2) - (e1_swap+e2_swap); // check improvement if(cur_imp > 0) { swaps++; if(cur_imp > imp) { imp = cur_imp; swap1 = i+1; swap2 = n-1; } } } #ifdef TWOOPT_DEBUG printf("two_opt: %d possible swaps\n", swaps); #endif // reverse sub-tour if(swaps > 0){ #ifdef TWOOPT_DEBUG printf("two_opt: best improvement is %f\n", imp); printf("two_opt: swapping %d to %d\n", swap1, swap2); #endif for(i = 0; i < (swap2-swap1+1)/2; i++) { // +1 for even length tmp = t[swap1+i]; t[swap1+i] = t[swap2-i]; t[swap2-i] = tmp; } } R_CheckUserInterrupt(); }while (swaps >0); UNPROTECT(1); return R_t; } TSP/vignettes/0000755000176200001440000000000014412674611012736 5ustar liggesusersTSP/vignettes/TSP.Rnw0000644000176200001440000013064014412657264014105 0ustar liggesusers%\documentclass[10pt,a4paper,fleqn]{article} \documentclass[nojss]{jss} \usepackage[english]{babel} %% my packages %\usepackage{a4wide} %\usepackage[round,longnamesfirst]{natbib} %\usepackage{hyperref} % \usepackage{amsmath} \usepackage{amsfonts} % %\newcommand{\strong}[1]{{\normalfont\fontseries{b}\selectfont #1}} \newcommand{\class}[1]{\mbox{\textsf{#1}}} \newcommand{\func}[1]{\mbox{\texttt{#1()}}} %\newcommand{\code}[1]{\mbox{\texttt{#1}}} %\newcommand{\pkg}[1]{\strong{#1}} \newcommand{\samp}[1]{`\mbox{\texttt{#1}}'} %\newcommand{\proglang}[1]{\textsf{#1}} \newcommand{\set}[1]{\mathcal{#1}} %\usepackage{Sweave} %% \VignetteIndexEntry{Introduction to TSP} \author{Michael Hahsler\\Southern Methodist University \And Kurt Hornik\\Wirtschaftsuniversit\"at Wien} \title{\pkg{TSP} -- Infrastructure for the Traveling Salesperson Problem} %% for pretty printing and a nice hypersummary also set: \Plainauthor{Michael Hahsler, Kurt Hornik} %% comma-separated \Plaintitle{TSP -- Infrastructure for the Traveling Salesperson Problem} %% without formatting \Shorttitle{Infrastructure for the TSP} %% a short title (if necessary) %% an abstract and keywords \Abstract{ The traveling salesperson problem (also known as traveling salesman problem or TSP) is a well known and important combinatorial optimization problem. The goal is to find the shortest tour that visits each city in a given list exactly once and then returns to the starting city. Despite this simple problem statement, solving the TSP is difficult since it belongs to the class of NP-complete problems. The importance of the TSP arises besides from its theoretical appeal from the variety of its applications. Typical applications in operations research include vehicle routing, computer wiring, cutting wallpaper and job sequencing. The main application in statistics is combinatorial data analysis, e.g., reordering rows and columns of data matrices or identifying clusters. In this paper we introduce the \proglang{R}~package \pkg{TSP} which provides a basic infrastructure for handling and solving the traveling salesperson problem. The package features S3 classes for specifying a TSP and its (possibly optimal) solution as well as several heuristics to find good solutions. In addition, it provides an interface to \emph{Concorde}, one of the best exact TSP solvers currently available. } \Keywords{combinatorial optimization, traveling salesman problem, \proglang{R}} \Plainkeywords{combinatorial optimization, traveling salesman problem, R} %% without formatting %% The address of (at least) one author should be given %% in the following format: \Address{ Michael Hahsler\\ Engineering Management, Information, and Systems\\ Lyle School of Engineering\\ Southern Methodist University\\ P.O. Box 750123 \\ Dallas, TX 75275-0123\\ E-mail: \email{mhahsler@lyle.smu.edu}\\ Kurt Hornik\\ Department of Finance, Accounting and Statistics\\ Wirtschaftsuniversit\"at Wien\\ 1090 Wien, Austria\\i E-mail: \email{kurt.hornik@wu-wien.ac.at}\\ URL: \url{http://statmath.wu.ac.at/~hornik/} } \begin{document} <>= options(width = 75, useFancyQuotes=FALSE, prompt="R> ") ### for sampling set.seed(1234) @ %\title{Introduction to \pkg{TSP} -- Infrastructure for the Traveling % Salesperson Problem} %\author{Michael Hahsler and Kurt Hornik} \maketitle \sloppy %\abstract{ % The traveling salesperson (or, salesman) problem (TSP) is a % well known and important combinatorial optimization problem. The goal % is to find the shortest tour that visits each city in a given list % exactly once and then returns to the starting city. Despite this % simple problem statement, solving the TSP is difficult since it % belongs to the class of NP-complete problems. The importance of the % TSP arises besides from its theoretical appeal from the variety of its % applications. Typical applications in operations research include % vehicle routing, computer wiring, cutting wallpaper and job % sequencing. The main application in statistics is combinatorial data % analysis, e.g., reordering rows and columns of data matrices or % identifying clusters. In this paper we introduce the % \proglang{R}~package \pkg{TSP} which provides a basic infrastructure % for handling and solving the traveling salesperson problem. The % package features S3 classes for specifying a TSP and its (possibly % optimal) solution as well as several heuristics to find good % solutions. In addition, it provides an interface to \emph{Concorde}, % one of the best exact TSP solvers currently available. } \section{Introduction} The traveling salesperson problem~\citep[TSP;][]{Lawler1985, Gutin2002} is a well known and important combinatorial optimization problem. The goal is to find the shortest tour that visits each city in a given list exactly once and then returns to the starting city. Formally, the TSP can be stated as follows. The distances between $n$ cities are stored in a distance matrix $\mathbf{D}$ with elements $d_{ij}$ where $i,j = 1\dots n$ and the diagonal elements $d_{ii}$ are zero. A \emph{tour} can be represented by a cyclic permutation $\pi$ of $\{1, 2,\dots, n\}$ where $\pi(i)$ represents the city that follows city $i$ on the tour. The traveling salesperson problem is then the optimization problem to find a permutation $\pi$ that minimizes the \emph{length of the tour} denoted by \begin{equation} \sum_{i=1}^n d_{i\pi(i)}. \end{equation} % see Lenstra & Kan 1975: Some simple Applications to the TSP For this minimization task, the tour length of $(n-1)!$ permutation vectors have to be compared. This results in a problem which is very hard to solve and in fact known to be NP-complete~\citep{Johnson1985a}. However, solving TSPs is an important part of applications in many areas including vehicle routing, computer wiring, machine sequencing and scheduling, frequency assignment in communication networks~\citep{Lenstra1975, Punnen2002}. %and structuring of %matrices~\citep{Lenstra1975, Punnen2002}. Applications in statistical data analysis include ordering and clustering objects. For example, data analysis applications in psychology ranging from profile smoothing to finding an order in developmental data are presented by~\cite{Hubert1978}. Clustering and ordering using TSP solvers is currently becoming popular in biostatistics. For example, \cite{Ray2007} describe an application for ordering genes and \cite{Johnson2006} use a TSP solver for clustering proteins. In this paper we give a very brief overview of the TSP and introduce the \proglang{R}~package \pkg{TSP} which provides an infrastructure for handling and solving TSPs. The paper is organized as follows. In Section~\ref{sec:TSP} we briefly present important aspects of the TSP including different problem formulations and approaches to solve TSPs. In Section~\ref{sec:infrastructure} we give an overview of the infrastructure implemented in \pkg{TSP} and the basic usage. In Section~\ref{sec:examples}, several examples are used to illustrate the package's capabilities. Section~\ref{sec:conclusion} concludes the paper. A previous version of this manuscript was published in the \emph{Journal of Statistical Software} \citep{TSP:Hahsler+Hornik2007}. \section{Theory} \label{sec:TSP} In this section, we briefly summarize some aspects of the TSP which are important for the implementation of the \pkg{TSP} package described in this paper. For a complete treatment of all aspects of the TSP, we refer the interested reader to the classic book edited by \cite{Lawler1985} and the more modern book edited by \cite{Gutin2002}. It has to be noted that in this paper, following the origin of the TSP, the term \emph{distance} is used. Distance is used here interchangeably with dissimilarity or cost and, unless explicitly stated, no restrictions to measures which obey the triangle inequality are made. An important distinction can be made between the symmetric TSP and the more general asymmetric TSP. For the symmetric case (normally referred to as just \emph{TSP}), for all distances in $\mathbf{D}$ the equality $d_{ij} = d_{ji}$ holds, i.e., it does not matter if we travel from $i$ to $j$ or the other way round, the distance is the same. In the asymmetric case (called \emph{ATSP}), the distances are not equal for all pairs of cities. Problems of this kind arise when we do not deal with spatial distances between cities but, e.g., with the cost or necessary time associated with traveling between locations, where the price for the plane ticket between two cities may be different depending on which way we go. \subsection{Different formulations of the TSP} \label{sec:formulations} Other than the permutation problem in the introduction, the TSP can also be formulated as a graph theoretic problem. Here the TSP is formulated by means of a complete graph $G = (V, E)$, where the cities correspond to the node set $V = \{1,2,\ldots,n\}$ and each edge $e_i \in E$ has an associated weight $w_i$ representing the distance between the nodes it connects. If the graph is not complete, the missing edges can be replaced by edges with very large distances. The goal is to find a \emph{Hamiltonian cycle}, i.e., a cycle which visits each node in the graph exactly once, with the least weight in the graph~\citep{Hoffman1985}. This formulation naturally leads to procedures involving minimum spanning trees for tour construction or edge exchanges to improve existing tours. TSPs can also be represented as integer and linear programming problems~\citep[see, e.g.,][]{Punnen2002}. The \emph{integer programming (IP) formulation} is based on the assignment problem with additional constraint of no sub-tours: \[ \begin{array}{rl} \text{Minimize } & \sum_{i=1}^n\sum_{j=1}^n{d_{ij}x_{ij}} % = \mathrm{trace}(\mathbf{D}^T\mathbf{X}) \\[3mm] \text{Subject to } & \sum_{i=1}^n{x_{ij}=1}, \quad j=1,\ldots,n, \\ & \sum_{j=1}^n{x_{ij}=1}, \quad i=1,\ldots,n, \\ & x_{ij} = 0 \text{ or } 1 \\ & \text{no sub-tours allowed} \\ \end{array} \] The solution matrix $\mathbf{X} = (x_{ij})$ of the assignment problem represents a tour or a collection of sub-tour (several unconnected cycles) where only edges which corresponding to elements $x_{ij} = 1$ are on the tour or a sub-tour. The additional restriction that no sub-tours are allowed (called \emph{sub-tour elimination constraints}) restrict the solution to only proper tours. Unfortunately, the number of sub-tour elimination constraints grows exponentially with the number of cities which leads to an extremely hard problem. The \emph{linear programming (LP) formulation} of the TSP is given by: \[ \begin{array}{rl} \text{Minimize } & \sum_{i=1}^m{w_ix_i} = \mathbf{w}^T\mathbf{x}\\[3mm] \text{Subject to } & \mathbf{x} \in \mathcal{S} \\ \end{array} \] where $m$ is the number of edges $e_i$ in $G$, $w_i \in \mathbf{w}$ is the weight of edge $e_i$ and $\mathbf{x}$ is the incidence vector indicating the presence or absence of each edge in the tour. Again, the constraints given by $\mathbf{x} \in \mathcal{S}$ are problematic since they have to contain the set of incidence vectors of all possible Hamiltonian cycles in $G$ which amounts to a direct search of all $(n-1)!$ possibilities and thus in general is infeasible. However, relaxed versions of the linear programming problem with removed integrality and sub-tour elimination constraints are extensively used by modern TSP solvers where such a partial description of constraints is used and improved iteratively in a branch-and-bound approach. \subsection{Useful manipulations of the distance matrix} \label{sec:manipulations} Sometimes it is useful to transform the distance matrix $\mathbf{D} = (d_{ij})$ of a TSP into a different matrix $\mathbf{D'} = (d'_{ij})$ which has the same optimal solution. Such a transformation requires that for any Hamiltonian cycle $H$ in a graph represented by its distance matrix $\mathbf{D}$ the equality \begin{equation*} \sum_{i,j \in H}{d_{ij}} = \alpha \sum_{i,j \in H}{d'_{ij}} + \beta \end{equation*} holds for suitable $\alpha > 0$ and $\beta \in \mathbb{R}$. From the equality we see that additive and multiplicative constants leave the optimal solution invariant. This property is useful to rescale distances, e.g., for many solvers, distances in the interval $[0, 1]$ have to be converted into integers from~1 to a maximal value. A different manipulation is to reformulate an asymmetric TSP as a symmetric TSP. This is possible by doubling the number of cities~\citep{Jonker1983}. For each city a dummy city is added. Between each city and its corresponding dummy city a very small value (e.g., $-\infty$) is used. This makes sure that each city always occurs in the solution together with its dummy city. The original distances are used between the cities and the dummy cities, where each city is responsible for the distance going to the city and the dummy city is responsible for the distance coming from the city. The distances between all cities and the distances between all dummy cities are set to a very large value (e.g., $\infty$) which makes these edges infeasible. An example for equivalent formulations as an asymmetric TSP (to the left) and a symmetric TSP (to the right) for three cities is: \begin{equation*} \begin{pmatrix} 0 &d_{12} &d_{13} \\ d_{21} &0 &d_{23} \\ d_{31} &d_{32} &0 \\ \end{pmatrix} \Longleftrightarrow \begin{pmatrix} 0 &\infty &\infty & -\infty &d_{21} &d_{31} \\ \infty &0 &\infty & d_{12} &-\infty &d_{31} \\ \infty &\infty &0 & d_{13} &d_{23} &-\infty \\ -\infty &d_{12} &d_{13} & 0 &\infty &\infty \\ d_{21} &-\infty &d_{23} & \infty &0 &\infty \\ d_{31} &d_{32} &-\infty & \infty &\infty &0 \\ \end{pmatrix} \end{equation*} Instead of the infinity values suitably large negative and positive values can be used. The new symmetric TSP can be solved using techniques for symmetric TSPs which are currently far more advanced than techniques for ATSPs. Removing the dummy cities from the resulting tour gives the solution for the original ATSP. \subsection{Finding exact solutions for the TSP} \label{sec:exact} Finding the exact solution to a TSP with $n$ cities requires to check $(n-1)!$ possible tours. To evaluate all possible tours is infeasible for even small TSP instances. To find the optimal tour \cite{Held1962} presented the following \emph{dynamic programming} formulation: Given a subset of city indices (excluding the first city) $S \subset \{2, 3, \dots, n\}$ and $l \in S$, let $d^*(S, l)$ denote the length of the shortest path from city $1$ to city $l$, visiting all cities in $S$ in-between. For $S = \{l\}$, $d^*(S,l)$ is defined as $d_{1l}$. The shortest path for larger sets with $|S| > 1$ is \begin{equation} d^*(S,l) = \mathrm{min}_{m \in S\setminus\{l\}}\Bigl( d^*(S\setminus\{l\},m) + d_{ml}\Bigl). %\text{ for } |S| > 1. \end{equation} Finally, the minimal tour length for a complete tour which includes returning to city $1$ is \begin{equation} d^{**} = \mathrm{min}_{l \in \{2,3,\dots,n\}}\Bigl( d^*(\{2,3,\dots,n\}, l) + d_{l1}\Bigl). \end{equation} Using the last two equations, the quantities $d^*(S,l)$ can be computed recursively and the minimal tour length $d^{**}$ can be found. In a second step, the optimal permutation $\pi = \{1, i_2, i_3,\dots,i_n\}$ of city indices $1$ through $n$ can be computed in reverse order, starting with $i_n$ and working successively back to $i_2$. The procedure exploits the fact that a permutation $\pi$ can only be optimal, if \begin{equation} d^{**} = d^*(\{2,3,\dots,n\}, i_n) + d_{i_n1} \end{equation} and, for $2 \le p \le n-1$, \begin{equation} d^*(\{i_2, i_3,\dots, i_p, i_{p+1}\}, i_{p+1}) = d^*(\{i_2,i_3,\dots,i_p\}, i_p) + d_{i_pi_{p+1}}. \end{equation} The space complexity of storing the values for all $d^*(S,l)$ is $(n-1)2^{n-2}$ which severely restricts the dynamic programming algorithm to TSP problems of small sizes. However, for very small TSP instances this approach is fast and efficient. %\marginpar{time complexity if order $n^22^n$. Check!} A different method, which can deal with larger instances, uses a relaxation of the linear programming problem presented in Section~\ref{sec:formulations} and iteratively tightens the relaxation till a solution is found. This general method for solving linear programming problems with complex and large inequality systems is called \emph{cutting plane method} and was introduced by \cite{Dantzig1954}. Each iteration begins with using instead of the original linear inequality description $\mathcal{S}$ the relaxation $A\mathbf{x} \le b$, where the polyhedron $P$ defined by the relaxation contains $\mathcal{S}$ and is bounded. The optimal solution $\mathbf{x}^*$ of the relaxed problem can be obtained using standard linear programming solvers. If the $\mathbf{x}^*$ found belongs to $\mathcal{S}$, the optimal solution of the original problem is obtained, otherwise, a linear inequality can be found which is satisfied by all points in $\mathcal{S}$ but violated by $\mathbf{x}^*$. Such an inequality is called a cutting plane or cut. A family of such cutting planes can be added to the inequality system $A\mathbf{x} \le b$ to obtain a tighter relaxation for the next iteration. If no further cutting planes can be found or the improvement in the objective function due to adding cuts gets very small, the problem is branched into two sub-problems which can be minimized separately. Branching is done iteratively which leads to a binary tree of sub-problems. Each sub-problem is either solved without further branching or is found to be irrelevant because its relaxed version already produces a longer path than a solution of another sub-problem. This method is called \emph{branch-and-cut}~\citep{Padberg1990} which is a variation of the well known \emph{branch-and-bound}~\citep{Land1960} procedure. The initial polyhedron $P$ used by \cite{Dantzig1954} contains all vectors $\mathbf{x}$ for which all $x_e \in \mathbf{x}$ satisfy $0 \le x_e \le 1$ and in the resulting tour each city is linked to exactly two other cities. Various separation algorithms for finding subsequent cuts to prevent sub-tours (\emph{sub-tour elimination inequalities}) and to ensure an integer solution \citep[\emph{Gomory cuts;}][]{Gomory1963} were developed over time. The currently most efficient implementation of this method is \emph{Concorde} described in~\cite{Applegate2000}. \subsection{Heuristics for the TSP} \label{sec:heuristics} The NP-completeness of the TSP already makes it more time efficient for small-to-medium size TSP instances to rely on heuristics in case a good but not necessarily optimal solution is sufficient. TSP heuristics typically fall into two groups, tour construction heuristics which create tours from scratch and tour improvement heuristics which use simple local search heuristics to improve existing tours. In the following we will only discuss heuristics available in \pkg{TSP}, for a comprehensive overview of the multitude of TSP heuristics including an experimental comparison, we refer the reader to the book chapter by \cite{Johnson2002}. \subsubsection{Tour construction heuristics} The implemented tour construction heuristics are the nearest neighbor algorithm and the insertion algorithms. \paragraph{Nearest neighbor algorithm.} The nearest neighbor algorithm~\citep{Rosenkrantz1977} follows a very simple greedy procedure: The algorithm starts with a tour containing a randomly chosen city and then always adds to the last city in the tour the nearest not yet visited city. The algorithm stops when all cities are on the tour. An extension to this algorithm is to repeat it with each city as the starting point and then return the best tour found. This heuristic is called repetitive nearest neighbor. \paragraph{Insertion algorithms.} All insertion algorithms~\citep{Rosenkrantz1977} start with a tour consisting of an arbitrary city and then choose in each step a city $k$ not yet on the tour. This city is inserted into the existing tour between two consecutive cities $i$ and $j$, such that the insertion cost (i.e., the increase in the tour's length) $$d(i,k) + d(k,j) - d(i,j)$$ is minimized. The algorithms stop when all cities are on the tour. The insertion algorithms differ in the way the city to be inserted next is chosen. The following variations are implemented: \begin{description} \item[Nearest insertion] The city $k$ is chosen in each step as the city which is nearest to a city on the tour. \item[Farthest insertion] The city $k$ is chosen in each step as the city which is farthest from any of the cities on the tour. \item[Cheapest insertion] The city $k$ is chosen in each step such that the cost of inserting the new city is minimal. \item[Arbitrary insertion] The city $k$ is chosen randomly from all cities not yet on the tour. \end{description} The nearest and cheapest insertion algorithms correspond to the minimum spanning tree algorithm by \cite{Prim1957}. Adding a city to a partial tour corresponds to adding an edge to a partial spanning tree. For TSPs with distances obeying the triangular inequality, the equality to minimum spanning trees provides a theoretical upper bound for the two algorithms of twice the optimal tour length. The idea behind the farthest insertion algorithm is to link cities far outside into the tour first to establish an outline of the whole tour early. With this change, the algorithm cannot be directly related to generating a minimum spanning tree and thus the upper bound stated above cannot be guaranteed. However, it can was shown that the algorithm generates tours which approach $2/3$ times the optimal tour length~\citep{Johnson1985}. \subsubsection{Tour improvement heuristics} Tour improvement heuristics are simple local search heuristics which try to improve an initial tour. A comprehensive treatment of the topic can be found in the book chapter by \cite{Rego2002}. \paragraph{$k$-Opt heuristics.} The idea is to define a neighborhood structure on the set of all admissible tours. Typically, a tour $t'$ is a neighbor of another tour $t$ if $t'$ can be obtained from $t$ by deleting $k$ edges and replacing them by a set of different feasible edges (a $k$-Opt move). In such a structure, the tour can iteratively be improved by always moving from one tour to its best neighbor till no further improvement is possible. The resulting tour represents a local optimum which is called $k$-optimal. Typically, $2$-Opt~\citep{Croes1958} and $3$-Opt~\citep{Lin1965} heuristics are used in practice. \paragraph{Lin-Kernighan heuristic.} This heuristic~\citep{Lin1973} does not use a fixed value for $k$ for its $k$-Opt moves, but tries to find the best choice of $k$ for each move. The heuristic uses the fact that each $k$-Opt move can be represented as a sequence of $2$-Opt moves. It builds up a sequence of $2$-Opt moves, checking after each additional move whether a stopping rule is met. Then the part of the sequence which gives the best improvement is used. This is equivalent to a choice of one $k$-Opt move with variable $k$. Such moves are used till a local optimum is reached. By using full backtracking, the optimal solution can always be found, but the running time would be immense. Therefore, only limited backtracking is allowed in the procedure, which helps to find better local optima or even the optimal solution. Further improvements to the procedure are described by \cite{Lin1973}. \section{Computational infrastructure: the TSP package} \label{sec:infrastructure} In package~\pkg{TSP}, a traveling salesperson problem is defined by an object of class \class{TSP} (symmetric) or \class{ATSP} (asymmetric). \func{solve\_TSP} is used to find a solution, which is represented by an object of class \class{TOUR}. Figure~\ref{fig:overview} gives an overview of this infrastructure. \begin{figure} \centering \includegraphics[width=14cm]{overview} \caption{An overview of the classes in \pkg{TSP}.} \label{fig:overview} \end{figure} \class{TSP} objects can be created from a distance matrix (a \class{dist} object) or a symmetric matrix using the creator function \func{TSP} or coercion with \func{as.TSP}. Similarly, \class{ATSP} objects are created by \func{ATSP} or \func{as.ATSP} from square matrices representing the distances. In the creation process, labels are taken and stored as city names in the object or can be explicitly given as arguments to the creator functions. Several methods are defined for the classes: \begin{itemize} \item \func{print} displays basic information about the problem (number of cities and the distance measure employed). \item \func{n\_of\_cities} returns the number of cities. \item \func{labels} returns the city names. \item \func{image} produces a shaded matrix plot of the distances between cities. The order of the cities can be specified as the argument \code{order}. \end{itemize} Internally, an object of class \class{TSP} is a \class{dist} object with an additional class attribute and, therefore, if needed, can be coerced to \class{dist} or to a matrix. An \class{ATSP} object is represented as a square matrix. Obviously, asymmetric TSPs are more general than symmetric TSPs, hence, symmetric TSPs can also be represented as asymmetric TSPs. To formulate an asymmetric TSP as a symmetric TSP with double the number of cities (see Section \ref{sec:manipulations}), \func{reformulate\_ATSP\_as\_TSP} is provided. This function creates the necessary dummy cities and adapts the distance matrix accordingly. A popular format to save TSP descriptions to disk which is supported by most TSP solvers is the format used by \emph{TSPLIB}, a library of sample instances of the TSP maintained by \cite{Reinelt2004}. The \pkg{TSP} package provides \func{read\_TSPLIB} and \func{write\_TSPLIB} to read and save symmetric and asymmetric TSPs in TSPLIB format. Class \class{TOUR} represents a solution to a TSP by an integer permutation vector containing the ordered indices and labels of the cities to visit. In addition, it stores an attribute indicating the length of the tour. Again, suitable \func{print} and \func{labels} methods are provided. The raw permutation vector (i.e., the order in which cities are visited) can be obtained from a tour using \func{as.integer}. With \func{cut\_tour}, a circular tour can be split at a specified city resulting in a path represented by a vector of city indices. The length of a tour can always be calculated using \func{tour\_length} and specifying a TSP and a tour. Instead of the tour, an integer permutation vector calculated outside the \pkg{TSP} package can be used as long as it has the correct length. All TSP solvers in \pkg{TSP} can be used with the simple common interface: \begin{quote} \code{solve\_TSP(x, method, control)} \end{quote} where \code{x} is the TSP to be solved, \code{method} is a character string indicating the method used to solve the TSP and \code{control} can contain a list with additional information used by the solver. The available algorithms are shown in Table~\ref{tab:methods}. \begin{table} \caption{Available algorithms in \pkg{TSP}.} \label{tab:methods} \centering \begin{tabular}{llc} \hline \textbf{Algorithm} & \textbf{Method argument} & \textbf{Applicable to} \\ \hline Nearest neighbor algorithm & \code{"nn"} & TSP/ATSP \\ Repetitive nearest neighbor algorithm & \code{"repetitive\_nn"} & TSP/ATSP \\ Nearest insertion & \code{"nearest\_insertion"} & TSP/ATSP \\ Farthest insertion & \code{"farthest\_insertion"} & TSP/ATSP \\ Cheapest insertion & \code{"cheapest\_insertion"} & TSP/ATSP \\ Arbitrary insertion & \code{"arbitrary\_insertion"} & TSP/ATSP \\ Concorde TSP solver & \code{"concorde"} & TSP \\ 2-Opt improvement heuristic & \code{"two\_opt"} & TSP/ATSP \\ Chained Lin-Kernighan & \code{"linkern"} & TSP \\ \hline \end{tabular} \end{table} All algorithms except the Concorde TSP solver and the Chained Lin-Kernighan heuristic (a Lin-Kernighan variation described in \cite{Applegate2003}) are included in the package and distributed under the GNU Public License (GPL). For the Concorde TSP solver and the Chained Lin-Kernighan heuristic only a simple interface (using \func{write\_TSPLIB}, calling the executable and reading back the resulting tour) is included in \pkg{TSP}. The executable itself is part of the Concorde distribution, has to be installed separately and is governed by a different license which allows only for academic use. The interfaces are included since Concorde~\citep{Applegate2000,Applegate2006} is currently one of the best implementations for solving symmetric TSPs based on the branch-and-cut method discussed in section~\ref{sec:exact}. In May 2004, Concorde was used to find the optimal solution for the TSP of visiting all 24,978 cities in Sweden. The computation was carried out on a cluster with 96 Xeon 2.8 GHz nodes and took in total almost 100 CPU years. \section{Examples} \label{sec:examples} In this section we provide some examples for the use of package~\pkg{TSP}. We start with a simple example of how to use the interface of the TSP solver to compare different heuristics. Then we show how to solve related tasks, using the Hamiltonian shortest path problem as an example. Finally, we give an example of clustering using the \pkg{TSP} package. An additional application can be found in package \pkg{seriation}~\citep{TSP:Hahsler+Buchta+Hornik:2006} which uses the TSP solvers from \pkg{TSP} to order (seriate) objects given a proximity matrix. \subsection{Comparing some heuristics} In the following example, we use several heuristics to find a short path in the \code{USCA50} data set which contains the distances between the first 50 cities in the \code{USCA312} data set. The \code{USCA312} data set contains the distances between 312 cities in the USA and Canada coded as a symmetric TSP. The smaller data set is used here, since some of the heuristic solvers employed are rather slow. <<>>= library("TSP") data("USCA50") USCA50 @ We calculate tours using different heuristics and store the results in the list \code{tours}. As an example, we show the first tour which displays the method employed, the number of cities involved and the tour length. All tour lengths are compared using the dot chart in Figure~\ref{fig:dotchart}. For the chart, we add a point for the optimal solution which has a tour length of 14497. The optimal solution can be found using Concorde (\code{method = "concorde"}). It is omitted here, since Concorde has to be installed separately. <>= set.seed(1234) @ <>= methods <- c("nearest_insertion", "farthest_insertion", "cheapest_insertion", "arbitrary_insertion", "nn", "repetitive_nn", "two_opt") tours <- sapply(methods, FUN = function(m) solve_TSP(USCA50, method = m), simplify = FALSE) ## tours$concorde <- solve_TSP(tsp, method = "concorde") tours[[1]] dotchart(sort(c(sapply(tours, tour_length), optimal = 14497)), xlab = "tour length", xlim = c(0, 20000)) @ \begin{figure} \centering \includegraphics[width=11cm, trim=0 10 0 0]{TSP-dotchart_USCA50} \caption{Comparison of the tour lengths for the USCA50 data set.} \label{fig:dotchart} \end{figure} \subsection{Finding the shortest Hamiltonian path} The problem of finding the shortest Hamiltonian path through a graph (i.e., a path which visits each node in the graph exactly once) can be transformed into the TSP with cities and distances representing the graphs vertices and edge weights, respectively~\citep{Garfinkel1985}. Finding the shortest Hamiltonian path through all cities disregarding the endpoints can be achieved by inserting a `dummy city' which has a distance of zero to all other cities. The position of this city in the final tour represents the cutting point for the path. In the following we use a heuristic to find a short path in the \code{USCA312} data set. Inserting dummy cities is performed in \pkg{TSP} by \func{insert\_dummy}. <>= set.seed(1234) @ <<>>= library("TSP") data("USCA312") tsp <- insert_dummy(USCA312, label = "cut") tsp @ The TSP now contains an additional dummy city and we can try to solve this TSP. <<>>= tour <- solve_TSP(tsp, method="farthest_insertion") tour @ Since the dummy city has distance zero to all other cities, the path length is equal to the tour length reported above. The path starts with the first city in the list after the `dummy' city and ends with the city right before it. We use \func{cut\_tour} to create a path and show the first and last 6 cities on it. <<>>= path <- cut_tour(tour, "cut") head(labels(path)) tail(labels(path)) @ The tour found in the example results in a path from Lihue on Hawaii to Prince Rupert in British Columbia. Such a tour can also be visualized using a scatter plot with a map from package \pkg{maps}. Note that the \code{if} statement and the \code{plot} in the \code{else} part in the following is not needed and only checks if the map package is installed when building this document. <>= if(require(maps)) { library("maps") data("USCA312_GPS") plot_path <- function(path) { plot((USCA312_GPS[, c("long", "lat")]), cex = .3, col = "red") map("world", col = "gray", add = TRUE) lines(USCA312_GPS[, c("long", "lat")][path,], col = "black") points(USCA312_GPS[c(head(path, 1), tail(path, 1)), c("long", "lat")], pch = 19, col = "black") } plot_path(path) } else { plot(NA, xlim= c(0,1), ylim = c(0,1)) text(.5, .5, "Suggested packages not available") } @ \begin{figure} \centering \includegraphics[width=10cm, trim=0 30 0 0]{TSP-map1} \caption{A ``short'' Hamiltonian path for the USCA312 dataset.} \label{fig:map1} \end{figure} The map containing the path is presented in Figure~\ref{fig:map1}. It has to be mentioned that the path found by the used heuristic is considerable longer than the optimal path found by Concorde with a length of $34928$, illustrating the power of modern TSP algorithms. For the following two examples, we indicate how the distance matrix between cities can be modified to solve related shortest Hamiltonian path problems. These examples serve as illustrations of how modifications can be made to transform different problems into a TSP. The first problem is to find the shortest Hamiltonian path starting with a given city. In this case, all distances to the selected city are set to zero, forcing the evaluation of all possible paths starting with this city and disregarding the way back from the final city in the tour. By modifying the distances the symmetric TSP is changed into an asymmetric TSP (ATSP) since the distances between the starting city and all other cities are no longer symmetric. As an example, we choose New York as the starting city. We transform the data set into an ATSP and set the column corresponding to New York to zero before solving it. Thus, the distance to return from the last city in the path to New York does not contribute to the path length. We use the nearest neighbor heuristic to calculate an initial tour which is then improved using $2$-Opt moves and cut at New York to create a path. <>= set.seed(1234) @ <<>>= atsp <- as.ATSP(USCA312) ny <- which(labels(USCA312) == "New York, NY") atsp[, ny] <- 0 initial_tour <- solve_TSP(atsp, method="nn") initial_tour tour <- solve_TSP(atsp, method ="two_opt", control = list(tour = initial_tour)) tour path <- cut_tour(tour, ny, exclude_cut = FALSE) head(labels(path)) tail(labels(path)) @ <>= plot_path(path) @ \begin{figure} \centering \includegraphics[width=10cm, trim=0 30 0 0]{TSP-map2} \caption{A Hamiltonian path for the USCA312 dataset starting in New York.} \label{fig:map2} \end{figure} The found path is presented in Figure~\ref{fig:map2}. It begins with New York and cities in New Jersey and ends in a city in Manitoba, Canada. %The path shows the typical behavior %of the nearest neighbor heuristic with first connecting the cities close by and %then making rather big ``jumps'' for the final cities. Concorde and many advanced TSP solvers can only solve symmetric TSPs. To use these solvers, we can formulate the ATSP as a TSP using \func{reformulate\_ATSP\_as\_TSP} which introduces a dummy city for each city (see Section~\ref{sec:manipulations}). <<>>= tsp <- reformulate_ATSP_as_TSP(atsp) tsp @ After finding a tour for the TSP, the dummy cities are removed again giving the tour for the original ATSP. Note that the tour needs to be reversed if the dummy cities appear before and not after the original cities in the solution of the TSP. The following code is not executed here, since it takes several minutes to execute and Concorde has to be installed separately. Concorde finds the optimal solution with a length of $36091$. <>= tour <- solve_TSP(tsp, method = "concorde") tour <- as.TOUR(tour[tour <= n_of_cities(atsp)]) @ Finding the shortest Hamiltonian path which ends in a given city can be achieved likewise by setting the row in the distance matrix which corresponds to this city to zero. For finding the shortest Hamiltonian path we can also restrict both end points. This problem can be transformed to a TSP by replacing the two cities by a single city which contains the distances from the start point in the columns and the distances to the end point in the rows. Obviously this is again an asymmetric TSP. For the following example, we are only interested in paths starting in New York and ending in Los Angeles. Therefore, we remove the two cities from the distance matrix, create an asymmetric TSP and insert a dummy city called \code{"LA/NY"}. The distances from this dummy city are replaced by the distances from New York and the distances towards are replaced by the distances towards Los Angeles. <>= set.seed(1234) @ <<>>= m <- as.matrix(USCA312) ny <- which(labels(USCA312) == "New York, NY") la <- which(labels(USCA312) == "Los Angeles, CA") atsp <- ATSP(m[-c(ny,la), -c(ny,la)]) atsp <- insert_dummy(atsp, label = "LA/NY") la_ny <- which(labels(atsp) == "LA/NY") atsp[la_ny, ] <- c(m[-c(ny,la), ny], 0) atsp[, la_ny] <- c(m[la, -c(ny,la)], 0) @ We use the nearest insertion heuristic. <<>>= tour <- solve_TSP(atsp, method ="nearest_insertion") tour path_labels <- c("New York, NY", labels(cut_tour(tour, la_ny)), "Los Angeles, CA") path_ids <- match(path_labels, labels(USCA312)) head(path_labels) tail(path_labels) @ <>= plot_path(path_ids) @ The path jumps from New York to cities in Ontario and it passes through cities in California and Nevada before ending in Los Angeles. The path displayed in Figure~\ref{fig:map3} contains multiple crossings which indicate that the solution is suboptimal. The optimal solution generated by reformulating the problem as a TSP and using Concorde has only a tour length of $38489$. \begin{figure} \centering \includegraphics[width=10cm, trim=0 30 0 0]{TSP-map3} \caption{A Hamiltonian path for the USCA312 dataset starting in New York and ending in Los Angles.} \label{fig:map3} \end{figure} \subsection{Rearrangement clustering} Solving a TSP to obtain a clustering was suggested several times in the literature \citep[see, e.g.,][]{Lenstra1974, Alpert1997, Johnson2004}. The idea is that objects in clusters are visited in consecutive order and from one cluster to the next larger ``jumps'' are necessary. \cite{Climer2006} call this type of clustering \emph{rearrangement clustering} and suggest to automatically find the cluster boundaries of $k$ clusters by adding $k$ \emph{dummy cities} which have constant distance $c$ to all other cities and are infinitely far from each other. In the optimal solution of the TSP, the dummy cities must separate the most distant cities and thus represent optimal boundaries for $k$ clusters. For the following example, we use the well known iris data set. Since we know that the dataset contains three classes denoted by the variable \code{Species}, we insert three dummy cities into the TSP for the iris data set and perform rearrangement clustering using the default method (nearest insertion algorithm). Note that this algorithm does not find the optimal solution and it is not guaranteed that the dummy cities will present the best cluster boundaries. %\marginpar{FIXME: Was sagt Concorde dazu?} <>= set.seed(4444) @ <<>>= data("iris") tsp <- TSP(dist(iris[-5]), labels = iris[, "Species"]) tsp_dummy <- insert_dummy(tsp, n = 3, label = "boundary") tour <- solve_TSP(tsp_dummy) @ Next, we plot the TSP's permuted distance matrix using shading to represent distances. The result is displayed as Figure~\ref{fig:clustering}. Lighter areas represent larger distances. The additional red lines represent the positions of the dummy cities in the tour, which mark the cluster boundaries obtained. <>= ## plot the distance matrix image(tsp_dummy, tour, xlab = "objects", ylab ="objects") ## draw lines where the dummy cities are located abline(h = which(labels(tour)=="boundary"), col = "red") abline(v = which(labels(tour)=="boundary"), col = "red") @ \begin{figure} \centering \includegraphics[width=9cm, height=9cm, trim=0 20 0 0]{TSP-clustering} \caption{Result of rearrangement clustering using three dummy cities and the nearest insertion algorithm on the iris data set.} \label{fig:clustering} \end{figure} One pair of red horizontal and vertical lines exactly separates the darker from lighter areas. The second pair occurs inside the larger dark block. We can look at how well the partitioning obtained fits the structure in the data given by the species field in the data set. Since we used the species as the city labels in the TSP, the labels in the tour represent the partitioning with the dummy cities named `boundary' separating groups. The result can be summarized based on the run length encoding of the obtained tour labels: <<>>= out <- rle(labels(tour)) data.frame(Species = out$values, Lenghts = out$lengths, Pos = cumsum(out$lengths)) @ One boundary perfectly splits the iris data set into a group containing only examples of species `Setosa' and a second group containing examples for `Virginica' and `Versicolor'. However, the second boundary only separates several examples of species `Virginica' from other examples of the same species. Even in the optimal tour found by Concorde, this problem occurs. The reason why the rearrangement clustering fails to split the data into three groups is the closeness between the groups `Virginica' and `Versicolor'. To inspect this problem further, we can project the data points on the first two principal components of the data set and add the path segments which resulted from solving the TSP. <>= prc <- prcomp(iris[1:4]) plot(prc$x, pch = as.numeric(iris[,5]), col = as.numeric(iris[,5])) paths <- cut_tour(tour, cut = "boundary") for(p in paths) lines(prc$x[p, ]) @ \begin{figure} \centering \includegraphics[width=10cm, trim=0 20 0 0]{TSP-clustering2} \caption{The 3 path segments representing a rearrangement clustering of the iris data set. The data points are projected on the set's first two principal components. The three species are represented by different markers and colors.} \label{fig:clustering2} \end{figure} The result in shown in Figure~\ref{fig:clustering2}. The three species are identified by different markers and all points connected by a single path represent a cluster found. Clearly, the two groups to the right side of the plot are too close to be separated correctly by using just the distances between individual points. This problem is similar to the \emph{chaining effect} known from hierarchical clustering using the single-linkage method. \section{Conclusion} \label{sec:conclusion} In this paper we presented the R extension package \pkg{TSP} which implements an infrastructure to handle and solve TSPs. The package introduces classes for problem descriptions (\class{TSP} and \class{ATSP}) and for the solution (\class{TOUR}). Together with a simple interface for solving TSPs, it allows for an easy and transparent usage of the package. With the interface to Concorde, \pkg{TSP} also can use a state of the art implementation which efficiently computes exact solutions using branch-and-cut. \section*{Acknowledgments} The authors of this paper want to thank Roger Bivand for providing the code to correctly draw tours and paths on a projected map. % %\bibliographystyle{abbrvnat} \bibliography{TSP} % \end{document} TSP/vignettes/TSP.bib0000644000176200001440000002704512606077054014073 0ustar liggesusers@INCOLLECTION{Garfinkel1985, author = {R.S. Garfinkel}, title = {Motivation and Modeling}, year = {1985}, chapter = {2}, pages = {17--36}, crossref = {Lawler1985}, owner = {hahsler}, timestamp = {2006.11.06} } @INCOLLECTION{Hoffman1985, author = {A.J. Hoffman and P. Wolfe}, title = {History}, year = {1985}, chapter = {1}, pages = {1--16}, crossref = {Lawler1985}, owner = {hahsler} } @INCOLLECTION{Johnson2002, author = {D.S. Johnson and L.A. McGeoch}, title = {Experimental Analysis of Heuristics for the {STSP}}, year = {2002}, chapter = {9}, pages = {369--444}, crossref = {Gutin2002}, owner = {hahsler}, timestamp = {2006.12.07} } @INCOLLECTION{Johnson1985, author = {D.S. Johnson and C.H. Papadimitriou}, title = {Performance guarantees for heuristics}, year = {1985}, chapter = {5}, pages = {145--180}, crossref = {Lawler1985}, owner = {hahsler}, timestamp = {2006.10.06} } @INCOLLECTION{Johnson1985a, author = {D.S. Johnson and C.H. Papadimitriou}, title = {Computational complexity}, year = {1985}, chapter = {3}, pages = {37--86}, crossref = {Lawler1985}, owner = {hahsler}, timestamp = {2006.10.06} } @INCOLLECTION{Punnen2002, author = {A.P. Punnen}, title = {The Traveling Salesman Problem: Applications, Formulations and Variations}, year = {2002}, chapter = {1}, pages = {1--28}, crossref = {Gutin2002}, owner = {hahsler}, timestamp = {2006.12.06} } @INCOLLECTION{Rego2002, author = {C. Rego and F. Glover}, title = {Local Search and Metaheuristics}, year = {2002}, chapter = {8}, pages = {309--368}, crossref = {Gutin2002}, owner = {hahsler}, timestamp = {2006.12.06} } @ARTICLE{Alpert1997, author = {C. J. Alpert and A. B. Kahng}, title = {Splitting an Ordering into a Partititon to Minimize Diameter}, journal = {Journal of Classification}, year = {1997}, volume = {14}, pages = {51--74}, number = {1}, owner = {hahsler}, timestamp = {2006.12.19} } @MANUAL{Applegate2006, title = {Concorde {TSP} Solver}, author = {David Applegate and Robert Bixby and Vasek Chv{\'a}tal and William Cook}, year = {2006}, owner = {hahsler}, timestamp = {2006.10.06}, url = {http://www.tsp.gatech.edu/concorde/} } @ARTICLE{Applegate1998, author = {David Applegate and Robert Bixby and Vasek Chv{\'a}tal and William Cook}, title = {On the Solution of Traveling Salesman Problems}, journal = {Documenta Mathematica}, year = {1998}, volume = {Extra Volume ICM}, pages = {645--656}, owner = {hahsler}, timestamp = {2006.10.06} } @INPROCEEDINGS{Applegate2000, author = {David Applegate and Robert E. Bixby and Vasek Chv{\'a}tal and William Cook}, title = {{TSP} Cuts Which Do Not Conform to the Template Paradigm}, booktitle = {Computational Combinatorial Optimization, Optimal or Provably Near-Optimal Solutions}, year = {2000}, editor = {M. Junger and D. Naddef}, volume = {2241}, series = {Lecture Notes In Computer Science}, pages = {261--304}, address = {London, UK}, publisher = {Springer-Verlag}, owner = {hahsler}, timestamp = {2006.10.06} } @ARTICLE{Applegate2003, author = {David Applegate and William Cook and Andre Rohe}, title = {Chained {L}in-{K}ernighan for Large Traveling Salesman Problems}, journal = {{INFORMS} Journal on Computing}, year = {2003}, volume = {15}, pages = {82--92}, number = {1}, owner = {hahsler} } @ARTICLE{Climer2006, author = {Sharlee Climer and Weixiong Zhang}, title = {Rearrangement Clustering: Pitfalls, Remedies, and Applications}, journal = {Journal of Machine Learning Research}, year = {2006}, volume = {7}, pages = {919--943}, month = jun, owner = {hahsler}, timestamp = {2006.10.06} } @ARTICLE{Croes1958, author = {G. A. Croes}, title = {A Method for Solving Traveling-Salesman Problems}, journal = {Operations Research}, year = {1958}, volume = {6}, pages = {791--812}, number = {6}, owner = {hahsler}, timestamp = {2006.11.29} } @ARTICLE{Dantzig1954, author = {G.B. Dantzig and D.R. Fulkerson and S.M. Johnson}, title = {Solution of a Large-scale Traveling Salesman Problem}, journal = {Operations Research}, year = {1954}, volume = {2}, pages = {393--410}, owner = {hahsler}, timestamp = {2006.12.10} } @INPROCEEDINGS{Gomory1963, author = {R.E. Gomory}, title = {An algorithm for integer solutions to linear programs}, booktitle = {Recent Advances in Mathematical Programming}, year = {1963}, editor = {R.L. Graves and P. Wolfe}, pages = {269--302}, address = {New York}, publisher = {McGraw-Hill}, owner = {hahsler}, timestamp = {2006.12.10} } @TECHREPORT{Hahsler2007a, author = {Michael Hahsler and Kurt Hornik and Christian Buchta}, title = {Getting Things in Order: An Introduction to the {R} package seriation}, institution = {Research Report Series, Department of Statistics and Mathematics, Wirtschaftsuniversit{\"a}t Wien}, year = {2007}, type = {Report}, number = {58}, address = {Augasse 2--6, 1090 Wien, Austria}, month = {August}, owner = {hahsler}, timestamp = {2007.12.04} } @ARTICLE{Held1962, author = {M. Held and R.M. Karp}, title = {A Dynamic Programming Approach to Sequencing Problems}, journal = {Journal of {SIAM}}, year = {1962}, volume = {10}, pages = {196--210}, owner = {hahsler}, timestamp = {2006.11.27} } @ARTICLE{Hubert1978, author = {Lawrence J. Hubert and Frank B. Baker}, title = {Applications of Combinatorial Programming to Data Analysis: The Traveling Salesman and Related Problems}, journal = {Psychometrika}, year = {1978}, volume = {43}, pages = {81--91}, number = {1}, month = {March}, owner = {hahsler}, timestamp = {2007.12.04} } @INPROCEEDINGS{Johnson2004, author = {David Johnson and Shankar Krishnan and Jatin Chhugani and Subodh Kumar and Suresh Venkatasubramanian}, title = {Compressing Large Boolean Matrices Using Reordering Techniques}, booktitle = {Proceedings of the 30th VLDB Conference}, year = {2004}, pages = {13--23}, owner = {hahsler}, timestamp = {2006.12.19} } @ARTICLE{Johnson2006, author = {Olin Johnson and Jing Liu}, title = {A traveling salesman approach for predicting protein functions}, journal = {Source Code for Biology and Medicine}, year = {2006}, volume = {1}, pages = {1--7}, number = {3}, owner = {hahsler}, timestamp = {2007.11.28} } @ARTICLE{Jonker1983, author = {Jonker, R. and Volgenant, T.}, title = {Transforming asymmetric into symmetric traveling salesman problems}, journal = {Operations Research Letters}, year = {1983}, volume = {2}, pages = {161--163}, owner = {hahsler}, timestamp = {2006.12.05} } @INPROCEEDINGS{Kruskal1956, author = {J.B. Kruskal}, title = {On the shortest spanning subtree and the traveling salesman problem}, booktitle = {Proceedings of the American Mathematical Society}, year = {1956}, pages = {48--50}, owner = {hahsler}, timestamp = {2006.10.06} } @ARTICLE{Land1960, author = {A.H. Land and A.G. Doig}, title = {An Automatic Method for Solving Discrete Programming Problems}, journal = {Econometrica}, year = {1960}, volume = {28}, pages = {497--520}, owner = {hahsler}, timestamp = {2006.12.12} } @ARTICLE{Lenstra1975, author = {J.K. Lenstra and A.H.G. Rinooy Kan}, title = {Some simple applications of the travelling salesman problem}, journal = {Operational Research Quarterly}, year = {1975}, volume = {26}, pages = {717--733}, number = {4}, month = {November}, owner = {hahsler}, timestamp = {2006.11.07} } @ARTICLE{Lenstra1974, author = {J. K. Lenstra}, title = {Clustering a Data Array and the Traveling-Salesman Problem}, journal = {Operations Research}, year = {1974}, volume = {22}, pages = {413--414}, number = {2}, owner = {hahsler}, timestamp = {2006.12.19} } @ARTICLE{Lin1965, author = {S. Lin}, title = {Computer solutions of the traveling-salesman problem}, journal = {Bell System Technology Journal}, year = {1965}, volume = {44}, pages = {2245--2269}, owner = {hahsler}, timestamp = {2006.11.29} } @ARTICLE{Lin1973, author = {S. Lin and B.W. Kernighan}, title = {An effective heuristic algorithm for the traveling-salesman problem}, journal = {Operations Research}, year = {1973}, volume = {21}, pages = {498--516}, number = {2}, owner = {hahsler}, timestamp = {2006.11.27} } @ARTICLE{Padberg1990, author = {M. Padberg and G. Rinaldi}, title = {Facet identification for the symmetric traveling salesman polytope}, journal = {Mathematical Programming}, year = {1990}, volume = {47}, pages = {219--257}, number = {2}, address = {Secaucus, NJ, USA}, issn = {0025-5610}, publisher = {Springer-Verlag New York, Inc.} } @ARTICLE{Prim1957, author = {R.C. Prim}, title = {Shortest connection networks and some generalisations}, journal = {Bell System Technical Journal}, year = {1957}, volume = {36}, pages = {1389--1401}, owner = {hahsler}, timestamp = {2006.10.06} } @ARTICLE{Ray2007, author = {S. S. Ray and S. Bandyopadhyay and S. K. Pal}, title = {Gene Ordering in Partitive Clustering using Microarray Expressions}, journal = {Journal of Biosciences}, year = {2007}, volume = {32}, pages = {1019--1025}, number = {5}, month = {August}, owner = {hahsler}, timestamp = {2007.11.28} } @MANUAL{Reinelt2004, title = {{TSPLIB}}, author = {Gerhard Reinelt}, organization = {Universit{\"a}t Heidelberg, Institut f{\"u}r Informatik}, address = {Im Neuenheimer Feld 368,D-69120 Heidelberg, Germany}, year = {2004}, owner = {hahsler}, timestamp = {2006.10.06}, url = {http://www.iwr.uni-heidelberg.de/groups/comopt/software/TSPLIB95/} } @ARTICLE{Rosenkrantz1977, author = {Daniel J. Rosenkrantz and Richard E. Stearns and Philip M. Lewis, II}, title = {An Analysis of Several Heuristics for the Traveling Salesman Problem}, journal = {{SIAM} Journal on Computing}, year = {1977}, volume = {6}, pages = {563--581}, number = {3}, owner = {hahsler}, timestamp = {2006.11.13} } @BOOK{Gutin2002, title = {The Traveling Salesman Problem and Its Variations}, publisher = {Kluwer}, year = {2002}, editor = {G. Gutin and A.P. Punnen}, volume = {12}, series = {Combinatorial Optimization}, address = {Dordrecht}, owner = {hahsler}, timestamp = {2006.11.29} } @BOOK{Lawler1985, title = {The Traveling Salesman Problem}, publisher = {Wiley}, year = {1985}, editor = {Lawler, E. L. and Lenstra, J. K. and Rinnooy Kan, A. H. G. and Shmoys, D. B.}, address = {New York}, owner = {hahsler}, timestamp = {2006.10.05} } @comment{jabref-meta: selector_journal:} @comment{jabref-meta: selector_author:} @comment{jabref-meta: selector_keywords:} @comment{jabref-meta: selector_publisher:} @Manual{TSP:Hahsler+Buchta+Hornik:2006, title = {seriation: Infrastructure for seriation}, author = {Michael Hahsler and Christian Buchta and Kurt Hornik}, year = 2006, note = {R package version 0.1-1}, } @Article{TSP:Pebesma+Bivand:2005, author = {Edzer J. Pebesma and Roger S. Bivand}, title = {Classes and methods for spatial data in {R}}, journal = {R News}, year = 2005, volume = 5, number = 2, pages = {9--13}, month = {November}, url = {http://CRAN.R-project.org/doc/Rnews/}, } @ARTICLE{TSP:Hahsler+Hornik2007, AUTHOR = {Michael Hahsler and Kurt Hornik}, TITLE = {{TSP} -- {I}nfrastructure for the Traveling Salesperson Problem}, JOURNAL = {Journal of Statistical Software}, YEAR = {2007}, VOLUME = {23}, PAGES = {1-21}, NUMBER = {2}, MONTH = {December}, ISSN = {1548-7660} } TSP/vignettes/overview.odg0000644000176200001440000003027712606077054015311 0ustar liggesusersPKAOx5.++mimetypeapplication/vnd.oasis.opendocument.graphicsPKAOx5Configurations2/statusbar/PKAOx5'Configurations2/accelerator/current.xmlPKPKAOx5Configurations2/floater/PKAOx5Configurations2/popupmenu/PKAOx5Configurations2/progressbar/PKAOx5Configurations2/menubar/PKAOx5Configurations2/toolbar/PKAOx5Configurations2/images/Bitmaps/PKAOx5 content.xml\nߧm1BbK$] H& 3`$VGX,K퉓Ɖs\IyaGaYHk,ģ~̮_~R =rSo$Wf\[()XLLesoӽX\}3a0p5jl3`?d蟬.~`)XSG ߋ,6_!CߏHIŵ@ eN(ހ^aRUmM )>/ \Td[4ϹHnwrޢT5t08(-{ f4< DjGph,(zY߯W~h".] 2A [VlѵRR'6:s'ߔʕnhS_tMM eh߾5Ig*Y.*c X>˫[4X^*[,Y{s^H&>bNӞ.8Jʟ!8j7ʌ$mfm4= Y4?iWx:4_N6fdcsc' ]L}’]9Yz@ڲ.WîaW=~P:uqy;c N~vH=Z/__"44a$5mt1ރ(>w˅Qm8oG=fsJ}xE,4: ?tO!CGjۇξ%/S_J(A[8"I''("TtvQ..Sw-=u rV,2~AYjm,bq=`1b4$x{0( (# '3"<uI'Cgo!9o!d& !M3=>o4N;'Czq=!Bo3N3Ad@. f|W潸o}E͟\ݣ{I}y6^j_x囗w$͐LY㎙w)l@|Dۏ% 8"RҕI__RQ?V=^ȋ[zP&@uNjTݭWY'siiiON%'+'ɜÇIB, .钁&zYNaF'&*_8mFԥI? k(bnskrkzr?޴b#Omt4]C~FW/62U ltѝ7W3faKvC':1tbs[:* F90uI|YJѥά[2}gtWLIRj/׾AUpTN,LHW{0:S_T޻w5fI/H1ĤSOldV9hA MA™ R٭nach@#y(9be*xD,f;k L#0]zy%9]qz+gt[>xE!1bVUKhߎ ڕ*J VY~kw畦u_#}xxow9=l[|d EjrPRmmxC\ҘCyr92(rF؎#gőWN궢稜Yܴ> M-ٶ8T8Gu1m sxV`ƠM:UN[Q-NF'鳱lguChG|@:n~0mc()P- h) CB@PMCR}Lu8cC d hm3~LO8Mr#k`.ѳNwqZ'Y(tw%YX!4wjN8QVJ&a_ǫi-R>_ n;]n;BVk#q=kOViVZ8%ז#垡_ ڦ g۲f,u5Y,쇗:>7vu-ԛPK-<( LUPKAOx5 styles.xml\͎6)֏ev-hsAKDZ=$%xw݅ YsfęΘoȸ#<,Y6 ,vm0߾5 CU<&@8D$3@8V6shJpLW,%I)jrTzD=lbnJ r/ Kޖ, Y17C%/`P,B!C>S,M>͝ʲd?0ri)j_9W[$"rr&UDIަJIo dUSN2`s_{PS_wua>sUpWM].w@T+K9MJU)7R׵mҟ{N v,#B]c"w+c x{'t0EXl7ekEg `m9ۛ8ꎒO~mچm18x_rε2di1uL8Spfp%; cD+$YOCLh3wJg̦7WQ =bXro)XÒpA!iL e)ɌiV;lli"W@^ӈtm83/Je(f<>HlJR $ KdzUO4(# VfoV.:6|=R,biJ)~xOM'{4~-#ڒkKGJs*i=[F\\/j,6[ 4DpPǏ]S~ɑpu(EjURAToVI#u~%]Zʰ5X:uV$зv֞*=t NmW|n(Ag@ =ȤgqkpomK:~s+T}^hTqIiUT#˥rX`w&h6Lh 8* KDQ2"}6I,MZ/,:MG4 Fzm("D95 ;u>b~8D4cwϩ{1C40Iɨd6aD>+JL T>)r&DȻ"BjE"4BϫBjy/4N/ˌӎ}5f@ a9ۏJ8偿=XUOê#Zޱ lI"JQRՕE| A N5U; $,y1[DuOY= =Vjc5ִaNqe_G'lh˚DC%sh^uaQkEt7QsQU@m>_쩀0շk͔3RtZ^hpfT4Qre~.8ޕ_y8sn[)5Ho;;/Y"!r3iٌ|Ծ煭[:ұ_:Ko_:K~/}^~/~iY2є.Is{e֭ 06 3pՍ^,GWGЮ/ }|5ڽ09c]=7XWuXWuXW6Bc]}Zx|6RE(.rFgzї5y+/>8]g8FU%Fx> Zeˡ{Zf:QZDc?~mv. Uw9NrKPqupQ*:QI(ak追4\i>?"D-YLePk]Lܙ榕bֿL w|6 5l = ůu@R9xdr0&w B3 OpenOffice.org/2.0$Linux OpenOffice.org_project/680m5$Build-90732006-10-06T11:33:592006-11-24T10:58:02de-AT20PT1H18M25SPKAOx5Thumbnails/thumbnail.pngL PNG  IHDRFKҟ IDATx]?lDN,P;hw8,Ud]YQj-Pw1*CEJ @y#!BuA$`^hɂC[Wcx&ཻZe;;%9$:)Ł;c7|a۷3[ޢ˶y֤n6 ZtUqH %)?Ym2H 's&8;Q7 2MV;"Bp}c},GgRMwE${a].ѳ0!GKdY!i$l5za &d`ڍםkJ.-޳=ZYQo9j'z.|`*+  F7^\?;eZm.cU*7:DU: -'gܥRf%Vϯ;'$=1p䱬/fy3O[Z^^sMӳw دeFEB74 | 1cL 9++LdUk̀I@`Ҁn$DDVF IJ(%G+ݰCtչ('kf?\N3`RـN7gzM(N6ɓKLq FD%9J!Y,ʿgZW XㅙDV~{w_ݱqhO޴]E{R6gPUhh7H[LUgS;&¦-&as^74$x/w$9Ym49$w qN=PV,akn90W4 S=Z.t0$j3 [z SgjuM*| "si G$A&ʸO—~*Kiedsvi-?Ne/kzu;_/94M@X;&(Doؕ4i>6~X dQZ4qK~P,k%x$ =.y!OL"|eQ/ܤҧ_rڕ|ǮLڊo~A%FoTZȿAoT{R@5X񇿓q&/}QuE;eÃZ6UqUP~ps.e+5>GK7gz p$::3fO޼#2f; (''I+~ϊu}Xp"=P$0 Yʈa(Av@ZhjuHKmZ(\I~mLS}31x}XJ4_lXu&Fa>FE!*[緈`5,\-~=e8Rq~]mu-,v$sb 4zS8B2ӔEgu2_;;WJxȡrT6^4Ƶ_tsٗdа\Y W+Z(R.2?6U "G  H7Om[Ƭ3]P^Tis@B%1 <>H셯@SG8\:q{6{errHP vCՏAJڣ'dts?2@?F8M yl12˞!'bH8P;QAꨔ#G˸'*TGEH5'cEO+t( ^e?V K|1ZG^s8VWYr4m@/x؆ &! a1lǝE  5^3~N/P87 /B 'bڼ(k= O@Co L~qy^@ Ѽnd_bY=pZN\G TQyTeX/^*%Ҽ[ݭכ_(L*\8$G|,K[ ]3sL&!:y!<H" 6~%ހ)+/VT'C5<߇B傤w^3RE@ xhX*L!\(t KA RFjJh/ j' o$9G 1ԈysmIENDB`PKQ L PKAOx5 settings.xmlZr8}߯HQ[[@@%L[`0ooR@,$9|H성恀.紺ۭ/+\<#.0e&u Ԡ_KߦcOOB,FTR-j;}@DAZ V_]6#+>)y%s# vH(( }O#߳Ok1秢lVg 7l djacr*^(g䍮0zީcζ;KclmO1^=!!0&GϜnR5LW7;Idb0 lu@7S6pҘBB y(S$F^)$W*jFǰ!81F qFu|Qf ܍sS~mbB)ΠȒ5gi3%s6qEPH0 v]5nP%HfdR&bnc$LGwt]RBuhw{M .4DcQZ̔*ϒ0`a"wK‰c7uޔ գ!" # !Jx s [>Z*ġw|Sse"H2/']E')?L?Gtt#W;s؉"M"J9;\X5.;pcAd8S2qؾk#$ɩf\A i0Kcc9/4M6ȍs)j)cw1 J¦mƯtL!@$82TR]amtU%06lU^;WgM#ɬh 9aDN\"mO@瓕w1>"j]ȦJ݀"h+ѭ!f?bJ8Gm- v 1-U 7}|GXdG|H+szY~CBټRKIU J- JOP2z|lu&ӛkXe'QTs$94z+%>ND~AU N2@FtS=" \gMr!YmF9p=׶ 'u\@aܖLsSoP<>2*n2q#?z7{^P-]uz^2 c2Zv=RuՕSy͊mˋt\ʀJf2ʭBۛ: 0;j2i9ɸ(/kՇAn +Nu:.h1[;~gnv6*Rg2d#}RbHC۝T yb`yʝ뛣V4cՊą0$c.mʛwS<&Bϒ8b<(sT)i]EX|H!_Tʝz18{oIjN7IQׂpqr՛5\AkagMv@|6s-,2O\څ'.?PKANPKAOx5.++mimetypePKAOx5QConfigurations2/statusbar/PKAOx5'Configurations2/accelerator/current.xmlPKAOx5Configurations2/floater/PKAOx5Configurations2/popupmenu/PKAOx5NConfigurations2/progressbar/PKAOx5Configurations2/menubar/PKAOx5Configurations2/toolbar/PKAOx5Configurations2/images/Bitmaps/PKAOx5-<( LU 1content.xmlPKAOx5Kq?E styles.xmlPKAOx5Koometa.xmlPKAOx5Q L HThumbnails/thumbnail.pngPKAOx5h.% $settings.xmlPKAOx5AN7+META-INF/manifest.xmlPK,TSP/vignettes/overview.pdf0000644000176200001440000003513512606077054015307 0ustar liggesusers%PDF-1.4 %äüöß 2 0 obj <> stream xXn7 Wh"~έ@uv/y$ܑ<8Dԃ:#rcΞOѰw;bOȏlB99CB6TmMk m&{v=/.-?_p׏ qy\ 4)8|6$]̝0sR;'&Elތ0.,I yes9R˜^7꽭WI ݍ;UTz=:ŵvc+ܮlH_ 8"x4èԳLJ!̅m{=+ۋWg>MD7@6($4)',jB4P-Ym Ɉ0HyWxO 쭱(RFoQ GV%l1uA#-6نٝD`P @ CH$J EDE$P..)m]7m;V$a 3B>P492Q M9ثet Hцb.ZJ cJ ׽47d]nc0fŌ0ᤶבX5esPC/:8[(]W|(=Pr >U)v=U u{'WA1$Wݦs/5{c:49˚:|@qnZ\YLP!pprwkb4U MPZicNs2imh)(X $>Tɔ`򠧥II1h[48^x$f4fҟfV`~5aoGȫe)hf b].&&wF0I.VGTDB~],&ލ޿==DXB&)HR?D,5\_&jة4+1YWG;rӧmS ЮG6WMJ@̓*jf%L#߿P}x9'?s.l` endstream endobj 3 0 obj 1405 endobj 5 0 obj <> stream xW{P\gǾ𺰰OBKxIh$rv&MӇMjӇmcDZ>:uik?:mtԚ86ZM8ڎS9<~|;nt.&TrD ;gB$G%V >K8ǵo !*&%g6 IIWnI-_:.>3oK4=/F$ȴ\İ?$}_}<B2LHHLJ^6O1["ɠrssEE4MxcR ar\Ӝcv5ndݶ{7tjVDj)71F-.a7Vj.I2E*; BFe=w.;MȾ;ܕU4Ѽ*lݸyi\Sv*00\[?RZahH,r;x~ T JnLtNK%e١Kôz&kj9DŽY<[j]lUMC0_Ö?ѩspKG*-N6S51{坞MXdR, &ڭ<eAFR^e.d $en~= Wws}}Ǖ=}%{0 u䨾\9 *:~̰gp-+$|:c`G$`4R^x rrgM׆i7;褱]gv4lS~ʖ'w?jPݸr8Y$OW&0yWr%jΒ>ԑg\_jvV>th^dw߯ :Rg0L@}7_~Kרϳ<)P6j@r}WG\mKepGtPw4XX|#6OuYAIԱ,7tm\B?/@r YުU.lbR*z|&KTލ兎#U<6\)k&IjfSRf?f5~pC elvV<٬&>?ysر__|Qsb@QO[Q@)76כRy џP-з ;E-7C=23yf_'C qjm5b 7#KA Z?ݱ]80AOMoӶ:0X BL…ɖxw:@3nql'`ǁpY_uGw遣u+];<{9 qwTQnxx`NUwxQrU.t;OGFN7ҕ}[_fc=ZOFovgkOo۴.22}橡=*O;4}Ɵ_*.T궙J֦hћÑdomW;s- \-ȕs5aY(hX*ϔNd,)gie⅔ۏNIiaM/xkĕ:zɧ>E=&5 QXsTba/= *n 5Lx!L{Hd9!]\BV+@AV ނFWKΒ?O N6nbٗvU +NPj6EO;K೅kSȡ URF5:qNDF'9FgFHhB qZєdӻ4tF H.F''K$Ͷht9:4:dh T3Fg[ }5"uėE,HQ^ScWzu9INr,<尕{`,Q<7!^3mеj8s Js!9%gX*zMJbl^q1:_:1G1q>6:%bT{RXψљ`@dF#6‚u"-ej~hG蜼FEq*̋ai%qdI'xUI,"1[ckv Uk:K-5Z ~U$$Jĺf1i̓c#!" ]Α K-ljGu\^KܤG ͽqhݐ*עy_X}O}@g,E/j(B#d \@ՊB_$QW j3_՞nuTPN:'6|ԯðj{j4.n,xiУ/崈uJݡqܹ 0AyʈaZ~aHZUzSj~cQZi+jU}!5bPQ Yj=I MiϜ_ǦxD_a[ endstream endobj 6 0 obj 2838 endobj 7 0 obj <> endobj 8 0 obj <> stream x]Mn0Fta$BJIXG=1CTeȂ3Ro/Eul?ǯ~45̢maoހJDۛo34.CmL3 ,ⷰ7~c;^!_| W(갮o}v2sB<5 uՆ~^֡/8 5|ceR"+<H.t!BTmN7f'%8UȚ~q~gNĚȏ;:`̉3'33Ur{*ɼGf@f+O)Z#> endobj 10 0 obj <> stream xX{l[y?^DJLR},J,JSÒ%YOK-˖H銤Wڎޒp֤1c6n;Y j"@2 qץ: 4@lj9ȥG *H(D"f#N""7.Sxa_+BHbP@({@aUoFRqplѮ.G|0 ,hE9B%SB]=sAT5<>`SafTl޲u))-CNQٯcTrCBy(DEJΡ5rSRTi)X`.sGx޼E8BBmo v5cX v Ys!瘁! } X&єZ[2c0*j *,mݴ;&Z渶ZF_#$!3Mت[f2xdok/Ճ] ]!6b@EvzMnrIIyyJѤ0z;DLΚm v Nmx=dVK \G{-ӥyj~`zlpf7Fo2.f@mk Z| Q)B29;!23:YZ{K33 ^eo˶hm|h9:r0#(dq sp8zABЯNVF{Y[V\П.kfI$&}o uWhG^粫fjR \m2jU!̔?q t'Z PXisR md]G*2!dKmKGCU}yKho)!ql[BQm5= Ivj׿\R!!!=Y?}vK|_QdrQ]h EEOqɘi!X y ;dFs#B <ꛄ?On+)leb)ޭr]qaD: b]`.'|]2}}'x6wz~{\$Zb՜yd4hUx&Y b;hڤKUҜ-l={N=J|lqx>fR ?_s` )(SSSSb`d*R゚TXmmcqI3l݇ Ӈ'GvZg܇jqy;shٽVg2ꪕ<@| +y <}~ JꚙEU=L+ud{teuAcWC]UR5RYhm=2J5skcRHb઼RHU6l̨b="-XXi6ğP{8q( @0 Lt(t/LZ?00k/Mb)^=|+znV{ ݬרM c.8yb]ҢJlޚ Y*BW3x z_2!?JB^$dO|Stwn֧!;Ss*ҥJqjrT%tIIIB{rK޽~b)CgiVzBsvu+Ŋ#nNCq$A:{:B++ n߇F%>>1άBfeCa nzłꝬ85wExm4 Zo{bf70R ˽y}/]WUC1K 1mni1یscsM2pNJ:ڨ쮙3gN?P$24 kt _=?qJ٥M x|kn69%o__k0厠No[Yͬ[ Қ&)|0-P[pcn5؆.%.!(\~(ŝQ U*jJeիOssr15%v"߾/tr, 5j]r~8mC9VKntO96]XܰJz6 (~XS1]sa_B+@³S !ZF q k_yM1*TUq ghBɱ 8TX {|tApVSΣUcZVgXGeVhD(fcJ4y3aV! S ]u fg5|H^~a9c.8qRy.sL0L(]^J8tErFcJWlu9GgcXc+~IWp ke)2?10ӷcQg 8 3ǔϝJXOIz.t[NȲ4O-KG|P,j/cؠ<JGcTw,{Ԥlq߬<Omc-YnG`Q}k xn'0΃U:`2?M(2pQlL71FEw +blɐk`|. ^BK{]xu|h vfa7n.Ht@)ƓA6(ÊnFK1,(ScN>ЍP4 \O`Nr,PhM\ \{06Ӱ1)]$>1"wv!jd) @}g#[f l+ uh@#tiE>4${k̫phj^??9 kC03L.jUx~ '1R}TaT$1 CpRb4h&Q< =҈[e^]>CܷJM,Zʛmyd**VF}*1VyC,3,#`)UdVBcSȬcj$XHyK\ ZU_$\#ʺlQX[2Uj@գj }fG [h]]Ua; XQbqA+&Jf{iYeb?wǨY¿|}L#*tE*""6 {aeݴhmmeS^D9o endstream endobj 11 0 obj 3916 endobj 12 0 obj <> endobj 13 0 obj <> stream x]n0 3SLJ2b/_?E $ǔ{xOSQJu?=!O1P.'q|3?o3=,/vv0d1o/ endstream endobj 14 0 obj <> endobj 15 0 obj <> stream xYmlS~Ͻ0|$8!_7`F c8N}+]@*M]UNn:NӴiu?6i۟iժ c*sI t{ss}sX֠΀ 4jx NtN `/J*377;|`R'LĎ'es#'yn񝦣&l'Y;?Q8Ym-O/xy`3G>vf֖ddXkjm Hs .I/*Z |@{F.M"K̺ML>BXp7܁YxnJ/ޚHck#Eކ(6xVj`=?Р?lBO-xУ}6`=j&S.ܶ?|}>>~xb>gKHa5uuw4 1Ct0p太.ɽCҠ{F2WgΌJ ?DɢE);]hP]+NU}{%ɣI/+q5c\>Xq+IeQS LfY_[ >{Y0MrkH;j _{3-X<+%bmI[_qlB㊮/%E  !wI}StRR﬚8}DU]؎,|Ѱ77(+FQ2/#^6aip ywC]k5[9c}Rvy6ѾL-P|;0n7Sn%^,@/L{`tVU].L'N.\"_^M&4ezNb]L5b8%ǓFFZCG~kS_v?kv%|Ό`O!/m [|nߨ[{k^~SeVs>`$${ Γb<~gϊ"ٞx#B/I֓m+0k*X0f2]fE@>e耭+K6zV`3*^]X HZ#d ɈNISK^XfrM`yc3rR 4H1#}c r+^zY`1VeY`9a#g&Jh_P`7VeT`t)O l5ei_cKײ\n 2#ı 9Y1W3w83? y0979^eyL`-iYW1-oF-#ฎuT`\a̱e}S`KӋOML`g.SscSh3u2;#:VoWV`C[3~I`*0rl͍̎Yюyǰrh%.c p9:Ƶsl#ϛxE`V^KN+:%9o79.qmכ,0zJ`P0&t舴k_cti@~B5:/q=υH>Wp>)v;h1 񄖤ݝݛ{6Jㇴb L!#ީtpRFTL*S񜎖J)-S=Ow;Vgx&{ -W“^mo r0zޞhO280tb9T:ABg"k4?9GT)(U8n iB?s.$^u(@/w8$"vH *dp۱0EC8p{j6Z8iTKgK4V%-^/W[1^bPށ׶exKl,VT cOHbi{xyR,*2|X[w1ЉPZYBo[cl`wB7lvac_Rc zg[A-S,\vgJ5VFT3=O%9SJpkm>K!Ws2~g Z,t1i8;r"x,-gFlv}>:̣]+wtUw-I7Lf\QYׯTQuiz;uN?08NS8KbbķY?-V4F?3쩬Q-}9*=ا*WUˇ;뻒Q%]e2)CJң< (-+/~ ߳ZWYNWIh Za??X?t1Zf3̜KG)1TlfWL7qI{ |)FRNFYcaڍ7?!Bc;/KgŞiܧi4Jf, endstream endobj 16 0 obj 2613 endobj 17 0 obj <> endobj 18 0 obj <> stream x]n E|tI$Rʒ}n>EaߗGJ]0ftOY{pxJXXj9&Pc!G33xo-Ny Bȫ`>Wc`0Eu33/l]Nt[8Kp-`1ejTQZmkJew0Of4RJOsl7IS.{\D)19qyIL_#/{7ݰϟ5`ZWgSKb xK endstream endobj 19 0 obj <> endobj 20 0 obj << /F1 9 0 R /F2 14 0 R /F3 19 0 R >> endobj 21 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <> endobj 22 0 obj <> endobj 23 0 obj < /Producer /CreationDate(D:20061124105806+01'00')>> endobj xref 0 24 0000000000 65535 f 0000013835 00000 n 0000000019 00000 n 0000001495 00000 n 0000013978 00000 n 0000001516 00000 n 0000004438 00000 n 0000004459 00000 n 0000004648 00000 n 0000005074 00000 n 0000005347 00000 n 0000009349 00000 n 0000009371 00000 n 0000009561 00000 n 0000009987 00000 n 0000010263 00000 n 0000012962 00000 n 0000012984 00000 n 0000013178 00000 n 0000013522 00000 n 0000013726 00000 n 0000013781 00000 n 0000014077 00000 n 0000014125 00000 n trailer < <49C1E7F026D6A67060FABDE68E754300> ] >> startxref 14304 %%EOF TSP/R/0000755000176200001440000000000014412644315011125 5ustar liggesusersTSP/R/reformulare_ATSP_as_TSP.R0000644000176200001440000001372714261142677015653 0ustar liggesusers####################################################################### # TSP - Traveling Salesperson Problem # Copyright (C) 2011 Michael Hahsler and Kurt Hornik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #' Reformulate a ATSP as a symmetric TSP #' #' A ATSP can be formulated as a symmetric TSP by doubling the number of cities #' (Jonker and Volgenant 1983). The solution of the TSP also represents the #' solution of the original ATSP. #' #' To reformulate a [ATSP] as a [TSP], for each city a dummy city (e.g, for 'New #' York' a dummy city 'New York*') is added. Between each city and its #' corresponding dummy city a very small (or negative) distance with value #' `cheap` is used. #' To ensure that the solver places each cities always occurs in the #' solution together with its dummy city, this cost has to be much smaller than #' the distances in the TSP. #' The original distances are used #' between the cities and the dummy cities, where each city is responsible for #' the distance going to the city and the dummy city is responsible for the #' distance coming from the city. The distances between all cities and the #' distances between all dummy cities are set to `infeasible`, a very #' large value which prevents the solver from using these links. #' We use infinite values here and [solve_TSP()] treats them appropriately. #' #' `filter_ATSP_as_TSP_dummies()` can be used to extract the solution for the original #' ATSP from the tour found for an ATSP reformulated as a TSP. Note that the symmetric TSP #' tour does not reveal the direction for the ATSP. The filter function computed the #' tour length for both directions and returns the shorter tour. #' #' [solve_TSP()] has a parameter `as_TSP` which preforms the reformulation and #' filtering the dummy cities automatically. #' #' **Note on performance:** Doubling the problem size is a performance issue especially #' has a negative impact on solution quality for heuristics. It should only be used #' together with Concorde when the optimal solution is required. Most heuristics can solve #' ATSPs directly with good solution quality. #' @family TSP #' #' @param x an [ATSP]. #' @param infeasible value for infeasible connections. #' @param cheap value for distance between a city and its corresponding dummy #' city. #' @param tour a [TOUR] created for a ATSP reformulated as a TSP. #' @param atsp the original [ATSP]. #' @return #' `reformulate_ATSP_as_TSP()` returns a [TSP] object. #' `filter_ATSP_as_TSP_dummies()` returns a [TOUR] object. #' @author Michael Hahsler #' @references Jonker, R. and Volgenant, T. (1983): Transforming asymmetric #' into symmetric traveling salesman problems, _Operations Research #' Letters,_ 2, 161--163. #' @keywords optimize #' @examples #' data("USCA50") #' #' ## set the distances from anywhere to Austin to zero which makes it an ATSP #' austin <- which(labels(USCA50) == "Austin, TX") #' atsp <- as.ATSP(USCA50) #' atsp[, austin] <- 0 #' atsp #' #' ## reformulate as a TSP (by doubling the number of cities with dummy cities marked with *) #' tsp <- reformulate_ATSP_as_TSP(atsp) #' tsp #' #' ## create tour for the TSP. You should use Concorde to find the optimal solution. #' # tour_tsp <- solve_TSP(tsp, method = "concorde") #' # The standard heuristic is bad for this problem. We use it here because #' # Concord may not be installed. #' tour_tsp <- solve_TSP(tsp) #' head(labels(tour_tsp), n = 10) #' tour_tsp #' # The tour length is -Inf since it includes cheap links #' # from a city to its dummy city. #' #' ## get the solution for the original ATSP by filtering out the dummy cities. #' tour_atsp <- filter_ATSP_as_TSP_dummies(tour_tsp, atsp = atsp) #' tour_atsp #' head(labels(tour_atsp), n = 10) #' #' ## This process can also be done automatically by using as_TSP = TRUE: #' # solve_TSP(atsp, method = "concorde", as_TSP = TRUE) #' #' ## The default heuristic can directly solve ATSPs with results close to the #' # optimal solution of 12715. #' solve_TSP(atsp, control = list(rep = 10)) #' @export reformulate_ATSP_as_TSP <- function(x, infeasible = Inf, cheap = -Inf) { if (!inherits(x, "ATSP")) stop("x is not an ATSP object!") method <- attr(x, "method") m <- as.matrix(x) ### check all but the diagonal for cheap! if (cheap >= min(m[-seq(1, nrow(m)^2, nrow(m)+1)])) stop("cheap needs to be strictly smaller than the smallest distance in the ATSP!") if (infeasible < max(m)) stop("infeasible needs to be larger than the largest distance in the ATSP!") ## scale matrix and add cheap links diag(m) <- cheap tsp <- rbind(cbind(matrix( infeasible, ncol = ncol(m), nrow = nrow(m) ), t(m)), cbind(m, matrix( infeasible, ncol = nrow(m), nrow = ncol(m) ))) ## create labels (* for virtual cities) lab <- c(labels(x), paste(labels(x), "*", sep = "")) dimnames(tsp) <- list(lab, lab) attr(tsp, "method") <- method ## return as TSP TSP(tsp) } #' @rdname reformulate_ATSP_as_TSP #' @export filter_ATSP_as_TSP_dummies <- function(tour, atsp) { ### Note: the tour can be in reverse order. t1 <- TOUR(tour[as.integer(tour) <= n_of_cities(atsp)], method = attr(tour, "method"), tsp = atsp) t2 <- TOUR(rev(tour[as.integer(tour) <= n_of_cities(atsp)]), method = attr(tour, "method"), tsp = atsp) if (attr(t1, "tour_length") > attr(t2, "tour_length")) t2 else t1 } TSP/R/tsp_two_opt.R0000644000176200001440000000363714205207106013633 0ustar liggesusers####################################################################### # TSP - Traveling Salesperson Problem # Copyrigth (C) 2011 Michael Hahsler and Kurt Hornik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ## heuristic to improve a tour using exchanges of 2 edges. tsp_two_opt <- function(x, control = NULL){ control <- .get_parameters(control, list( tour = NULL, two_opt_repetitions = 1 ), method = "two_opt") if (!is.null(control$tour) && control$two_opt_repetitions > 1) { control$two_opt_repetitions <- 1 warning("Doing multiple repetitions of two-opt given a fixed tour does not make sense. Doing only 1 repetition.") } ## improve a given tour or create a random tour ## we use a function since for rep >1 we want several random ## initial tours initial <- function() { if(!is.null(control$tour)) as.integer(control$tour) else sample(n_of_cities(x)) } xx <- as.matrix(x) if(control$two_opt_repetitions > 1) { tour <- replicate(control$two_opt_repetitions, .Call(R_two_opt, xx, initial()), simplify = FALSE) lengths <- sapply(tour, FUN = function(t) tour_length(x, t)) cat(lengths) tour <- tour[[which.min(lengths)]] }else tour <- .Call(R_two_opt, xx, initial()) if (control$verbose) cat("Two-opt done.\n\n") tour } TSP/R/tsp_concorde.R0000644000176200001440000002705214363770616013751 0ustar liggesusers####################################################################### # TSP - Traveling Salesperson Problem # Copyright (C) 2011 Michael Hahsler and Kurt Hornik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #' Using the Concorde TSP Solver #' #' The Concorde TSP Solver package contains several solvers. Currently, #' interfaces to the Concorde solver (Applegate et al. 2001), one of the most #' advanced and fastest TSP solvers using branch-and-cut, and the Chained #' Lin-Kernighan (Applegate et al. 2003) implementation are provided in #' \pkg{TSP}. Concorde can solve [TSP]s and [ETSP]s directly. [ATSP]s are #' reformulated as larger TSP's and then solved. #' #' #' **Installation of Concorde** #' #' The Concorde TSP Solver is freely available for academic research. #' It is not included in the \pkg{TSP} R package and has #' to be obtained separately from the #' [Concorde download page](http://www.math.uwaterloo.ca/tsp/concorde/downloads/downloads.htm). #' Either download the precompiled executables and place them in a suitable #' directory (make sure they are executable), or you can get the source code and #' compile the program on your own. \pkg{TSP} needs to know where the executables are. #' There are two options: #' 1. use `concorde_path()` to set the path to the #' directory containing the executables for concorde and linkern, or #' 2. make #' sure that the executables are in the search path stored in the `PATH` #' environment variable (see [Sys.setenv()]). #' #' **Using Concorde for `solve_TSP()`** #' #' [solve_TSP()] uses [write_TSPLIB()] to write the TSP for #' Concorde and tries to find the appropriate `precision` value (digits #' after the decimal point) to convert the provided distances into the needed #' integer value range. The `precision` value can also be specified in #' `control` in [solve_TSP()] with method Concorde. Warning #' messages will alert the user if the conversion to integer values results #' into rounding errors that are worse then what is specified in the #' `precision` control parameter. #' #' To get a list of all available command line options which can be used via #' the `clo` option for `solve_TSP` use `concorde_help()` and #' `linkern_help()`. Several options (\option{-x}, \option{-o}, #' \option{-N}, \option{-Q}) are not available via [solve_TSP()] since they #' are used by the interface. #' #' If Concorde takes too long, then you can kill the 'concorde' process via your #' operating system and you can continue with R. #' #' @family TSP #' #' @name Concorde #' @aliases Concorde concorde concorde_path concorde_help linkern_help #' #' @param path a character string with the path to the directory where the #' executables are installed. #' @returns Nothing. #' @author Michael Hahsler #' @references Concorde home page, #' \url{http://www.math.uwaterloo.ca/tsp/concorde/} #' #' David Applegate, Robert Bixby, Vasek Chvatal, William Cook (2001): TSP cuts #' which do not conform to the template paradigm, Computational Combinatorial #' Optimization, M. Junger and D. Naddef (editors), Springer-Verlag. #' #' David Applegate and William Cook and Andre Rohe (2003): Chained #' Lin-Kernighan for Large Traveling Salesman Problems, \emph{INFORMS Journal #' on Computing}, \bold{15}, 82--92. #' @keywords documentation #' @examples #' #' \dontrun{ #' ## see if Concorde is correctly installed #' concorde_path() #' #' #' ## set path to the Concorde executible if it is not in the search PATH #' ## Example: #' ## concorde_path("~/concorde/") #' #' concorde_help() #' #' data("USCA312") #' #' ## run concorde in verbose mode (-v) with fast cuts only (-V) #' solve_TSP(USCA312, method = "concorde", control = list(clo = "-v -V")) #' } #' NULL ## prepare distances as integers in the appropriate range [0..MAX] .prepare_dist_concorde <- function(x, MAX, precision, verbose = FALSE) { ## handle inf x <- .replaceInf(x) ## fix neg. values min_x <- min(x) if (min_x < 0) { if (verbose) warning( "pTSP contains negative distances (maybe the result of a reformulation from ATSP). Shifting distances by subtracting the minimum.", immediate. = FALSE) x <- x - min_x } ## get max (excluding) to check for possible integer overflows max_x <- max(x) prec <- floor(log10(MAX / max_x)) if (any((x %% 1) != 0) || prec < 0) { if (prec < precision) { warning( paste0( "Concorde/Linken can only handle distances represented as integers. Converting the provided distances to integers with precison ", prec, ". This may lead to rounding errors." ), immediate. = TRUE ) x <- x * 10 ^ prec } } storage.mode(x) <- "integer" ## so write.TSBLIB does not do precision changes x } ## interface to the Concorde algorithm ## (can only handle TSP and no neg. distances!) tsp_concorde <- function(x, control = NULL) { if (!is.null(control$exe)) warning("exe is deprecated. Use concorde_path() instead!") ## get parameters control <- .get_parameters( control, list( clo = "", exe = .find_exe(control$exe, "concorde"), precision = 6, verbose = TRUE, keep_files = FALSE ) ) ## check x if (inherits(x, "TSP")) { #if(n_of_cities(x) < 10) MAX <- 2^15 - 1 else MAX <- 2^31 - 1 ### MFH: concorde may overflow with 2^31-1 if (n_of_cities(x) < 10) MAX <- 2 ^ 15 - 1 else MAX <- 2 ^ 28 - 1 x <- .prepare_dist_concorde(x, MAX, precision = control$precision, verbose = control$verbose) } else if (inherits(x, "ETSP")) { ## nothing to do! } else stop("Concorde only handles TSP and ETSP.") ## get temp files and change working directory wd <- tempdir() dir <- getwd() setwd(wd) on.exit(setwd(dir)) ### fix for Windows by Stephen Eick ##temp_file <- tempfile(tmpdir = wd) temp_file <- basename(tempfile(tmpdir = wd)) ## file name needs to be unique tmp_file_in <- paste(temp_file, ".dat", sep = "") tmp_file_out <- paste(temp_file, ".sol", sep = "") ## precision is already handled! write_TSPLIB(x, file = tmp_file_in, precision = 0) ## change working directory ## do the call and read back result ## we do not check return values of Concorde since they are not ## very consistent system2( control$exe, args = paste("-x", control$clo, "-o", tmp_file_out, tmp_file_in), stdout = if (control$verbose) "" else FALSE, stderr = if (control$verbose) "" else FALSE, ) if (!file.access(tmp_file_out) == 0) stop( "Concorde has not produced a result file.\nIs concorde properly installed? (see ? Concorde)\nDid Concorde finish without an error or being interupted?" ) ##else cat("Concorde done.\n") order <- scan(tmp_file_out, what = integer(0), quiet = TRUE) ## remove number of nodes and add one (result starts with 0) order <- order[-1] + 1L ## tidy up if (!control$keep_files) unlink(c(tmp_file_in, tmp_file_out)) else cat("File are in:", wd, "\n\n") order } ## interface to the Concorde's Chained Lin-Kernighan algorithm ## (can only handle TSP, handles neg. distances) tsp_linkern <- function(x, control = NULL) { if (!is.null(control$exe)) warning("exe is deprecated. Use concorde_path() instead!") ## get parameters control <- .get_parameters( control, list( exe = .find_exe(control$exe, "linkern"), clo = "", precision = 6, verbose = TRUE, keep_files = FALSE ) ) ## have to set -r for small instances <8 if (n_of_cities(x) <= 8) control$clo <- paste(control$clo, "-k", n_of_cities(x)) ## check x if (inherits(x, "TSP")) { #MAX <- 2^31 - 1 MAX <- 2 ^ 28 - 1 x <- .prepare_dist_concorde(x, MAX, precision = control$precision, verbose = control$verbose) } else if (inherits(x, "ETSP")) { ## nothing to do } else stop("Linkern only works for TSP and ETSP.") ## get temp files and change working directory wd <- tempdir() dir <- getwd() setwd(wd) on.exit(setwd(dir)) ### fix for Windows by Stephen Eick ##temp_file <- tempfile(tmpdir = wd) temp_file <- basename(tempfile(tmpdir = wd)) ## file name needs to be unique tmp_file_in <- paste(temp_file, ".dat", sep = "") tmp_file_out <- paste(temp_file, ".sol", sep = "") write_TSPLIB(x, file = tmp_file_in, precision = 0) ## do the call and read back result ## we do not check return values of Concorde since they are not ## very consistent system2( control$exe, args = paste("-o", tmp_file_out, control$clo, tmp_file_in), stdout = if (control$verbose) "" else FALSE, stderr = if (control$verbose) "" else FALSE ) if (!file.access(tmp_file_out) == 0) stop( "Linkern has not produced a result file.\nIs linkern properly installed?\nDid linkern finish without an error or being interrupted?" ) ##else cat("Concorde done.\n") order <- read.table(tmp_file_out)[, 1] ## remove number of nodes and add one (result starts with 0) order <- order + as.integer(1) ## tidy up if (!control$keep_files) unlink(c(tmp_file_in, tmp_file_out)) else cat("File are in:", wd, "\n\n") order } ## path ## path #' @rdname Concorde #' @export concorde_path <- local({ .path <- NULL function(path) { if (missing(path)) { if (!is.null(.path)) return(.path) else { ## find concorde and/or linkern p <- dirname(Sys.which("concorde")) if (p == "") p <- dirname(Sys.which("linkern")) if (p == "") stop( "Can not find executables for concorde or linkern. Please install the executables or set path manually." ) return(p) } } else { if (!is.null(path)) { path <- normalizePath(path) ### translate all special characters ex <- c( list.files(path, pattern = "concorde", ignore.case = TRUE), list.files(path, pattern = "linkern", ignore.case = TRUE) ) if (length(ex) < 1) stop(paste("no executable (concorde and/or linkern) found in", path)) cat("found:", ex, "\n") } .path <<- path invisible(.path) } } }) ## get help page #' @rdname Concorde #' @export concorde_help <- function() { cat( "The following options can be specified in solve_TSP with method \"concorde\" using clo in control:\n\n" ) system2(.find_exe(NULL, "concorde"), args = "") } #' @rdname Concorde #' @export linkern_help <- function() { cat( "The following options can be specified in solve_TSP with method \"linkern\" using clo in control:\n\n" ) system2(.find_exe(NULL, "linkern"), args = "") } ## helper to find the 'concorde' executable .find_exe <- function(exe = NULL, prog) { ## if not specified if (is.null(exe)) { ## was the path set ? if (!is.null(concorde_path())) exe <- paste(concorde_path(), .Platform$file.sep, prog, sep = "") ## no, so it must be in the systems execution path else exe <- prog } exe } TSP/R/insert_dummy.R0000644000176200001440000001155114204063545013771 0ustar liggesusers####################################################################### # TSP - Traveling Salesperson Problem # Copyrigth (C) 2011 Michael Hahsler and Kurt Hornik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ## insert a dummy city ##generic #' Insert dummy cities into a distance matrix #' #' Inserts dummy cities into a TSP problem. A #' dummy city has the same, constant distance (0) to all other cities and is #' infinitely far from other dummy cities. A dummy city can be used to #' transform a shortest Hamiltonian path problem (i.e., finding an optimal #' linear order) into a shortest Hamiltonian cycle problem which can be solved #' by a TSP solvers (Garfinkel 1985). #' #' Several dummy cities can be used together with a TSP solvers to perform #' rearrangement clustering (Climer and Zhang 2006). #' #' The dummy cities are inserted after the other cities in `x`. #' #' A `const` of 0 is guaranteed to work if the TSP finds the optimal #' solution. For heuristics returning suboptimal solutions, a higher #' `const` (e.g., `2 * max(x)`) might provide better results. #' #' @family TSP #' #' @param x an object with a TSP problem. #' @param n number of dummy cities. #' @param const distance of the dummy cities to all other cities. #' @param inf distance between dummy cities. #' @param label labels for the dummy cities. If only one label is given, it is #' reused for all dummy cities. #' @returns returns an object of the same class as `x`. #' #' @author Michael Hahsler #' @references Sharlee Climer, Weixiong Zhang (2006): Rearrangement Clustering: #' Pitfalls, Remedies, and Applications, \emph{Journal of Machine Learning #' Research} \bold{7}(Jun), pp. 919--943. #' #' R.S. Garfinkel (1985): Motivation and modelling (chapter 2). In: E. L. #' Lawler, J. K. Lenstra, A.H.G. Rinnooy Kan, D. B. Shmoys (eds.) The #' traveling salesman problem - A guided tour of combinatorial optimization, #' Wiley & Sons. #' @keywords manip #' @examples #' ## Example 1: Find a short Hamiltonian path #' set.seed(1000) #' x <- data.frame(x = runif(20), y = runif(20), row.names = LETTERS[1:20]) #' #' tsp <- TSP(dist(x)) #' #' ## add a dummy city to cut the tour into a path #' tsp <- insert_dummy(tsp, label = "cut") #' tour <- solve_TSP(tsp) #' tour #' #' plot(x) #' lines(x[cut_tour(tour, cut = "cut"),]) #' #' #' ## Example 2: Rearrangement clustering of the iris dataset #' set.seed(1000) #' data("iris") #' tsp <- TSP(dist(iris[-5])) #' #' ## insert 2 dummy cities to creates 2 clusters #' tsp_dummy <- insert_dummy(tsp, n = 3, label = "boundary") #' #' ## get a solution for the TSP #' tour <- solve_TSP(tsp_dummy) #' #' ## plot the reordered distance matrix with the dummy cities as lines separating #' ## the clusters #' image(tsp_dummy, tour) #' abline(h = which(labels(tour)=="boundary"), col = "red") #' abline(v = which(labels(tour)=="boundary"), col = "red") #' #' ## plot the original data with paths connecting the points in each cluster #' plot(iris[,c(2,3)], col = iris[,5]) #' paths <- cut_tour(tour, cut = "boundary") #' for(p in paths) lines(iris[p, c(2,3)]) #' #' ## Note: The clustering is not perfect! #' @export insert_dummy <- function(x, n = 1, const = 0, inf = Inf, label = "dummy") UseMethod("insert_dummy") ## use insert dummy from ATSP #' @rdname insert_dummy #' @export insert_dummy.TSP <- function(x, n = 1, const = 0, inf = Inf, label = "dummy") { x <- insert_dummy(ATSP(x), n, const, inf, label) TSP(x) } #' @rdname insert_dummy #' @export insert_dummy.ATSP <- function(x, n = 1, const = 0, inf = Inf, label = "dummy") { method <- attr(x, "method") n <- as.integer(n) p <- n_of_cities(x) if(length(label) == 1 && n > 1) label = rep(label, n) ## add dummy rows/columns x <- cbind(x, matrix(const, ncol = n, nrow = p, dimnames = list(NULL, label))) x <- rbind(x, matrix(const, ncol = p+n, nrow = n, dimnames = list(label, NULL))) ## place inf between dummies if(n>1) { x[(p+1):(p+n), (p+1):(p+n)] <- inf diag(x[(p+1):(p+n), (p+1):(p+n)]) <- 0 } attr(x, "method") <- method ATSP(x) } #' @rdname insert_dummy #' @export insert_dummy.ETSP <- function(x, n = 1, const = 0, inf = Inf, label = "dummy") stop("Dummy cities cannot be used with ETSP! Convert the problem into a TSP.") TSP/R/TSPLIB.R0000644000176200001440000002373514204063370012252 0ustar liggesusers####################################################################### # TSP - Traveling Salesperson Problem # Copyrigth (C) 2011 Michael Hahsler and Kurt Hornik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #' Read and write TSPLIB files #' #' Reads and writes TSPLIB format files. TSPLIB files can be used by most TSP #' solvers. Sample instances for the TSP in TSPLIB format are available on the #' TSPLIB homepage (see references). #' #' In the TSPLIB format distances are represented by integer values. Therefore, #' if `x` contains `double` values (which is normal in R) the values #' given in `x` are multiplied by \eqn{10^{precision}} before coercion to #' `integer`. Note that therefore all results produced by programs using #' the TSPLIB file as input need to be divided by \eqn{10^{precision}} (i.e., #' the decimal point has to be shifted `precision` placed to the left). #' #' Currently only the following `EDGE_WEIGHT_TYPE`s are implemented: #' `EXPLICIT`, `EUC_2D` and `EUC_3D`. #' #' @name TSPLIB #' @aliases TSPLIB #' @family TSP #' #' @param x an object with a TSP problem. #' `NA`s are not allowed. #' @param file file name or a [connection]. #' @param precision controls the number of decimal places used to represent #' distances (see details). If `x` already is `integer`, this #' argument is ignored and `x` is used as is. #' @param inf replacement value for `Inf` (TSPLIB format cannot handle #' `Inf`). If `inf` is `NULL`, a large value of \eqn{max(x) + 2 #' range(x)} (ignoring infinite entries) is used. #' @param neg_inf replacement value for `-Inf`. If no value is specified, #' a small value of \eqn{min(x) - 2 range(x)} (ignoring infinite entries) is #' used. #' @returns returns an object of class `TSP` or #' `ATSP`. #' @author Michael Hahsler #' @references TSPLIB home page, #' \url{http://comopt.ifi.uni-heidelberg.de/software/TSPLIB95/} #' @keywords file #' @examples #' #' ## Drilling problem from TSP #' drill <- read_TSPLIB(system.file("examples/d493.tsp", package = "TSP")) #' drill #' tour <- solve_TSP(drill, method = "nn", two_opt = TRUE) #' tour #' plot(drill, tour, cex=.6, col = "red", pch= 3, main = "TSPLIB: d493") #' #' #' ## Write and read data in TSPLIB format #' x <- data.frame(x=runif(5), y=runif(5)) #' #' ## create TSP, ATSP and ETSP (2D) #' tsp <- TSP(dist(x)) #' atsp <- ATSP(dist(x)) #' etsp <- ETSP(x[,1:2]) #' #' write_TSPLIB(tsp, file="example.tsp") #' #file.show("example.tsp") #' r <- read_TSPLIB("example.tsp") #' r #' #' write_TSPLIB(atsp, file="example.tsp") #' #file.show("example.tsp") #' r <- read_TSPLIB("example.tsp") #' r #' #' write_TSPLIB(etsp, file="example.tsp") #' #file.show("example.tsp") #' r <- read_TSPLIB("example.tsp") #' r #' #' ## clean up #' unlink("example.tsp") #' @export read_TSPLIB <- function(file, precision = 0) { ## TSP or ATSP type <- NULL lines <- readLines(file) ## get info metadata <- grep(":", lines) info <- list() lapply(strsplit(lines[metadata], "[[:space:]]*:[[:space:]]*"), FUN = function(x) { x[2] <- sub("[[:space:]]*$","",x[2]) ## kill trailing spaces info[[toupper(x[1])]] <<- toupper(x[2]) }) ## check if(substr(info$TYPE, 1, 3) == "TSP") type <- "TSP" else if(substr(info$TYPE, 1, 3) == "ATS") type <- "ATSP" else stop ("Currently the only implemented TYPEs are TSP and ATS(P)!") dim <- as.integer(info$DIMENSION) if(info$EDGE_WEIGHT_TYPE == "EXPLICIT") { ## get data data_start <- grep("EDGE_WEIGHT_SECTION", lines, ignore.case = TRUE) if(length(data_start) == 0) stop("EDGE_WEIGHT_SECTION missing") data <- lines[(data_start+1):length(lines)] data <- sub("EOF", "", data, ignore.case = TRUE) ## kill optional EOF data <- sub("^[[:space:]]*", "", data)## kill leading spaces data <- strsplit(paste(data, collapse = " "), "[[:space:]]+")[[1]] ## remove everything after the data if(info$EDGE_WEIGHT_FORMAT == "FULL_MATRIX") data <- data[1:(dim^2)] else if(info$EDGE_WEIGHT_FORMAT == "UPPER_ROW" || info$EDGE_WEIGHT_FORMAT == "LOWER_COL" || info$EDGE_WEIGHT_FORMAT == "UPPER_COL" || info$EDGE_WEIGHT_FORMAT == "LOWER_ROW") data <- data[1:(dim*(dim-1)/2)] else if(info$EDGE_WEIGHT_FORMAT == "UPPER_DIAG_ROW" || info$EDGE_WEIGHT_FORMAT == "LOWER_DIAG_COL" || info$EDGE_WEIGHT_FORMAT == "UPPER_DIAG_COL" || info$EDGE_WEIGHT_FORMAT == "LOWER_DIAG_ROW") data <- data[1:(dim*(dim-1)/2 + dim)] data <- as.numeric(data) if(precision != 0) data <- data / 10^precision ## ATSP if(type == "ATSP") { if(info$EDGE_WEIGHT_FORMAT == "FULL_MATRIX"){ ## todo: find out if FULL_MATRIX is row or column oriented? data <- matrix(data, ncol = dim) }else stop("ATSP needs EDGE_WEIGHT_FORMAT FULL_MATRIX!") return(ATSP(data)) } ## TSP ## we have only symmetric data here! if(info$EDGE_WEIGHT_FORMAT == "FULL_MATRIX") { data <- as.dist(matrix(data, ncol = dim)) }else if(info$EDGE_WEIGHT_FORMAT == "UPPER_ROW" || info$EDGE_WEIGHT_FORMAT == "LOWER_COL") { class(data) <- "dist" attr(data, "Size") <- dim attr(data, "Diag") <- FALSE attr(data, "Upper") <- FALSE }else if(info$EDGE_WEIGHT_FORMAT == "UPPER_COL" || info$EDGE_WEIGHT_FORMAT == "LOWER_ROW") { m <- matrix(NA, nrow = dim, ncol = dim) m[upper.tri(m, diag = FALSE)] <- data data <- as.dist(t(m)) }else if(info$EDGE_WEIGHT_FORMAT == "UPPER_DIAG_ROW" || info$EDGE_WEIGHT_FORMAT == "LOWER_DIAG_COL") { class(data) <- "dist" attr(data, "Size") <- dim attr(data, "Diag") <- TRUE attr(data, "Upper") <- FALSE data <- as.dist(data, diag = FALSE) }else if(info$EDGE_WEIGHT_FORMAT == "UPPER_DIAG_COL" || info$EDGE_WEIGHT_FORMAT == "LOWER_DIAG_ROW") { m <- matrix(NA, nrow = dim, ncol = dim) m[upper.tri(m, diag = TRUE)] <- data data <- as.dist(t(m)) }else stop("The specified EDGE_WEIGHT_FORMAT is not implemented!") return(TSP(data)) } else if (info$EDGE_WEIGHT_TYPE == "EUC_2D" || info$EDGE_WEIGHT_TYPE == "EUC_2D") { data_start <- grep("NODE_COORD_SECTION", lines, ignore.case = TRUE) if(length(data_start) == 0) stop("NODE_COORD_SECTION missing") data <- lines[(data_start+1):(data_start+dim)] data <- matrix(as.numeric(unlist(strsplit(data, split="\\s+"))), nrow = dim, byrow = TRUE) data <- data[,-1] return(ETSP(data)) } stop("EDGE_WEIGHT_TYPE not implemented! Implemented types are EXPLICIT, EUC_2D and EUC_3D") } #' @rdname TSPLIB #' @export write_TSPLIB <- function(x, file, precision = 6, inf = NULL, neg_inf = NULL) UseMethod("write_TSPLIB") ## write a simple TSPLIB format file from an object of class TSP ## (contains a dist object or a symmetric matrix) ## TSP has data as integer #' @rdname TSPLIB #' @export write_TSPLIB.TSP <- function(x, file, precision = 6, inf = NULL, neg_inf = NULL) { ## prepare data (NA, Inf) if(any(is.na(x))) stop("NAs not allowed!") x <- .replaceInf(x, inf, neg_inf) ## Concorde can handle UPPER_ROW and dist (lower triangle matrix) ## is symmetric. format <- "EDGE_WEIGHT_FORMAT: UPPER_ROW" zz <- file(file, "w") cat("NAME: TSP", "COMMENT: Generated by write_TSPLIB (R-package TSP)", "TYPE: TSP", paste("DIMENSION:", n_of_cities(x)), "EDGE_WEIGHT_TYPE: EXPLICIT", format, file = zz, sep = "\n") ## only integers can be used as weights if(storage.mode(x) != "integer" && precision != 0) x <- x * 10^precision x <- suppressWarnings(as.integer(x)) if(any(is.na(x))) stop("Integer overflow, please reduce precision.") cat("EDGE_WEIGHT_SECTION", x, file = zz, sep = "\n") cat("EOF", file = zz, sep = "\n") close(zz) } #' @rdname TSPLIB #' @export write_TSPLIB.ATSP <- function(x, file, precision = 6, inf = NULL, neg_inf = NULL) { ## prepare data (NA, Inf) if(any(is.na(x))) stop("NAs not allowed!") x <- .replaceInf(x, inf, neg_inf) format <- "EDGE_WEIGHT_FORMAT: FULL_MATRIX" zz <- file(file, "w") cat("NAME: ATSP", "COMMENT: Generated by write_TSPLIB (R package TSP)", "TYPE: ATSP", paste("DIMENSION:", n_of_cities(x)), "EDGE_WEIGHT_TYPE: EXPLICIT", format, file = zz, sep = "\n") ## only integers can be used as weights if(storage.mode(x) != "integer") x <- x * 10^precision x <- suppressWarnings(as.integer(x)) if(any(is.na(x))) stop("integer overflow, please reduce precision.") cat("EDGE_WEIGHT_SECTION", x, file = zz, sep = "\n") cat("EOF", file = zz, sep = "\n") close(zz) } ## ETSP use data as real #' @rdname TSPLIB #' @export write_TSPLIB.ETSP <- function(x, file, precision = 6, inf = NULL, neg_inf = NULL) { if(any(is.na(x))) stop("NAs are not allowed!") if(any(!is.finite(x))) stop("Only finite values allowed!") if(ncol(x) == 2) type <- "EUC_2D" else if(ncol(x) == 3) type <- "EUC_3D" else stop("Only EUC_2D and EUC_3D supported.") zz <- file(file, "w") cat("NAME: ETSP", "COMMENT: Generated by write_TSPLIB (R package TSP)", "TYPE: TSP", paste("DIMENSION:", n_of_cities(x)), paste("EDGE_WEIGHT_TYPE:", type), file = zz, sep = "\n") ## fix row names rownames(x) <- NULL x <- do.call(data.frame, lapply(1:ncol(x), FUN = function(i) sprintf(paste("%0.", precision, "e", sep=""), x[,i]))) cat("NODE_COORD_SECTION", file = zz, sep = "\n") write.table(x, quote=FALSE, col.names = FALSE, file = zz) cat("EOF", file = zz, sep = "\n") close(zz) } TSP/R/tour_length.R0000644000176200001440000000614114402141504013573 0ustar liggesusers####################################################################### # TSP - Traveling Salesperson Problem # Copyrigth (C) 2011 Michael Hahsler and Kurt Hornik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #' Calculate the length of a tour #' #' Calculate the length of a [TOUR] for a [TSP]. #' #' If no `tsp` is specified, then the tour length stored in `x` as #' attribute `"tour_length"` is returned. If `tsp` is given then the #' tour length is recalculated using the specified TSP problem. #' #' If a distance in the tour is infinite, the result is also infinite. If the #' tour contains positive and negative infinite distances then the method #' returns `NA`. #' #' @family TOUR #' #' @param x a TSP problem or a [TOUR]. #' @param order an object of class `TOUR` #' @param tsp as TSP object. #' @param ... further arguments are currently unused. #' @author Michael Hahsler #' @keywords optimize #' @examples #' #' data("USCA50") #' #' ## original order #' tour_length(solve_TSP(USCA50, method="identity")) #' #' ## length of a manually created (random) tour #' tour <- TOUR(sample(seq(n_of_cities(USCA50)))) #' tour #' tour_length(tour) #' tour_length(tour, USCA50) #' @export tour_length <- function(x, ...) UseMethod("tour_length") #' @rdname tour_length #' @export tour_length.TSP <- function(x, order, ...) { n <- n_of_cities(x) if (missing(order)) order <- 1:n .Call(R_tour_length_dist, x, order) } #' @rdname tour_length #' @export tour_length.ATSP <- function(x, order, ...) { n <- n_of_cities(x) if (missing(order)) order <- 1:n .Call(R_tour_length_matrix, x, order) } ### faster for small n but takes O(n^2) memory #tour_length.ETSP <- function(x, order) tour_length(as.TSP(x), order) #' @rdname tour_length #' @export tour_length.ETSP <- function(x, order, ...) { n <- n_of_cities(x) if (n != nrow(x)) stop("x and order do not have the same number of cities!") if (missing(order)) order <- 1:n as.numeric(sum(sapply( 1:(n - 1), FUN = function(i) dist(x[order[c(i, i + 1)], , drop = FALSE]) )) + dist(x[order[c(n, 1)], , drop = FALSE])) } #' @rdname tour_length #' @export tour_length.TOUR <- function(x, tsp = NULL, ...) { if (is.null(tsp)) { len <- attr(x, "tour_length") if (is.null(len)) len <- NA return(len) } tour_length(x = tsp, order = x) } #' @rdname tour_length #' @export tour_length.integer <- function(x, tsp = NULL, ...) { if (is.null(tsp)) return(NA) tour_length(x = tsp, order = x) } TSP/R/tsp_insertion.R0000644000176200001440000001045714205203457014155 0ustar liggesusers####################################################################### # TSP - Traveling Salesperson Problem # Copyrigth (C) 2011 Michael Hahsler and Kurt Hornik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ## Insertion algorithms ## (Rosenkrantz et al. 1977) tsp_insertion <- function(x, type = "nearest", control = NULL){ ## since sample has an annoying convenience feature for ## lenght(x) == 1 choose1 <- function(x) if(length(x) > 1) sample(x, 1) else x ## this is slower than which.min and which.max but works also ## correctly for only values Inf in x and breaks ties randomly choose1_min <- function(x) choose1(which(x == min(x))) choose1_max <- function(x) choose1(which(x == max(x))) types <- c("nearest", "farthest", "cheapest", "arbitrary") type_num <- pmatch(type, types) if(is.na(type_num)) stop(paste("Unknown insertion type: ", sQuote(type))) ## x comes checked form solve_TSP/solve_ATSP n <- n_of_cities(x) ## we use a matrix for now (covers TSP and ATSP) asym <- inherits(x, "ATSP") x <- as.matrix(x) ## place first city control <- .get_parameters(control, list( start = sample(n, 1) ), method = paste0(types[type_num], "_insertion")) start <- as.integer(control$start) if(start < 0 || start > n) stop(paste("illegal value for", sQuote("start"))) placed <- logical(n) placed[start] <- TRUE order <- c(start) ## place other cities while(any(placed == FALSE)) { ## find city to be inserted ks <- which(!placed) js <- which(placed) ## nearest / farthest if(type_num < 3) { m <- x[ks,js, drop = FALSE] ## for the asymmetric case we have to take distances ## from and to the city into account if(asym){ m <- cbind(m, t(x)[ks,js, drop = FALSE]) } ds <- sapply(1:length(ks), FUN = function(i) min(m[i, , drop = FALSE])) ## nearest/farthest insertion winner_index <- if(type_num == 1) choose1_min(ds) else choose1_max(ds) k <- ks[winner_index] } ## cheapest else if(type_num == 3) { winner_index <- choose1_min(sapply(ks, FUN = function(k) min(.Call(R_insertion_cost, x, order, k)) )) k <- ks[winner_index] ## we look for the optimal insertion place for k again later ## this is not necessary, but it is more convenient ## to reuse the code for the other insertion algorithms for now. } ## random else if(type_num == 4) k <- choose1(ks) ## just in case else stop("unknown insertion type") ## do insertion placed[k] <- TRUE if(length(order) == 1) order <- append(order, k) else { pos <- choose1_min(.Call(R_insertion_cost, x, order, k)) order <- append(order, k, after = pos) } } if (control$verbose) cat("All cities placed.\n\n") order } ### faster arbitrary insertion (random sampling takes care of breaking ties) tsp_insertion_arbitrary <- function(x, control = NULL){ ## x comes checked form solve_TSP/solve_ATSP n <- n_of_cities(x) control <- .get_parameters(control, list(), method = "arbitrary_insertion") ## we use a matrix for now (covers TSP and ATSP) x <- as.matrix(x) ## deal with special cases if(nrow(x) == 1) return(1L) if(nrow(x) == 2) return(sample(1:2)) x[is.na(x)] <- Inf ## random order rorder <- sample(n) x <- x[rorder, rorder] ## FIXME: specify start city ## place first two cities order <- integer(n) order[1:2] <- 1:2 ## place other cities for(i in 3:n) { pos <- which.min(.Call(R_insertion_cost, x, order[1:(i-1L)], i)) + 1L order[((pos):i)+1L] <- order[(pos):i] order[pos] <- i } if (control$verbose) cat("All cities placed.\n\n") rorder[order] } TSP/R/solve_TSP.R0000644000176200001440000003561614363767667013166 0ustar liggesusers####################################################################### # TSP - Traveling Salesperson Problem # Copyrigth (C) 2011 Michael Hahsler and Kurt Hornik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #' TSP solver interface #' #' Common interface to all TSP solvers in this package. #' #' **TSP Methods** #' #' Currently the following methods are available: #' - "identity", "random" return a tour representing the order in the data #' (identity order) or a random order. \[TSP, ATSP\] #' #' - "nearest_insertion", "farthest_insertion", "cheapest_insertion", "arbitrary_insertion" #' Nearest, farthest, cheapest and #' arbitrary insertion algorithms for a symmetric and asymmetric TSP #' (Rosenkrantz et al. 1977). \[TSP, ATSP\] #' #' The distances between cities are stored in a distance matrix \eqn{D} with #' elements \eqn{d(i,j)}. All insertion algorithms start with a tour #' consisting of an arbitrary city and choose in each step a city \eqn{k} not #' yet on the tour. This city is inserted into the existing tour between two #' consecutive cities \eqn{i} and \eqn{j}, such that \deqn{d(i,k) + d(k,j) - #' d(i,j)} is minimized. The algorithms stops when all cities are on the tour. #' #' The nearest insertion algorithm chooses city \eqn{k} in each step as the #' city which is \emph{nearest} to a city on the tour. #' #' For farthest insertion, the city \eqn{k} is chosen in each step as the city #' which is \emph{farthest} to any city on the tour. #' #' Cheapest insertion chooses the city \eqn{k} such that the cost of inserting #' the new city (i.e., the increase in the tour's length) is minimal. #' #' Arbitrary insertion chooses the city \eqn{k} randomly from all cities not #' yet on the tour. #' #' Nearest and cheapest insertion tries to build the tour using cities which #' fit well into the partial tour constructed so far. The idea behind behind #' farthest insertion is to link cities far away into the tour fist to #' establish an outline of the whole tour early. #' #' Additional control options: #' - "start" index of the first city (default: a random city). #' #' - "nn", "repetitive_nn" Nearest neighbor and repetitive #' nearest neighbor algorithms for symmetric and asymmetric TSPs (Rosenkrantz #' et al. 1977). \[TSP, ATSP\] #' #' The algorithm starts with a tour containing a random city. Then the #' algorithm always adds to the last city on the tour the nearest not yet #' visited city. The algorithm stops when all cities are on the tour. #' #' Repetitive nearest neighbor constructs a nearest neighbor tour for each city #' as the starting point and returns the shortest tour found. #' #' Additional control options: #' - "start" index of the first city (default: a random city). #' #' - "two_opt" Two edge exchange improvement procedure (Croes 1958). \[TSP, ATSP\] #' #' This is a tour refinement procedure which systematically exchanges two edges #' in the graph represented by the distance matrix till no improvements are #' possible. Exchanging two edges is equal to reversing part of the tour. The #' resulting tour is called _2-optimal._ #' #' This method can be applied to tours created by other methods or used as its #' own method. In this case improvement starts with a random tour. #' #' Additional control options: #' - "tour" an existing tour which should be improved. #' If no tour is given, a random tour is used. #' - "two_opt_repetitions" number of times to try two_opt with a #' different initial random tour (default: 1). #' #' - "concorde" Concorde algorithm (Applegate et al. 2001). \[TSP, ETSP\] #' #' Concorde is an advanced exact TSP solver for _symmetric_ TSPs #' based on branch-and-cut. #' ATSPs can be solved using [reformulate_ATSP_as_TSP()] done automatically #' with `as_TSP = TRUE`. #' The program is not included in this package and #' has to be obtained and installed separately. #' #' Additional control options: #' - "exe" a character string containing the path to the executable (see [Concorde]). #' - "clo" a character string containing command line options for #' Concorde, e.g., `control = list(clo = "-B -v")`. See #' [concorde_help()] on how to obtain a complete list of available command #' line options. #' - "precision" an integer which controls the number of decimal #' places used for the internal representation of distances in Concorde. The #' values given in `x` are multiplied by \eqn{10^{precision}} before being #' passed on to Concorde. Note that therefore the results produced by Concorde #' (especially lower and upper bounds) need to be divided by #' \eqn{10^{precision}} (i.e., the decimal point has to be shifted #' `precision` placed to the left). The interface to Concorde uses #' [write_TSPLIB()]. #' #' - "linkern" Concorde's Chained Lin-Kernighan heuristic (Applegate et al. 2003). \[TSP, ETSP\] #' #' The Lin-Kernighan (Lin and Kernighan 1973) heuristic uses variable \eqn{k} #' edge exchanges to improve an initial tour. The program is not included in #' this package and has to be obtained and installed separately (see [Concorde]). #' #' Additional control options: see Concorde above. #' #' **Treatment of `NA`s and infinite values in `x`** #' #' [TSP] and [ATSP] need to contain valid distances. `NA`s are not allowed. `Inf` is #' allowed and can be used to model the missing edges in incomplete graphs #' (i.e., the distance between the two objects is infinite) or unfeasable connections. #' Internally, `Inf` is replaced by a large value given by \eqn{max(x) + 2 range(x)}. #' Note that the solution might still place the two objects next to each other #' (e.g., if `x` contains several unconnected subgraphs) which results in #' a path length of `Inf`. `-Inf` is replaced by \eqn{min(x) - 2 range(x)} and #' can be used to encourage the solver to place two objects next to each other. #' #' **Parallel execution support** #' #' All heuristics can be used with the control arguments `repetitions` #' (uses the best from that many repetitions with random starts) and #' `two_opt` (a logical indicating if two_opt refinement should be #' performed). If several repetitions are done (this includes method #' `"repetitive_nn"`) then \pkg{foreach} is used so they can be performed #' in parallel on multiple cores/machines. To enable parallel execution an #' appropriate parallel backend needs to be registered (e.g., load #' \pkg{doParallel} and register it with [doParallel::registerDoParallel()]). #' #' **Solving ATSP and ETSP** #' #' Some solvers (including Concorde) cannot directly solve [ATSP] #' directly. `ATSP` can be reformulated as larger `TSP` and solved #' this way. For convenience, `solve_TSP()` has an extra argument #' `as_TSP` which can be set to `TRUE` to automatically solve the #' `ATSP` reformulated as a `TSP` (see [reformulate_ATSP_as_TSP()]). #' #' Only methods "concorde" and "linkern" can solve [ETSP]s directly. #' For all other methods, ETSPs are currently converted into TSPs by creating a #' distance matrix and then solved. #' #' @family TSP #' @family TOUR #' #' @param x a TSP problem. #' @param method method to solve the TSP (default: "arbitrary insertion" #' algorithm with two_opt refinement. #' @param control a list of arguments passed on to the TSP solver selected by #' `method`. #' @param as_TSP should the ATSP reformulated as a TSP for the solver? #' @param ... additional arguments are added to `control`. #' @return An object of class [TOUR]. #' @author Michael Hahsler #' @references #' David Applegate, Robert Bixby, Vasek Chvatal, William Cook #' (2001): TSP cuts which do not conform to the template paradigm, #' Computational Combinatorial Optimization, M. Junger and D. Naddef (editors), #' Springer. #' #' D. Applegate, W. Cook and A. Rohe (2003): Chained Lin-Kernighan for Large #' Traveling Salesman Problems. \emph{INFORMS Journal on Computing, #' 15(1):82--92.} #' #' G.A. Croes (1958): A method for solving traveling-salesman problems. #' \emph{Operations Research, 6(6):791--812.} #' #' S. Lin and B. Kernighan (1973): An effective heuristic algorithm for the #' traveling-salesman problem. \emph{Operations Research, 21(2): 498--516.} #' #' D.J. Rosenkrantz, R. E. Stearns, and Philip M. Lewis II (1977): An analysis #' of several heuristics for the traveling salesman problem. \emph{SIAM #' Journal on Computing, 6(3):563--581.} #' @keywords optimize #' @examples #' #' ## solve a simple Euclidean TSP (using the default method) #' etsp <- ETSP(data.frame(x = runif(20), y = runif(20))) #' tour <- solve_TSP(etsp) #' tour #' tour_length(tour) #' plot(etsp, tour) #' #' #' ## compare methods #' data("USCA50") #' USCA50 #' methods <- c("identity", "random", "nearest_insertion", #' "cheapest_insertion", "farthest_insertion", "arbitrary_insertion", #' "nn", "repetitive_nn", "two_opt") #' #' ## calculate tours #' tours <- lapply(methods, FUN = function(m) solve_TSP(USCA50, method = m)) #' names(tours) <- methods #' #' ## use the external solver which has to be installed separately #' \dontrun{ #' tours$concorde <- solve_TSP(USCA50, method = "concorde") #' tours$linkern <- solve_TSP(USCA50, method = "linkern") #' } #' #' ## register a parallel backend to perform repetitions in parallel #' \dontrun{ #' library(doParallel) #' registerDoParallel() #' } #' #' ## add some tours using repetition and two_opt refinements #' tours$'nn+two_opt' <- solve_TSP(USCA50, method = "nn", two_opt = TRUE) #' tours$'nn+rep_10' <- solve_TSP(USCA50, method = "nn", rep = 10) #' tours$'nn+two_opt+rep_10' <- solve_TSP(USCA50, method = "nn", two_opt = TRUE, rep = 10) #' tours$'arbitrary_insertion+two_opt' <- solve_TSP(USCA50) #' #' ## show first tour #' tours[[1]] #' #' ## compare tour lengths #' opt <- 14497 # obtained by Concorde #' tour_lengths <- c(sort(sapply(tours, tour_length), decreasing = TRUE), #' optimal = opt) #' dotchart(tour_lengths / opt * 100 - 100, xlab = "percent excess over optimum") #' @export solve_TSP <- function(x, method = NULL, control = NULL, ...) UseMethod("solve_TSP") ## TSP #' @rdname solve_TSP #' @export solve_TSP.TSP <- function(x, method = NULL, control = NULL, ...) { .solve_TSP(x, method, control, ...) } ## ATSP #' @rdname solve_TSP #' @export solve_TSP.ATSP <- function(x, method = NULL, control = NULL, as_TSP = FALSE, ...) { # force as_TSP for solvers that cannot deal with ATSPs m <- pmatch(tolower(method), c("concorde", "linkern")) if (!is.na(m) && length(m) > 0L && !as_TSP) { warning( "NOTE: Solver cannot solve the ATSP directly. Reformulating ATSP as TSP. Use 'as_TSP = TRUE' to supress this warning.\n" ) as_TSP <- TRUE } # reformulate ATSP as TSP if (as_TSP) { x_atsp <- x x <- reformulate_ATSP_as_TSP(x_atsp) } tour <- .solve_TSP(x, method, control, ...) if (as_TSP) tour <- filter_ATSP_as_TSP_dummies(tour, atsp = x_atsp) tour } ## ETSP #' @rdname solve_TSP #' @export solve_TSP.ETSP <- function(x, method = NULL, control = NULL, ...) { ## all but concorde and linkern can only do TSP m <- pmatch(tolower(method), c("concorde", "linkern")) if (length(m) == 0L || is.na(m)) x <- as.TSP(x) .solve_TSP(x, method, control, ...) } ## Deal with Inf: punish (-)Inf with max (min) +(-) 2*range .replaceInf <- function(x, pInf = NULL, nInf = NULL) { if (any(is.infinite(x))) { range_x <- range(x, na.rm = TRUE, finite = TRUE) # data with only a single non-inf value. diff_range <- diff(range_x) if (diff_range == 0) { if (range_x[1] == 0) diff_range <- 1 else diff_range <- range_x[1] * 2 } if (is.null(pInf)) pInf <- range_x[2] + 2 * diff_range if (is.null(nInf)) nInf <- range_x[1] - 2 * diff_range x[x == Inf] <- pInf x[x == -Inf] <- nInf } x } ## workhorse .solve_TSP <- function(x, method = NULL, control = NULL, ...) { ## add ... to control control <- c(control, list(...)) ## methods methods <- c( "identity", "random", "nearest_insertion", "farthest_insertion", "cheapest_insertion", "arbitrary_insertion", "nn", "repetitive_nn", ### deprecate use two_opt "2-opt", "two_opt", "concorde", "linkern" ) ## default is arbitrary_insertion + two_opt if (is.null(method)) { method <- "arbitrary_insertion" if (is.null(control[["two_opt"]])) control <- c(control, list(two_opt = TRUE)) } else method <- match.arg(tolower(method), methods) ## check for NAs if (any(is.na(x))) stop("NAs not allowed!") ## Inf x_ <- .replaceInf(x) ## work horses .solve_TSP_worker <- function(x_, method, control) { order <- switch( method, identity = seq(n_of_cities(x_)), random = sample(n_of_cities(x_)), nearest_insertion = tsp_insertion(x_, type = "nearest", control = control), farthest_insertion = tsp_insertion(x_, type = "farthest", control = control), cheapest_insertion = tsp_insertion(x_, type = "cheapest", control = control), # arbitrary_insertion = tsp_insertion(x_, type = "arbitrary", control = control), arbitrary_insertion = tsp_insertion_arbitrary(x_, control = control), nn = tsp_nn(x_, control = control), repetitive_nn = tsp_repetitive_nn(x_, control = control), two_opt = tsp_two_opt(x_, control = control), '2-opt' = tsp_two_opt(x_, control = control), concorde = tsp_concorde(x_, control = control), linkern = tsp_linkern(x_, control = control) ) ### do refinement two_opt if (!is.null(control[["two_opt"]]) && control[["two_opt"]]) { order <- tsp_two_opt(x_, control = c(control, list(tour = order))) method <- paste(method , "+two_opt", sep = "") } TOUR(order, method = method, tsp = x) } ## do rep? if (!is.null(control$rep)) n <- control$rep else n <- 1L ## no rep or two_opt for these! if (method == "concorde" || method == "linkern") { n <- 1L control$two_opt <- NULL } ## no rep! if (method == "repetitive_nn") n <- 1L if (n == 1L) return(.solve_TSP_worker(x_, method, control)) #l <- replicate(n, .solve_TSP_worker(x_, method, control), simplify = FALSE) l <- foreach(i = 1:n) %dopar% .solve_TSP_worker(x_, method, control) l <- l[[which.min(sapply(l, attr, "tour_length"))]] attr(l, "method") <- paste(attr(l, "method"), "_rep_", n, sep = "") return(l) } TSP/R/AAA_TSP-package.R0000644000176200001440000000211514260640415013746 0ustar liggesusers#' @title `r packageDescription("TSP")$Package`: `r packageDescription("TSP")$Title` #' #' @description Basic infrastructure and some algorithms for the traveling salesperson problem (also traveling salesman problem; TSP). The package provides some simple algorithms and an interface to the Concorde TSP solver and its implementation of the Chained-Lin-Kernighan heuristic. The code for [Concorde](https://www.math.uwaterloo.ca/tsp/concorde/) itself is not included in the package and has to be obtained separately. #' #' @references Michael Hahsler and Kurt Hornik. TSP -- Infrastructure for the traveling salesperson problem. Journal of Statistical Software, 23(2):1--21, December 2007. \doi{10.18637/jss.v023.i02} #' #' @section Key functions: #' - [solve_TSP()] #' #' @author Michael Hahsler #' @docType package #' @name TSP-package #' #' @importFrom stats as.dist dist #' @importFrom utils read.table write.table head tail #' @importFrom grDevices gray.colors #' @importFrom graphics image.default plot polygon #' @importFrom foreach foreach "%dopar%" #' @useDynLib TSP, .registration=TRUE NULL TSP/R/ETSP.R0000644000176200001440000000760014402152761012024 0ustar liggesusers####################################################################### # TSP - Traveling Salesperson Problem # Copyrigth (C) 2011 Michael Hahsler and Kurt Hornik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #' Class ETSP -- Euclidean traveling salesperson problem #' #' Constructor to create an instance of a Euclidean traveling salesperson #' problem (TSP) represented by city coordinates and some auxiliary methods. #' #' Objects of class `ETSP` are internally represented as a `matrix` #' objects (use `as.matrix()` to get the `matrix` object). #' #' @family TSP #' #' @param x,object an object (data.frame or matrix) to be converted into a #' `ETSP` or, for the methods, an object of class `ETSP`. #' @param labels optional city labels. If not given, labels are taken from #' `x`. #' @param col color scheme for image. #' @param order order of cities for the image as an integer vector or an object #' of class [TOUR]. #' @param tour,y a tour to be visualized. #' @param tour_lty,tour_col line type and color for tour. #' @param labels logical; plot city labels. #' @param ... further arguments are passed on. #' @returns #' - `ETSP()` returns `x` as an object of class `ETSP`. #' - `n_of_cities()` returns the number of cities in `x`. #' - `labels()` returns a vector with the names of the cities in `x`. #' @author Michael Hahsler #' @keywords classes #' @examples #' ## create a random ETSP #' n <- 20 #' x <- data.frame(x = runif(n), y = runif(n), row.names = LETTERS[1:n]) #' etsp <- ETSP(x) #' etsp #' #' ## use some methods #' n_of_cities(etsp) #' labels(etsp) #' #' ## plot ETSP and solution #' tour <- solve_TSP(etsp) #' tour #' #' plot(etsp, tour, tour_col = "red") #' @export ETSP <- function(x, labels = NULL) { if(inherits(x, "ETSP")) return(x) x <- as.ETSP(x) if(!is.null(labels)) rownames(x) <- labels x } ## coercion #' @rdname ETSP #' @export as.ETSP <- function(x) UseMethod("as.ETSP") #' @rdname ETSP #' @export as.ETSP.matrix <- function(x){ mode(x) <- "numeric" if(is.null(rownames(x))) rownames(x) <- 1:nrow(x) class(x) <- c("ETSP", class(x)) x } #' @rdname ETSP #' @export as.ETSP.data.frame <- function(x){ as.ETSP(as.matrix(x)) } #' @rdname ETSP #' @export as.TSP.ETSP <- function(x) TSP(dist(x)) #' @rdname ETSP #' @export as.matrix.ETSP <- function(x, ...) { unclass(x) } ## print #' @rdname ETSP #' @export print.ETSP <- function(x, ...) { cat("object of class", sQuote(class(x)[1]), "\n") cat(n_of_cities(x), "cities", "(Euclidean TSP)\n") } ## number of cities #' @rdname ETSP #' @export n_of_cities.ETSP <- function(x) nrow(x) ## labels #' @rdname ETSP #' @export labels.ETSP <- function(object, ...) rownames(object) ## image #' @rdname ETSP #' @export image.ETSP <- function(x, order, col = gray.colors(64), ...) { p <- n_of_cities(x) if(missing(order)) order <- 1:p x <- as.TSP(x) graphics::image.default(1:p, 1:p, as.matrix(x)[order, order], col = col, ...) } #' @rdname ETSP #' @importFrom graphics text #' @export plot.ETSP <- function(x, y = NULL, tour = NULL, tour_lty = 2, tour_col = 2, labels = TRUE, ...) { x <- as.matrix(x) plot(x, y = NULL, ...) if(!is.null(y)) tour <- TOUR(y) if(!is.null(tour)) polygon(x[tour,], lty = tour_lty, border = tour_col) if(labels) text(x, y = NULL, labels = rownames(x), pos = 3) } TSP/R/AAA_parameter.R0000644000176200001440000000414014205203150013655 0ustar liggesusers####################################################################### # Code to check parameter/control objects # Copyrigth (C) 2011-2016 Michael Hahsler # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ## helper to parse parameter lists with defaults .nodots <- function(...) { l <- list(...) if(length(l) > 0L) warning("Unknown arguments: ", paste(names(l), "=",l, collapse=", ")) } .get_parameters <- function(parameter, defaults, method = NA) { defaults <- as.list(defaults) parameter <- as.list(parameter) ## add verbose if(is.null(defaults$verbose)) defaults$verbose <- FALSE if(length(parameter) != 0) { o <- pmatch(names(parameter), names(defaults)) ## unknown parameter # if(any(is.na(o))){ # warning(sprintf(ngettext(length(is.na(o)), # "Unknown parameter: %s", # "Unknown parameters: %s"), # paste(names(parameter)[is.na(o)], # collapse = ", ")), call. = FALSE, immediate. = TRUE) # # cat("Available parameter (with default values):\n") # #print(defaults) # cat(rbind(names(defaults)," = ", gsub("\n"," ",as.character(defaults))), # sep=c("\t"," ","\n")) # } defaults[o[!is.na(o)]] <- parameter[!is.na(o)] } if(defaults$verbose) { cat("Used control parameters by", sQuote(method), "\n") #print(defaults) cat(rbind(names(defaults)," = ", strtrim(gsub("\n"," ",as.character(defaults)), 50)), sep=c("\t"," ","\n")) cat("\n") } defaults } TSP/R/TOUR.R0000644000176200001440000000715414260637710012052 0ustar liggesusers####################################################################### # TSP - Traveling Salesperson Problem # Copyrigth (C) 2011 Michael Hahsler and Kurt Hornik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #' Class TOUR -- Solution to a traveling salesperson problem #' #' Class to store the solution of a TSP. Objects of this class are returned by #' TSP solvers in this package. Essentially, an object of class `TOUR` is #' a permutation vector containing the order of cities to visit. #' #' Since an object of class `TOUR` is an integer vector, it can be #' subsetted as an ordinary vector or coerced to an integer vector using #' `as.integer()`. It also contains the names of the objects as labels. #' Additionally, `TOUR` has the following attributes: `"method"`, #' `"tour_length"`. #' #' For most functions, e.g., [tour_length()] or [image.TSP()], the #' `TSP/ATSP` object used to find the tour is still needed, since the tour #' does not contain the distance information. #' #' @family TOUR #' #' @param x an integer permutation vector or, for the methods an object of #' class [TOUR]. #' @param object data (an integer vector) which can be coerced to `TOUR`. #' @param method character string; method used to create the tour. #' @param tsp `TSP` object the tour applies to. If available then the tour #' will include the tour length. Also the labels of the cities will be #' available in the tour (otherwise the labels of `x` are used). #' @param ... further arguments are passed on. #' @author Michael Hahsler #' @keywords classes #' @examples #' TOUR(1:10) #' #' ## calculate a tour #' data("USCA50") #' tour <- solve_TSP(USCA50) #' tour #' #' ## get tour length directly from tour #' tour_length(tour) #' #' ## get permutation vector #' as.integer(tour) #' #' ## show labels #' labels(tour) #' @export TOUR <- function(x, method = NA, tsp = NULL) { if (inherits(x, "TOUR")) return(x) x <- as.TOUR(x) attr(x, "method") <- as.character(method) if (!is.null(tsp)) { attr(x, "tour_length") <- tour_length(x, tsp) names(x) <- labels(tsp)[x] } x } ## coercion #' @rdname TOUR #' @export as.TOUR <- function(object) UseMethod("as.TOUR") #' @rdname TOUR #' @export as.TOUR.numeric <- function(object) { l <- labels(object) ### preserve labels object <- as.integer(object) names(object) <- l as.TOUR(object) } #' @rdname TOUR #' @export as.TOUR.integer <- function(object) { ## check tour if (any(object < 1) || any(object > length(object)) || any(is.na(object))) stop("tour contains illegal elements.") if (any(duplicated(object))) stop("tour indices are not unique.") class(object) <- c("TOUR", class(object)) object } #' @rdname TOUR #' @export print.TOUR <- function(x, ...) { cat("object of class", sQuote(class(x)[1]), "\n") cat("result of method", sQuote(attr(x, "method")), "for", length(x), "cities\n") if (!is.null(attr(x, "tour_length"))) cat("tour length:", attr(x, "tour_length"), "\n") else cat("tour length: unknown\n") } TSP/R/TSP.R0000644000176200001440000001106714401437346011725 0ustar liggesusers####################################################################### # TSP - Traveling Salesperson Problem # Copyrigth (C) 2011 Michael Hahsler and Kurt Hornik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #' Class TSP -- Symmetric traveling salesperson problem #' #' Constructor to create an instance of a symmetric traveling salesperson #' problem (TSP) and some auxiliary methods. #' #' Objects of class `TSP` are internally represented as `dist` #' objects (use [as.dist()] to get the `dist` object). #' #' Not permissible paths can be set to a distance of `+Inf`. `NA`s are not allowed and `-Inf` will lead #' to the algorithm only being able to find an admissible tour, but not the best one. #' #' @family TSP #' #' @param x,object an object (currently `dist` or a symmetric matrix) to #' be converted into a `TSP` or, for the methods, an object of class #' `TSP`. #' @param labels optional city labels. If not given, labels are taken from #' `x`. #' @param method optional name of the distance metric. If `x` is a #' `dist` object, then the method is taken from that object. #' @param col color scheme for image. #' @param order order of cities for the image as an integer vector or an object #' of class [TOUR]. #' @param ... further arguments are passed on. #' @returns #' - `TSP()` returns `x` as an object of class `TSP`. #' - `n_of_cities()` returns the number of cities in `x`. #' - `labels()` returns a vector with the names of the cities in `x`. #' @author Michael Hahsler #' @keywords classes #' @examples #' data("iris") #' d <- dist(iris[-5]) #' #' ## create a TSP #' tsp <- TSP(d) #' tsp #' #' ## use some methods #' n_of_cities(tsp) #' labels(tsp) #' image(tsp) #' @export TSP <- function(x, labels = NULL, method = NULL) { if (inherits(x, "TSP")) return(x) x <- as.TSP(x) if (!is.null(labels)) attr(x, "Labels") <- labels if (!is.null(method)) attr(x, "method") <- method x } ## coercion #' @rdname TSP #' @export as.TSP <- function(x) UseMethod("as.TSP") #' @rdname TSP #' @export as.TSP.dist <- function(x) { ## make sure we have a upper triangle matrix w/o diagonal x <- as.dist(x, diag = FALSE, upper = FALSE) ## make sure we have labels if (is.null(attr(x, "Labels"))) attr(x, "Labels") <- c(1:n_of_cities(x)) if (any(is.nan(x))) stop(paste(sQuote("NAs"), "not supported")) ## make sure data is numeric mode(x) <- "numeric" class(x) <- c("TSP", class(x)) x } #' @rdname TSP #' @export as.TSP.matrix <- function(x) { if (!isSymmetric(x)) stop("TSP requires a symmetric matrix") method <- attr(x, "method") x <- as.dist(x, diag = FALSE, upper = FALSE) attr(x, "method") <- method ## make sure we have labels if (is.null(attr(x, "Labels"))) attr(x, "Labels") <- c(1:n_of_cities(x)) if (any(is.nan(x))) stop(paste(sQuote("NAs"), "not supported")) ## make sure data is numeric mode(x) <- "numeric" class(x) <- c("TSP", class(x)) x } #' @rdname TSP #' @param m a TSP object to be converted to a [dist] object. #' @export as.dist.TSP <- function(m, ...) { class(m) <- "dist" as.dist(m, ...) } ## print #' @rdname TSP #' @export print.TSP <- function(x, ...) { method <- attr(x, "method") if (is.null(method)) method <- "unknown" cat("object of class", sQuote(class(x)[1]), "\n") cat(n_of_cities(x), "cities", paste("(distance ", sQuote(method), ")", sep = ""), "\n") } ## generic for n_of_cities #' @rdname TSP #' @export n_of_cities <- function(x) UseMethod("n_of_cities") ## number of cities #' @rdname TSP #' @export n_of_cities.TSP <- function(x) attr(x, "Size") #' @export n_of_cities.default <- n_of_cities.TSP ## labels #' @rdname TSP #' @export labels.TSP <- function(object, ...) attr(object, "Labels") ## image #' @rdname TSP #' @export image.TSP <- function(x, order, col = gray.colors(64), ...) { p <- n_of_cities(x) if (missing(order)) order <- 1:p graphics::image.default(1:p, 1:p, as.matrix(x)[order, order], col = col, ...) } TSP/R/USCA312.R0000644000176200001440000000216714412644012012231 0ustar liggesusers#' USCA312/USCA50 -- 312/50 cities in the US and Canada #' #' The `USCA312` dataset contains the distances between 312 cities in the #' US and Canada as an object of class `TSP`. `USCA50` is a subset #' of `USCA312` containing only the first 50 cities. #' #' The `USCA312_GPS` dataset contains the location (long/lat) of the 312 #' cities. #' #' #' @name USCA #' @aliases USCA312 USCA312_GPS USCA50 #' @docType data #' @format `USCA312` and `USCA50` are objects of class `TSP`. #' `USCA312_GPS` is a data.frame with city name, long and lat. #' @author Michael Hahsler #' @source John Burkardt, CITIES -- City Distance Datasets, Florida State #' University, Department of Scientific Computing #' @keywords datasets #' @examples #' data("USCA312") #' #' ## calculate a tour #' tour <- solve_TSP(USCA312) #' tour #' #' # Visualize the tour if package maps is installed #' if(require("maps")) { #' #' library(maps) #' data("USCA312_GPS") #' head(USCA312_GPS) #' #' plot((USCA312_GPS[, c("long", "lat")]), cex = .3) #' map("world", col = "gray", add = TRUE) #' polygon(USCA312_GPS[, c("long", "lat")][tour,], border = "red") #' } NULL TSP/R/cut_tour.R0000644000176200001440000000632714260637776013142 0ustar liggesusers####################################################################### # TSP - Traveling Salesperson Problem # Copyrigth (C) 2011 Michael Hahsler and Kurt Hornik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #' Cut a tour to form a path #' #' Cuts a tour at a specified city to form a path. #' #' @family TOUR #' #' @param x an object of class [TOUR]. #' @param cut the index or label of the city/cities to cut the tour. #' @param exclude_cut exclude the city where we cut? If `FALSE`, the city #' at the cut is included in the path as the first city. #' @return Returns a named vector with city ids forming the path. If multiple #' cuts are used then a list with paths is returned. #' @author Michael Hahsler #' @keywords optimize #' @examples #' data("USCA50") #' #' ## find a path starting at Austin, TX #' tour <- solve_TSP(USCA50) #' path <- cut_tour(tour, cut = "Austin, TX", exclude_cut = FALSE) #' path #' #' ## cut the tours at two cities #' tour <- solve_TSP(USCA50) #' path <- cut_tour(tour, cut = c("Austin, TX", "Cambridge, MA"), exclude_cut = FALSE) #' path #' #' ## cut a tour at the largest gap using a dummy city #' tsp <- insert_dummy(USCA50, label = "cut") #' tour <- solve_TSP(tsp) #' #' ## cut tour into path at the dummy city #' path <- cut_tour(tour, "cut") #' path #' @export cut_tour <- function(x, cut, exclude_cut = TRUE) UseMethod("cut_tour") #' @rdname cut_tour #' @export cut_tour.TOUR <- function(x, cut, exclude_cut = TRUE) { exclude_cut <- as.integer(exclude_cut) ## city label if (is.character(cut)) { cut <- which(as.logical(apply( sapply(cut, "==", labels(x)), MARGIN = 1, sum ))) if (length(cut) < 1) stop("cut has to exist") ## city id } else { if (any(is.na(cut <- match(cut, x)))) stop("cut has to exist") } if (length(cut) == 1L) { ## single path if (exclude_cut && length(x) <= 1) path <- integer(0) else path <- c(x, x)[(cut + exclude_cut):(length(x) + cut - 1L)] } else { ## multiple paths, return as a list path <- replicate(length(cut), integer(0)) path[[1L]] <- c(if ((tail(cut, 1) + exclude_cut) <= length(x)) (tail(cut, 1) + exclude_cut):length(x) else NULL, if (cut[1] > 1) 1:(cut[1] - 1L) else NULL) for (i in seq_len(length(cut) - 1L)) { if ((cut[i] + exclude_cut) <= (cut[i + 1L] - 1L)) path[[i + 1L]] <- (cut[i] + exclude_cut):(cut[i + 1L] - 1L) } path <- lapply( path, FUN = function(i) x[i] ) if (exclude_cut) names(path) <- labels(x)[cut] } path } TSP/R/tsp_nn.R0000644000176200001440000000501214205204263012541 0ustar liggesusers####################################################################### # TSP - Traveling Salesperson Problem # Copyrigth (C) 2011 Michael Hahsler and Kurt Hornik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ## nearest neighbor algorithm tsp_nn <- function(x, control = NULL) { ## parameter x comes checked from solve_TSP/solve_ATSP n <- n_of_cities(x) ## we use a matrix for now (covers TSP and ATSP) x <- as.matrix(x) control <- .get_parameters(control, list( start = sample(n, 1) ), method = "nn") start <- control$start if(start < 0 || start > n) stop(paste("illegal value for", sQuote("start"))) placed <- logical(n) order <- integer(n) ## place first city current <- start order[1L] <- current placed[current] <- TRUE while(length(rest <- which(!placed)) > 0L) { ## nearest <- rest[which.min(x[current,rest])] ## which.min has problems with Inf ## so we can break ties randomly now too x_sub <- x[current, rest] current <- rest[which(x_sub == min(x_sub, na.rm = TRUE))] if(length(current) > 1L) current <- sample(current, 1) ## place city order[n + 1L - length(rest)] <- current placed[current] <- TRUE } if (control$verbose) cat("All cities placed.\n\n") order } ## repetitive NN tsp_repetitive_nn <- function(x, control){ n <- n_of_cities(x) control <- .get_parameters(control, list(), method = "repetitive_nn") #tours <- lapply(1:n, function(i) tsp_nn(x, control = list(start = i))) ## no backend would warn! i <- 0L ## for R CMD check (no global binding for i) suppressWarnings( tours <- foreach(i = 1:n) %dopar% tsp_nn(x, control = list(start = i)) ) if (control$verbose) cat("All replications are complete.\n\n") lengths <- sapply(tours, FUN = function(i) tour_length(x, i)) tours[[which.min(lengths)]] } TSP/R/ATSP.R0000644000176200001440000001034414204054400012006 0ustar liggesusers####################################################################### # TSP - Traveling Salesperson Problem # Copyrigth (C) 2011 Michael Hahsler and Kurt Hornik # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ## create a (asymmetric) ATSP problem #' Class ATSP -- Asymmetric traveling salesperson problem #' #' Constructor to create an instance of the asymmetric traveling salesperson #' problem (ATSP) and some auxiliary methods. #' #' Objects of class `ATSP` are internally represented by a matrix (use #' `as.matrix()` to get just the matrix). #' #' ATSPs can be transformed into (larger) symmetric TSPs using #' [reformulate_ATSP_as_TSP()]. #' #' @family TSP #' #' @param x,object an object (a square matrix) to be converted into an #' `ATSP` or, for the methods, an object of class `ATSP`. #' @param labels optional city labels. If not given, labels are taken from #' `x`. #' @param method optional name of the distance metric. #' @param col color scheme for image. #' @param order order of cities as an integer vector or an object of class #' `TOUR`. #' @param ... further arguments are passed on. #' @returns #' - `ATSP()` returns `x` as an object of class `ATSP`. #' - `n_of_cities()` returns the number of cities in `x`. #' - `labels()` returns a vector with the names of the cities in `x`. #' @author Michael Hahsler #' @keywords classes #' @examples #' data <- matrix(runif(10^2), ncol = 10, dimnames = list(1:10, 1:10)) #' #' atsp <- ATSP(data) #' atsp #' #' ## use some methods #' n_of_cities(atsp) #' labels(atsp) #' #' ## calculate a tour #' tour <- solve_TSP(atsp, method = "nn") #' tour #' #' tour_length(tour) #' #' image(atsp, tour) #' @export ATSP <- function(x, labels = NULL, method = NULL) { if(inherits(x, "ATSP")) return(x) atsp <- as.ATSP(x) if(!is.null(labels)) dimnames(atsp) <- list(labels, labels) if(!is.null(method)) attr(atsp, "method") <- method atsp } #' @rdname ATSP #' @export as.ATSP <- function(x) UseMethod("as.ATSP") #' @rdname ATSP #' @export as.ATSP.matrix <- function(x){ .isSquare <- function(x) (dim(x)[1] == dim(x)[2]) if(!.isSquare(x)) stop("ATSP requires a square matrix") ## check for NAs if(any(is.nan(x))) stop(paste(sQuote("NAs"), "not supported")) ## make sure we have labels if(is.null(dimnames(x))) dimnames(x) <- list(1:dim(x)[1], 1: dim(x)[1]) if(is.null(colnames(x))) colnames(x) <- rownames(x) if(is.null(rownames(x))) rownames(x) <- colnames(x) ## make sure data is numeric mode(x) <- "numeric" class(x) <- c("ATSP", class(x)) x } #' @rdname ATSP #' @export as.ATSP.dist <- function(x){ method <- attr(x, "method") x <- as.ATSP(as.matrix(x)) ## make sure data is numeric mode(x) <- "numeric" class(x) <- c("ATSP", class(x)) attr(x, "method") <- method x } ## print #' @rdname ATSP #' @export print.ATSP <- function(x, ...) { method <- attr(x, "method") if(is.null(method)) method <- "unknown" cat("object of class", sQuote(class(x)[1]), " (asymmetric TSP) \n") cat(n_of_cities(x), "cities", paste("(distance ", sQuote(method),")", sep=""), "\n") } ## number of cities #' @rdname ATSP #' @export n_of_cities.ATSP <- function(x) nrow(x) ## labels #' @rdname ATSP #' @export labels.ATSP <- function(object, ...) dimnames(object)[[1]] ## image #' @rdname ATSP #' @export image.ATSP <- function(x, order, col = gray.colors(64), ...) { p <- n_of_cities(x) if(missing(order)) order <- 1:p graphics::image.default(1:p, 1:p, x[order, order], col = col, ...) } ## coerce to matrix #' @rdname ATSP #' @export as.matrix.ATSP <- function(x, ...){ unclass(x) } TSP/NEWS.md0000644000176200001440000000774714412664050012037 0ustar liggesusers# TSP 1.2-4 (04/03/2023) * removed dependency on maptools. # TSP 1.2-3 (03/08/2023) ## New Features * plot for ETSP gained parameter labels to plot city labels. ## Bug Fixes * register S3 method n_of_cities.default # TSP 1.2-2 (01/24/2023) ## Bug Fixes * Fixed bool definition for C23. # TSP 1.2-1 (07/14/2022) ## New Features * added filter_ATSP_as_TSP_dummies(). * tour_length() now also accepts integer vectors instead of TOUR. ## Bug Fixes * Small integer values are now left unscaled for Concorde. # TSP 1.2-0 (02/21/2022) ## Internal Changes * The package uses now roxygen. * C code has now long vector support for dist. # TSP 1.1-11 (10/06/2021) ## Bug Fixes * cut_tour: fixed dropped city for multiple cut points (reported by RegularnaMatrica) # TSP 1.1-10 (04/17/2020) ## Bug Fixes * Fixed Linkern file management on Windows. * Converting distances that only contain 0 and Inf (e.g., from an adjacency matrix) is now fixed for Concorde and Linkern. * Reduced the maximum integer for Concorde to avoid overflows (reported by sarwanpasha). # TSP 1.1-9 (02/02/2020) * Maintenance release. # TSP 1.1-8 (01/23/2020) ## New Feature * solve_TSP for ATSP gained parameter as_TSP to solve the ATSP reformulated as a TSP. * Concorde and linkern can now solve ATSP using a reformulation as a TSP. * cut_tour can now cut a tour into multiple paths. # TSP 1.1-7 (05/22/2019) ## Bug Fixes * concorde_path now normalizes the path (translates . and ~). * reformulate_ATSP_as_TSP now keeps the method attribute (i.e., used distance measure) * TSP and ATSP gained parameter method to store the name of the used distance metric. * Fixed read_TSPLIB for EDGE_WEIGHT_FORMAT of LOWER_ROW, LOWER_DIAG_ROW, UPPER_COL and UPPER_DIAG_COL (reported by klukac). # TSP 1.1-6 (04/29/2018) ## Bug Fixes * Start for insertion algorithms is now coerced to integer. * Fixed problem with TSP with 1 city on Win 32 on R 3.5.0. # TSP 1.1-5 (02/21/2017) * fixed TSP labels. * fixed tour_length for ETSP and added tests. # TSP 1.1-4 (2/21/2016) * fixed bug in arbitrary insertion for TSPs with two or less cities (bug report by Shrinidhee Shevade). * concorde and linkern help: exe argument was removed. The exe control argument for both methods in solve_TSP is now deprecated. Use concorde_path(path) instead. * concorde and linkern gained a control argument verbose to suppress the output. # TSP 1.1-3 (9/2/2015) * two-opt now works correctly with asymmetric TSPs (bug report by Luis Martinez). # TSP 1.1-2 (7/30/2015) * Fixed imports for non-base packages. # TSP 1.1-1 (5/15/2015) * improved speed of C code. * compatibility with new release of testthat # TSP 1.1-0 (3/14/2015) * default method is now arbitrary_insertion with two_opt refinement. * we use foreach (use doParallel) to compute repetitions in parallel * ETSP (Euclidean TSP) added. * generic and arguments for tour_length have # Changed (fist argument is now a tour). * method "2-opt" was renamed to "two_opt" so it can also be used as a proper variable name. * solve_TSP gained methods "identity" and "random". * solve_TSP gained options "repetition" and "two_opt". # TSP 1.0-10 (2/3/2015) * added check for argument cut in cut_tour * Finding concord and linkern is now case insensitive (Reported by Mark Otto) # TSP 1.0-9 (7/16/2014) * Check for NAs in distances. * +INF and -INF are now handled in solve_TSP. * fixed single quotes in vignette. # TSP 1.0-8 (9/6/2013) * service release. # TSP 1.0-7 (8/22/2012) * Added PACKAGE argument to C calls. # TSP 1.0-6 (11/29/2011) * Fixed bug in read_TSPLIB. # TSP 1.0-5 (11/10/2011) * Changed constructor for TOUR to allow for method and tour_length. * Bug fixes # TSP 1.0-4 (8/31/2011) * Fixed bug with missing row/column labels in as.ATSP() (reported by Ian Deters) # TSP 1.0-3 (5/26/2011) * Service release # TSP 1.0-2 (1/14/2011) * Fixed Windows/R bug with temp files. * Fixed the code for SpatialLines thanks to Roger Bivand. # TSP 0.1-2 (9/18/2006) * Initial release. TSP/MD50000644000176200001440000000577614413041204011240 0ustar liggesusersd725628eda94aef34baee1a6300246bb *DESCRIPTION a22e52650bbc8c2e5714bdea84406e3c *NAMESPACE 4ac712944f6f94af5f32a2d79b215800 *NEWS.md a6c58bee926cef1f2aa01d2d55a15c98 *R/AAA_TSP-package.R 9ec5470a168f0eec29f8966a3d9e0de9 *R/AAA_parameter.R 9db80d2422f37bb05ced61d75be3ebe7 *R/ATSP.R 185c84e25431be9c7e7933780f7581af *R/ETSP.R 88a5897e489cc8e3ca88c191ee94f651 *R/TOUR.R 92e6d885be089801bc15faead45452df *R/TSP.R 9b958b031e449dfd9a81aa0a935cd12a *R/TSPLIB.R e2f164c656627a98f2643c77ca8f6a9c *R/USCA312.R b2fd8bac405b43750bb1610718506bfa *R/cut_tour.R 983685c5b48493021e2cb6c7e6aeeef4 *R/insert_dummy.R 759852269e8d5d3fd5de71e105142ecc *R/reformulare_ATSP_as_TSP.R e39e135e1d1c4447e050267facdf0a57 *R/solve_TSP.R 24553b3b5d5d19cb7dbcd900411fb70e *R/tour_length.R 3fb2864d56f667e14667a8e3ce821f95 *R/tsp_concorde.R 1b25f3c8049e3e9a196cfcad276e0052 *R/tsp_insertion.R d1598a91dc21d0e3eb936ce3889abf0d *R/tsp_nn.R 9ec8f13ea9c0935151f0c6b9096a55b8 *R/tsp_two_opt.R 5228b5dee9cd34c6719e508f8308f31d *README.md 7f2094c7b4d5faa522b624cffc621f8b *build/partial.rdb 8d2a660943725e8e516cb0ea5756851f *build/vignette.rds cbc08fbda69c99bfd002bd94e83f18e9 *data/USCA312.rda 4e7f660688a4bc16dee5b14a5a9a41c3 *data/USCA312_GPS.rda 654e60750bbc434a2c4ef01f6ac38885 *data/USCA50.rda f06eaa5d43b10fb3fff425ea6e60bfc7 *inst/CITATION 8d113c7f0845f9379b7e1a4befea4870 *inst/doc/TSP.R 7d0e7e741518b21e836f7c0d60744de6 *inst/doc/TSP.Rnw 6c293dccdd449b58b5353ec19ae4eb69 *inst/doc/TSP.pdf 9d75b7ee2a0295809647546e2caec298 *inst/examples/d493.tsp a3bc8512298ca7ea098fef3efe9962e2 *man/ATSP.Rd 5207f6cce5e4e2a639ff18de0d1bb8eb *man/Concorde.Rd c2a955a1e4a27c1daad55b464bcf3d5e *man/ETSP.Rd dc7d95e3024d23317f2fa4f4a30f2ea7 *man/TOUR.Rd 90cd4b4ad4edf88336d24edd128b59ca *man/TSP-package.Rd 2cb1ebdacc6f0f79e484e6aa6e990690 *man/TSP.Rd 40daa526faaba857a7e845589985c32c *man/TSPLIB.Rd 2ded294f8969cbcf772ea3a86054d77d *man/USCA.Rd fe61a8d6f99ca35fd9e73d2aec010688 *man/cut_tour.Rd 85b2a1befff39b63d07b787268e0b995 *man/figures/logo.svg 70f7fc298debb5a1c2df22cb9f7011ab *man/insert_dummy.Rd 92e483552cb089259b959e845229f8ab *man/reformulate_ATSP_as_TSP.Rd 7880d3b260f9c8ad05bd23a7b35c4f86 *man/solve_TSP.Rd 1b7562cd9fd001811d8370c558eb6d70 *man/tour_length.Rd f0276d6a12d50703983732ab3dc0240a *src/dll.c fc6380482b910ae85f24f5f2dafd99b9 *src/insertion_cost.c a6aaa1c2435490a41f41a4b5c0c3ba7c *src/matrix_pos.h 3086f08677dfbd91cf438867a26d5114 *src/tour_length.c c52e2ddbd6678b80c7388f8574708a2c *src/two_opt.c 3703922de28f16a1f0bd1ca82302cb51 *tests/testthat.R 6cc29a47b81c493ef81b21b3b871138e *tests/testthat/test-ETSP.R efc5545170e5a3a8cf6792c5abc140f8 *tests/testthat/test-TSPLIB.R 85fee4ffde4907f1da64c1fa6a7f3375 *tests/testthat/test-concorde.R 00853d4a02dc8fa428c3199c34e18443 *tests/testthat/test-insert_cut_etc.R 998eecca7ceecf1bffb9b82d7305e430 *tests/testthat/test-solve_TSP.R 7d0e7e741518b21e836f7c0d60744de6 *vignettes/TSP.Rnw e5fefe1a7b9cc2d989c7a10694f263be *vignettes/TSP.bib c760b2e30089afe4035f4c86a0faca1a *vignettes/overview.odg 76b5cfce452ac70b4c4b51bf5164887d *vignettes/overview.pdf TSP/inst/0000755000176200001440000000000014412674611011703 5ustar liggesusersTSP/inst/examples/0000755000176200001440000000000012606077054013522 5ustar liggesusersTSP/inst/examples/d493.tsp0000644000176200001440000003277512606077054014753 0ustar liggesusersNAME : d493 COMMENT : Drilling problem (Reinelt) TYPE : TSP DIMENSION : 493 EDGE_WEIGHT_TYPE : EUC_2D NODE_COORD_SECTION 1 0.00000e+00 0.00000e+00 2 1.11630e+03 1.55520e+03 3 1.35760e+03 1.47900e+03 4 1.14810e+03 1.77110e+03 5 1.18620e+03 1.79650e+03 6 1.20520e+03 1.88540e+03 7 1.23700e+03 1.99340e+03 8 1.30050e+03 2.00610e+03 9 1.16080e+03 2.02510e+03 10 1.17350e+03 2.03780e+03 11 1.22430e+03 2.05050e+03 12 1.35130e+03 2.24100e+03 13 1.73230e+03 2.13310e+03 14 1.74500e+03 2.19020e+03 15 1.76400e+03 2.29180e+03 16 1.76400e+03 2.34260e+03 17 1.73230e+03 2.39340e+03 18 1.74500e+03 2.41880e+03 19 1.64970e+03 2.43150e+03 20 1.75770e+03 2.52040e+03 21 2.29740e+03 1.77110e+03 22 2.21490e+03 1.42820e+03 23 2.22760e+03 1.33930e+03 24 2.18310e+03 1.32030e+03 25 2.61490e+03 1.11070e+03 26 2.50700e+03 1.16150e+03 27 2.34820e+03 9.52000e+02 28 2.22120e+03 1.00910e+03 29 2.20850e+03 1.08530e+03 30 2.20220e+03 1.13610e+03 31 2.21490e+03 1.17420e+03 32 2.02440e+03 1.12340e+03 33 2.04340e+03 1.30120e+03 34 1.94820e+03 1.30760e+03 35 1.94180e+03 1.39010e+03 36 1.84660e+03 1.41550e+03 37 1.75770e+03 1.36470e+03 38 1.80210e+03 1.35200e+03 39 1.83390e+03 1.26310e+03 40 1.73230e+03 1.25040e+03 41 2.04340e+03 1.58060e+03 42 2.04980e+03 1.74570e+03 43 1.99900e+03 1.80290e+03 44 1.96090e+03 1.81560e+03 45 2.05610e+03 1.82190e+03 46 2.01170e+03 1.82830e+03 47 2.04340e+03 1.85370e+03 48 1.84660e+03 1.78380e+03 49 1.82120e+03 1.82830e+03 50 1.84660e+03 1.86640e+03 51 1.81480e+03 1.65050e+03 52 1.66880e+03 1.80920e+03 53 1.85930e+03 2.16480e+03 54 1.98630e+03 2.13310e+03 55 2.01170e+03 2.17750e+03 56 1.94820e+03 2.19660e+03 57 1.89100e+03 2.24740e+03 58 2.01170e+03 2.27280e+03 59 2.03710e+03 2.30450e+03 60 2.05610e+03 2.35530e+03 61 1.89740e+03 2.41250e+03 62 1.89740e+03 2.45690e+03 63 1.91640e+03 2.46960e+03 64 2.05610e+03 2.46960e+03 65 2.15770e+03 2.13940e+03 66 1.63700e+03 2.69820e+03 67 1.70690e+03 2.70460e+03 68 1.76400e+03 2.74900e+03 69 1.70690e+03 2.77440e+03 70 1.76400e+03 2.79980e+03 71 1.87200e+03 3.06650e+03 72 1.85290e+03 3.00300e+03 73 1.87200e+03 2.99670e+03 74 1.89740e+03 2.99670e+03 75 2.21490e+03 2.97130e+03 76 2.19580e+03 2.93950e+03 77 2.24660e+03 2.88870e+03 78 1.89100e+03 2.86970e+03 79 2.20220e+03 2.84430e+03 80 1.90370e+03 2.81890e+03 81 1.87200e+03 2.81890e+03 82 2.01170e+03 2.76170e+03 83 1.90370e+03 2.69820e+03 84 1.95450e+03 2.58390e+03 85 2.05610e+03 2.57760e+03 86 2.09420e+03 2.56490e+03 87 2.19580e+03 2.47600e+03 88 2.58950e+03 2.99030e+03 89 2.60860e+03 2.99030e+03 90 2.50700e+03 3.00300e+03 91 2.89430e+03 3.04750e+03 92 2.89430e+03 3.00300e+03 93 2.90700e+03 2.97130e+03 94 3.02770e+03 3.04750e+03 95 2.79270e+03 2.81250e+03 96 2.22760e+03 2.81250e+03 97 2.58320e+03 2.79980e+03 98 2.59590e+03 2.77440e+03 99 2.50700e+03 2.77440e+03 100 2.72290e+03 2.75540e+03 101 2.61490e+03 2.74900e+03 102 2.88800e+03 2.73000e+03 103 3.21180e+03 2.73000e+03 104 3.14200e+03 2.71730e+03 105 2.75460e+03 2.69820e+03 106 2.45620e+03 2.69820e+03 107 2.57050e+03 2.62200e+03 108 2.72290e+03 2.62200e+03 109 3.36420e+03 2.62200e+03 110 2.90070e+03 2.61570e+03 111 3.13560e+03 2.60300e+03 112 2.71020e+03 2.59660e+03 113 2.71650e+03 2.54580e+03 114 2.88800e+03 2.53310e+03 115 2.84990e+03 2.51410e+03 116 2.29740e+03 2.51410e+03 117 2.60860e+03 2.49500e+03 118 3.22450e+03 2.48870e+03 119 2.69110e+03 2.47600e+03 120 2.87530e+03 2.43790e+03 121 2.50060e+03 2.41880e+03 122 2.43080e+03 2.39980e+03 123 2.87530e+03 2.39980e+03 124 3.12930e+03 2.36800e+03 125 2.58320e+03 2.36800e+03 126 2.49430e+03 2.36800e+03 127 2.78000e+03 2.36170e+03 128 2.33550e+03 2.35530e+03 129 2.61490e+03 2.31720e+03 130 2.92610e+03 2.30450e+03 131 2.80540e+03 2.29180e+03 132 2.58320e+03 2.29180e+03 133 2.82450e+03 2.28550e+03 134 2.86260e+03 2.27910e+03 135 2.79910e+03 2.26010e+03 136 2.69110e+03 2.26010e+03 137 2.75460e+03 2.25370e+03 138 2.91340e+03 2.25370e+03 139 2.34820e+03 2.24100e+03 140 2.90700e+03 2.23470e+03 141 3.13560e+03 2.23470e+03 142 2.92610e+03 2.22830e+03 143 3.43410e+03 2.20290e+03 144 2.88160e+03 2.19020e+03 145 2.60220e+03 2.19020e+03 146 2.71020e+03 2.16480e+03 147 2.79270e+03 2.14580e+03 148 2.82450e+03 2.13310e+03 149 2.42440e+03 2.10770e+03 150 2.86890e+03 2.10130e+03 151 3.43410e+03 2.10130e+03 152 2.61490e+03 2.08860e+03 153 3.07850e+03 2.08230e+03 154 2.58950e+03 2.07590e+03 155 2.48790e+03 2.06320e+03 156 2.73560e+03 2.06320e+03 157 3.44680e+03 2.04420e+03 158 3.35150e+03 2.03150e+03 159 2.62760e+03 2.01880e+03 160 2.69750e+03 2.00610e+03 161 2.48790e+03 1.99340e+03 162 2.68480e+03 1.97430e+03 163 2.46250e+03 1.96800e+03 164 3.13560e+03 1.96800e+03 165 3.39600e+03 1.96800e+03 166 2.74830e+03 1.96160e+03 167 2.72290e+03 1.96160e+03 168 3.23090e+03 1.95530e+03 169 2.97050e+03 1.94260e+03 170 2.47520e+03 1.93620e+03 171 2.51330e+03 1.92350e+03 172 2.92610e+03 1.91720e+03 173 2.49430e+03 1.91080e+03 174 2.61490e+03 1.90450e+03 175 2.51970e+03 1.89180e+03 176 2.58950e+03 1.89180e+03 177 3.40870e+03 1.89180e+03 178 3.64360e+03 1.89180e+03 179 2.78640e+03 1.88540e+03 180 2.65940e+03 1.88540e+03 181 2.49430e+03 1.87910e+03 182 2.95780e+03 1.87910e+03 183 3.45950e+03 1.87910e+03 184 3.05310e+03 1.86640e+03 185 2.77370e+03 1.86640e+03 186 2.71020e+03 1.86640e+03 187 3.23720e+03 1.85370e+03 188 3.32610e+03 1.85370e+03 189 2.73560e+03 1.84730e+03 190 2.49430e+03 1.83460e+03 191 3.26900e+03 1.83460e+03 192 3.30710e+03 1.83460e+03 193 3.36420e+03 1.83460e+03 194 2.67210e+03 1.82830e+03 195 3.35150e+03 1.82190e+03 196 3.47220e+03 1.82190e+03 197 2.86890e+03 1.81560e+03 198 2.81180e+03 1.80920e+03 199 3.35150e+03 1.80290e+03 200 3.29440e+03 1.79650e+03 201 2.54510e+03 1.79650e+03 202 3.11020e+03 1.77750e+03 203 3.16100e+03 1.77750e+03 204 3.28170e+03 1.77750e+03 205 3.33880e+03 1.75840e+03 206 2.99590e+03 1.75840e+03 207 3.19910e+03 1.72030e+03 208 3.00230e+03 1.72030e+03 209 2.63400e+03 1.72030e+03 210 2.50700e+03 1.70760e+03 211 2.96420e+03 1.70760e+03 212 3.05940e+03 1.70760e+03 213 3.09750e+03 1.70760e+03 214 3.64360e+03 1.70760e+03 215 2.80540e+03 1.70130e+03 216 2.58320e+03 1.69490e+03 217 3.07850e+03 1.69490e+03 218 2.89430e+03 1.68860e+03 219 3.14830e+03 1.68220e+03 220 3.21820e+03 1.66320e+03 221 3.19910e+03 1.66320e+03 222 2.72920e+03 1.66320e+03 223 2.95150e+03 1.65050e+03 224 2.43080e+03 1.64410e+03 225 2.50700e+03 1.63140e+03 226 3.59920e+03 1.63140e+03 227 3.13560e+03 1.62510e+03 228 3.07850e+03 1.62510e+03 229 3.05940e+03 1.62510e+03 230 2.77370e+03 1.62510e+03 231 2.91340e+03 1.61870e+03 232 3.30710e+03 1.61870e+03 233 3.13560e+03 1.60600e+03 234 3.01500e+03 1.60600e+03 235 2.42440e+03 1.59970e+03 236 2.83080e+03 1.59330e+03 237 3.29440e+03 1.59330e+03 238 3.12930e+03 1.58060e+03 239 3.37690e+03 1.56790e+03 240 2.61490e+03 1.56790e+03 241 2.93240e+03 1.54890e+03 242 3.04620e+03 1.54730e+03 243 3.07220e+03 1.54730e+03 244 3.09820e+03 1.54730e+03 245 3.12420e+03 1.54730e+03 246 3.15020e+03 1.54730e+03 247 3.17620e+03 1.54730e+03 248 3.20220e+03 1.54730e+03 249 3.22820e+03 1.54730e+03 250 3.25420e+03 1.54730e+03 251 3.28020e+03 1.54730e+03 252 3.30620e+03 1.54730e+03 253 3.33220e+03 1.54730e+03 254 3.35820e+03 1.54730e+03 255 2.72290e+03 1.53620e+03 256 3.06570e+03 1.52460e+03 257 3.11120e+03 1.52460e+03 258 3.13720e+03 1.52460e+03 259 3.16320e+03 1.52460e+03 260 3.18920e+03 1.52460e+03 261 3.21520e+03 1.52460e+03 262 3.24120e+03 1.52460e+03 263 3.26720e+03 1.52460e+03 264 3.29320e+03 1.52460e+03 265 3.34520e+03 1.52460e+03 266 2.43710e+03 1.52350e+03 267 2.96420e+03 1.51080e+03 268 2.74190e+03 1.50440e+03 269 2.43080e+03 1.50440e+03 270 3.41350e+03 1.49860e+03 271 2.99750e+03 1.49210e+03 272 2.82450e+03 1.48540e+03 273 3.02020e+03 1.47910e+03 274 3.39070e+03 1.47910e+03 275 3.41350e+03 1.47260e+03 276 2.83720e+03 1.46630e+03 277 2.60860e+03 1.46630e+03 278 2.99750e+03 1.46610e+03 279 3.10470e+03 1.46610e+03 280 3.13070e+03 1.46610e+03 281 3.15670e+03 1.46610e+03 282 3.18270e+03 1.46610e+03 283 3.20870e+03 1.46610e+03 284 3.23470e+03 1.46610e+03 285 3.26070e+03 1.46610e+03 286 3.28670e+03 1.46610e+03 287 3.31270e+03 1.46610e+03 288 3.41350e+03 1.44660e+03 289 3.07870e+03 1.44660e+03 290 3.11770e+03 1.44330e+03 291 3.14370e+03 1.44330e+03 292 3.16970e+03 1.44330e+03 293 3.19570e+03 1.44330e+03 294 3.22170e+03 1.44330e+03 295 3.24770e+03 1.44330e+03 296 3.27370e+03 1.44330e+03 297 2.90070e+03 1.44090e+03 298 2.69110e+03 1.44090e+03 299 2.99750e+03 1.44010e+03 300 3.33220e+03 1.44010e+03 301 2.43710e+03 1.43460e+03 302 3.39070e+03 1.43360e+03 303 3.30950e+03 1.42710e+03 304 3.02020e+03 1.42710e+03 305 2.58320e+03 1.42190e+03 306 3.07870e+03 1.42060e+03 307 3.41350e+03 1.42060e+03 308 3.28350e+03 1.41730e+03 309 3.12750e+03 1.41730e+03 310 2.99750e+03 1.41410e+03 311 3.33220e+03 1.41410e+03 312 3.23720e+03 1.40920e+03 313 3.19910e+03 1.40920e+03 314 3.10150e+03 1.40760e+03 315 3.39070e+03 1.40760e+03 316 3.44040e+03 1.40280e+03 317 2.95150e+03 1.40280e+03 318 3.02020e+03 1.40110e+03 319 3.30950e+03 1.40110e+03 320 3.41350e+03 1.39460e+03 321 3.07870e+03 1.39460e+03 322 3.16100e+03 1.39010e+03 323 2.99750e+03 1.38810e+03 324 3.33220e+03 1.38810e+03 325 2.93880e+03 1.38380e+03 326 2.87530e+03 1.38380e+03 327 3.10150e+03 1.38160e+03 328 3.39070e+03 1.38160e+03 329 3.13990e+03 1.37540e+03 330 3.02020e+03 1.37510e+03 331 3.30950e+03 1.37510e+03 332 3.41350e+03 1.36860e+03 333 3.07870e+03 1.36860e+03 334 2.79910e+03 1.36470e+03 335 3.59920e+03 1.36470e+03 336 3.33220e+03 1.36210e+03 337 2.99750e+03 1.36210e+03 338 3.10150e+03 1.35560e+03 339 3.39070e+03 1.35560e+03 340 3.26900e+03 1.35200e+03 341 2.91970e+03 1.35200e+03 342 2.83720e+03 1.35200e+03 343 3.02020e+03 1.34910e+03 344 3.30950e+03 1.34910e+03 345 2.87530e+03 1.34570e+03 346 3.07870e+03 1.34260e+03 347 3.41350e+03 1.34260e+03 348 3.48490e+03 1.33930e+03 349 2.97050e+03 1.33930e+03 350 2.99750e+03 1.33610e+03 351 3.33220e+03 1.33610e+03 352 2.91340e+03 1.33300e+03 353 3.10150e+03 1.32960e+03 354 3.39070e+03 1.32960e+03 355 3.30950e+03 1.32310e+03 356 3.24360e+03 1.32310e+03 357 3.02020e+03 1.32310e+03 358 2.95780e+03 1.32030e+03 359 3.15470e+03 1.32030e+03 360 3.07870e+03 1.31660e+03 361 3.41350e+03 1.31660e+03 362 3.61190e+03 1.31390e+03 363 3.33220e+03 1.31010e+03 364 2.99750e+03 1.31010e+03 365 3.10150e+03 1.30360e+03 366 3.39070e+03 1.30360e+03 367 3.30950e+03 1.29710e+03 368 3.02020e+03 1.29710e+03 369 2.84990e+03 1.29490e+03 370 2.87530e+03 1.29490e+03 371 2.90070e+03 1.29490e+03 372 3.54200e+03 1.29490e+03 373 3.41350e+03 1.29060e+03 374 3.07870e+03 1.29060e+03 375 3.17370e+03 1.28850e+03 376 3.33220e+03 1.28410e+03 377 2.99750e+03 1.28410e+03 378 3.10150e+03 1.27760e+03 379 3.39070e+03 1.27760e+03 380 3.30950e+03 1.27110e+03 381 3.02020e+03 1.27110e+03 382 2.76730e+03 1.26950e+03 383 3.07870e+03 1.26460e+03 384 3.41350e+03 1.26460e+03 385 2.60220e+03 1.26310e+03 386 3.12750e+03 1.26130e+03 387 3.28350e+03 1.26130e+03 388 3.33220e+03 1.25810e+03 389 2.99750e+03 1.25810e+03 390 2.88160e+03 1.25680e+03 391 2.79270e+03 1.25680e+03 392 2.55780e+03 1.25680e+03 393 3.10150e+03 1.25160e+03 394 3.39070e+03 1.25160e+03 395 3.47850e+03 1.25040e+03 396 3.02020e+03 1.24510e+03 397 2.91970e+03 1.24410e+03 398 2.81810e+03 1.24410e+03 399 2.51970e+03 1.24410e+03 400 3.07870e+03 1.23860e+03 401 3.41350e+03 1.23860e+03 402 3.29320e+03 1.23530e+03 403 3.26720e+03 1.23530e+03 404 3.24120e+03 1.23530e+03 405 3.21520e+03 1.23530e+03 406 3.18920e+03 1.23530e+03 407 3.16320e+03 1.23530e+03 408 3.13720e+03 1.23530e+03 409 2.99750e+03 1.23210e+03 410 3.33220e+03 1.23210e+03 411 2.88160e+03 1.22500e+03 412 3.09820e+03 1.21260e+03 413 3.12420e+03 1.21260e+03 414 3.15020e+03 1.21260e+03 415 3.17620e+03 1.21260e+03 416 3.20220e+03 1.21260e+03 417 3.22820e+03 1.21260e+03 418 3.25420e+03 1.21260e+03 419 3.28020e+03 1.21260e+03 420 3.30620e+03 1.21260e+03 421 3.41350e+03 1.21260e+03 422 2.58950e+03 1.21230e+03 423 2.57050e+03 1.21230e+03 424 2.99750e+03 1.20610e+03 425 3.02020e+03 1.19960e+03 426 3.39070e+03 1.19960e+03 427 3.45950e+03 1.19960e+03 428 3.48490e+03 1.19960e+03 429 2.65940e+03 1.19330e+03 430 3.41350e+03 1.18660e+03 431 2.93880e+03 1.18040e+03 432 2.99750e+03 1.18010e+03 433 3.06570e+03 1.15410e+03 434 3.11770e+03 1.15410e+03 435 3.14370e+03 1.15410e+03 436 3.16970e+03 1.15410e+03 437 3.19570e+03 1.15410e+03 438 3.22170e+03 1.15410e+03 439 3.24770e+03 1.15410e+03 440 3.27370e+03 1.15410e+03 441 3.29970e+03 1.15410e+03 442 3.34520e+03 1.15410e+03 443 2.92610e+03 1.14250e+03 444 3.05270e+03 1.13130e+03 445 3.07870e+03 1.13130e+03 446 3.10470e+03 1.13130e+03 447 3.13070e+03 1.13130e+03 448 3.15670e+03 1.13130e+03 449 3.18270e+03 1.13130e+03 450 3.20870e+03 1.13130e+03 451 3.23470e+03 1.13130e+03 452 3.26070e+03 1.13130e+03 453 3.28670e+03 1.13130e+03 454 3.31270e+03 1.13130e+03 455 3.33870e+03 1.13130e+03 456 3.36470e+03 1.13130e+03 457 2.74190e+03 1.12980e+03 458 2.86260e+03 1.12340e+03 459 3.06580e+03 1.09800e+03 460 3.03400e+03 1.09170e+03 461 2.87530e+03 1.07900e+03 462 2.79270e+03 1.04090e+03 463 2.90070e+03 1.02820e+03 464 2.83720e+03 1.02180e+03 465 2.94510e+03 1.01550e+03 466 2.86260e+03 1.00910e+03 467 2.93880e+03 8.31300e+02 468 3.07210e+03 9.32900e+02 469 3.05940e+03 9.52000e+02 470 3.03400e+03 9.64700e+02 471 3.06580e+03 9.71000e+02 472 3.09120e+03 9.90100e+02 473 3.20550e+03 9.83700e+02 474 3.40870e+03 8.75800e+02 475 3.45950e+03 9.20200e+02 476 3.51030e+03 1.01550e+03 477 3.36420e+03 1.01550e+03 478 3.38330e+03 1.02820e+03 479 3.49760e+03 1.02820e+03 480 3.39600e+03 1.05360e+03 481 3.29440e+03 1.05360e+03 482 3.51660e+03 1.07260e+03 483 3.21820e+03 1.09800e+03 484 3.56740e+03 1.10440e+03 485 3.55470e+03 1.12340e+03 486 3.39600e+03 1.12340e+03 487 3.54840e+03 1.14250e+03 488 3.52930e+03 1.15520e+03 489 3.40870e+03 1.16150e+03 490 3.47220e+03 1.17420e+03 491 3.69440e+03 1.30120e+03 492 3.74520e+03 1.27580e+03 493 3.74520e+03 1.02180e+03 EOF TSP/inst/doc/0000755000176200001440000000000014412674611012450 5ustar liggesusersTSP/inst/doc/TSP.Rnw0000644000176200001440000013064014412657264013617 0ustar liggesusers%\documentclass[10pt,a4paper,fleqn]{article} \documentclass[nojss]{jss} \usepackage[english]{babel} %% my packages %\usepackage{a4wide} %\usepackage[round,longnamesfirst]{natbib} %\usepackage{hyperref} % \usepackage{amsmath} \usepackage{amsfonts} % %\newcommand{\strong}[1]{{\normalfont\fontseries{b}\selectfont #1}} \newcommand{\class}[1]{\mbox{\textsf{#1}}} \newcommand{\func}[1]{\mbox{\texttt{#1()}}} %\newcommand{\code}[1]{\mbox{\texttt{#1}}} %\newcommand{\pkg}[1]{\strong{#1}} \newcommand{\samp}[1]{`\mbox{\texttt{#1}}'} %\newcommand{\proglang}[1]{\textsf{#1}} \newcommand{\set}[1]{\mathcal{#1}} %\usepackage{Sweave} %% \VignetteIndexEntry{Introduction to TSP} \author{Michael Hahsler\\Southern Methodist University \And Kurt Hornik\\Wirtschaftsuniversit\"at Wien} \title{\pkg{TSP} -- Infrastructure for the Traveling Salesperson Problem} %% for pretty printing and a nice hypersummary also set: \Plainauthor{Michael Hahsler, Kurt Hornik} %% comma-separated \Plaintitle{TSP -- Infrastructure for the Traveling Salesperson Problem} %% without formatting \Shorttitle{Infrastructure for the TSP} %% a short title (if necessary) %% an abstract and keywords \Abstract{ The traveling salesperson problem (also known as traveling salesman problem or TSP) is a well known and important combinatorial optimization problem. The goal is to find the shortest tour that visits each city in a given list exactly once and then returns to the starting city. Despite this simple problem statement, solving the TSP is difficult since it belongs to the class of NP-complete problems. The importance of the TSP arises besides from its theoretical appeal from the variety of its applications. Typical applications in operations research include vehicle routing, computer wiring, cutting wallpaper and job sequencing. The main application in statistics is combinatorial data analysis, e.g., reordering rows and columns of data matrices or identifying clusters. In this paper we introduce the \proglang{R}~package \pkg{TSP} which provides a basic infrastructure for handling and solving the traveling salesperson problem. The package features S3 classes for specifying a TSP and its (possibly optimal) solution as well as several heuristics to find good solutions. In addition, it provides an interface to \emph{Concorde}, one of the best exact TSP solvers currently available. } \Keywords{combinatorial optimization, traveling salesman problem, \proglang{R}} \Plainkeywords{combinatorial optimization, traveling salesman problem, R} %% without formatting %% The address of (at least) one author should be given %% in the following format: \Address{ Michael Hahsler\\ Engineering Management, Information, and Systems\\ Lyle School of Engineering\\ Southern Methodist University\\ P.O. Box 750123 \\ Dallas, TX 75275-0123\\ E-mail: \email{mhahsler@lyle.smu.edu}\\ Kurt Hornik\\ Department of Finance, Accounting and Statistics\\ Wirtschaftsuniversit\"at Wien\\ 1090 Wien, Austria\\i E-mail: \email{kurt.hornik@wu-wien.ac.at}\\ URL: \url{http://statmath.wu.ac.at/~hornik/} } \begin{document} <>= options(width = 75, useFancyQuotes=FALSE, prompt="R> ") ### for sampling set.seed(1234) @ %\title{Introduction to \pkg{TSP} -- Infrastructure for the Traveling % Salesperson Problem} %\author{Michael Hahsler and Kurt Hornik} \maketitle \sloppy %\abstract{ % The traveling salesperson (or, salesman) problem (TSP) is a % well known and important combinatorial optimization problem. The goal % is to find the shortest tour that visits each city in a given list % exactly once and then returns to the starting city. Despite this % simple problem statement, solving the TSP is difficult since it % belongs to the class of NP-complete problems. The importance of the % TSP arises besides from its theoretical appeal from the variety of its % applications. Typical applications in operations research include % vehicle routing, computer wiring, cutting wallpaper and job % sequencing. The main application in statistics is combinatorial data % analysis, e.g., reordering rows and columns of data matrices or % identifying clusters. In this paper we introduce the % \proglang{R}~package \pkg{TSP} which provides a basic infrastructure % for handling and solving the traveling salesperson problem. The % package features S3 classes for specifying a TSP and its (possibly % optimal) solution as well as several heuristics to find good % solutions. In addition, it provides an interface to \emph{Concorde}, % one of the best exact TSP solvers currently available. } \section{Introduction} The traveling salesperson problem~\citep[TSP;][]{Lawler1985, Gutin2002} is a well known and important combinatorial optimization problem. The goal is to find the shortest tour that visits each city in a given list exactly once and then returns to the starting city. Formally, the TSP can be stated as follows. The distances between $n$ cities are stored in a distance matrix $\mathbf{D}$ with elements $d_{ij}$ where $i,j = 1\dots n$ and the diagonal elements $d_{ii}$ are zero. A \emph{tour} can be represented by a cyclic permutation $\pi$ of $\{1, 2,\dots, n\}$ where $\pi(i)$ represents the city that follows city $i$ on the tour. The traveling salesperson problem is then the optimization problem to find a permutation $\pi$ that minimizes the \emph{length of the tour} denoted by \begin{equation} \sum_{i=1}^n d_{i\pi(i)}. \end{equation} % see Lenstra & Kan 1975: Some simple Applications to the TSP For this minimization task, the tour length of $(n-1)!$ permutation vectors have to be compared. This results in a problem which is very hard to solve and in fact known to be NP-complete~\citep{Johnson1985a}. However, solving TSPs is an important part of applications in many areas including vehicle routing, computer wiring, machine sequencing and scheduling, frequency assignment in communication networks~\citep{Lenstra1975, Punnen2002}. %and structuring of %matrices~\citep{Lenstra1975, Punnen2002}. Applications in statistical data analysis include ordering and clustering objects. For example, data analysis applications in psychology ranging from profile smoothing to finding an order in developmental data are presented by~\cite{Hubert1978}. Clustering and ordering using TSP solvers is currently becoming popular in biostatistics. For example, \cite{Ray2007} describe an application for ordering genes and \cite{Johnson2006} use a TSP solver for clustering proteins. In this paper we give a very brief overview of the TSP and introduce the \proglang{R}~package \pkg{TSP} which provides an infrastructure for handling and solving TSPs. The paper is organized as follows. In Section~\ref{sec:TSP} we briefly present important aspects of the TSP including different problem formulations and approaches to solve TSPs. In Section~\ref{sec:infrastructure} we give an overview of the infrastructure implemented in \pkg{TSP} and the basic usage. In Section~\ref{sec:examples}, several examples are used to illustrate the package's capabilities. Section~\ref{sec:conclusion} concludes the paper. A previous version of this manuscript was published in the \emph{Journal of Statistical Software} \citep{TSP:Hahsler+Hornik2007}. \section{Theory} \label{sec:TSP} In this section, we briefly summarize some aspects of the TSP which are important for the implementation of the \pkg{TSP} package described in this paper. For a complete treatment of all aspects of the TSP, we refer the interested reader to the classic book edited by \cite{Lawler1985} and the more modern book edited by \cite{Gutin2002}. It has to be noted that in this paper, following the origin of the TSP, the term \emph{distance} is used. Distance is used here interchangeably with dissimilarity or cost and, unless explicitly stated, no restrictions to measures which obey the triangle inequality are made. An important distinction can be made between the symmetric TSP and the more general asymmetric TSP. For the symmetric case (normally referred to as just \emph{TSP}), for all distances in $\mathbf{D}$ the equality $d_{ij} = d_{ji}$ holds, i.e., it does not matter if we travel from $i$ to $j$ or the other way round, the distance is the same. In the asymmetric case (called \emph{ATSP}), the distances are not equal for all pairs of cities. Problems of this kind arise when we do not deal with spatial distances between cities but, e.g., with the cost or necessary time associated with traveling between locations, where the price for the plane ticket between two cities may be different depending on which way we go. \subsection{Different formulations of the TSP} \label{sec:formulations} Other than the permutation problem in the introduction, the TSP can also be formulated as a graph theoretic problem. Here the TSP is formulated by means of a complete graph $G = (V, E)$, where the cities correspond to the node set $V = \{1,2,\ldots,n\}$ and each edge $e_i \in E$ has an associated weight $w_i$ representing the distance between the nodes it connects. If the graph is not complete, the missing edges can be replaced by edges with very large distances. The goal is to find a \emph{Hamiltonian cycle}, i.e., a cycle which visits each node in the graph exactly once, with the least weight in the graph~\citep{Hoffman1985}. This formulation naturally leads to procedures involving minimum spanning trees for tour construction or edge exchanges to improve existing tours. TSPs can also be represented as integer and linear programming problems~\citep[see, e.g.,][]{Punnen2002}. The \emph{integer programming (IP) formulation} is based on the assignment problem with additional constraint of no sub-tours: \[ \begin{array}{rl} \text{Minimize } & \sum_{i=1}^n\sum_{j=1}^n{d_{ij}x_{ij}} % = \mathrm{trace}(\mathbf{D}^T\mathbf{X}) \\[3mm] \text{Subject to } & \sum_{i=1}^n{x_{ij}=1}, \quad j=1,\ldots,n, \\ & \sum_{j=1}^n{x_{ij}=1}, \quad i=1,\ldots,n, \\ & x_{ij} = 0 \text{ or } 1 \\ & \text{no sub-tours allowed} \\ \end{array} \] The solution matrix $\mathbf{X} = (x_{ij})$ of the assignment problem represents a tour or a collection of sub-tour (several unconnected cycles) where only edges which corresponding to elements $x_{ij} = 1$ are on the tour or a sub-tour. The additional restriction that no sub-tours are allowed (called \emph{sub-tour elimination constraints}) restrict the solution to only proper tours. Unfortunately, the number of sub-tour elimination constraints grows exponentially with the number of cities which leads to an extremely hard problem. The \emph{linear programming (LP) formulation} of the TSP is given by: \[ \begin{array}{rl} \text{Minimize } & \sum_{i=1}^m{w_ix_i} = \mathbf{w}^T\mathbf{x}\\[3mm] \text{Subject to } & \mathbf{x} \in \mathcal{S} \\ \end{array} \] where $m$ is the number of edges $e_i$ in $G$, $w_i \in \mathbf{w}$ is the weight of edge $e_i$ and $\mathbf{x}$ is the incidence vector indicating the presence or absence of each edge in the tour. Again, the constraints given by $\mathbf{x} \in \mathcal{S}$ are problematic since they have to contain the set of incidence vectors of all possible Hamiltonian cycles in $G$ which amounts to a direct search of all $(n-1)!$ possibilities and thus in general is infeasible. However, relaxed versions of the linear programming problem with removed integrality and sub-tour elimination constraints are extensively used by modern TSP solvers where such a partial description of constraints is used and improved iteratively in a branch-and-bound approach. \subsection{Useful manipulations of the distance matrix} \label{sec:manipulations} Sometimes it is useful to transform the distance matrix $\mathbf{D} = (d_{ij})$ of a TSP into a different matrix $\mathbf{D'} = (d'_{ij})$ which has the same optimal solution. Such a transformation requires that for any Hamiltonian cycle $H$ in a graph represented by its distance matrix $\mathbf{D}$ the equality \begin{equation*} \sum_{i,j \in H}{d_{ij}} = \alpha \sum_{i,j \in H}{d'_{ij}} + \beta \end{equation*} holds for suitable $\alpha > 0$ and $\beta \in \mathbb{R}$. From the equality we see that additive and multiplicative constants leave the optimal solution invariant. This property is useful to rescale distances, e.g., for many solvers, distances in the interval $[0, 1]$ have to be converted into integers from~1 to a maximal value. A different manipulation is to reformulate an asymmetric TSP as a symmetric TSP. This is possible by doubling the number of cities~\citep{Jonker1983}. For each city a dummy city is added. Between each city and its corresponding dummy city a very small value (e.g., $-\infty$) is used. This makes sure that each city always occurs in the solution together with its dummy city. The original distances are used between the cities and the dummy cities, where each city is responsible for the distance going to the city and the dummy city is responsible for the distance coming from the city. The distances between all cities and the distances between all dummy cities are set to a very large value (e.g., $\infty$) which makes these edges infeasible. An example for equivalent formulations as an asymmetric TSP (to the left) and a symmetric TSP (to the right) for three cities is: \begin{equation*} \begin{pmatrix} 0 &d_{12} &d_{13} \\ d_{21} &0 &d_{23} \\ d_{31} &d_{32} &0 \\ \end{pmatrix} \Longleftrightarrow \begin{pmatrix} 0 &\infty &\infty & -\infty &d_{21} &d_{31} \\ \infty &0 &\infty & d_{12} &-\infty &d_{31} \\ \infty &\infty &0 & d_{13} &d_{23} &-\infty \\ -\infty &d_{12} &d_{13} & 0 &\infty &\infty \\ d_{21} &-\infty &d_{23} & \infty &0 &\infty \\ d_{31} &d_{32} &-\infty & \infty &\infty &0 \\ \end{pmatrix} \end{equation*} Instead of the infinity values suitably large negative and positive values can be used. The new symmetric TSP can be solved using techniques for symmetric TSPs which are currently far more advanced than techniques for ATSPs. Removing the dummy cities from the resulting tour gives the solution for the original ATSP. \subsection{Finding exact solutions for the TSP} \label{sec:exact} Finding the exact solution to a TSP with $n$ cities requires to check $(n-1)!$ possible tours. To evaluate all possible tours is infeasible for even small TSP instances. To find the optimal tour \cite{Held1962} presented the following \emph{dynamic programming} formulation: Given a subset of city indices (excluding the first city) $S \subset \{2, 3, \dots, n\}$ and $l \in S$, let $d^*(S, l)$ denote the length of the shortest path from city $1$ to city $l$, visiting all cities in $S$ in-between. For $S = \{l\}$, $d^*(S,l)$ is defined as $d_{1l}$. The shortest path for larger sets with $|S| > 1$ is \begin{equation} d^*(S,l) = \mathrm{min}_{m \in S\setminus\{l\}}\Bigl( d^*(S\setminus\{l\},m) + d_{ml}\Bigl). %\text{ for } |S| > 1. \end{equation} Finally, the minimal tour length for a complete tour which includes returning to city $1$ is \begin{equation} d^{**} = \mathrm{min}_{l \in \{2,3,\dots,n\}}\Bigl( d^*(\{2,3,\dots,n\}, l) + d_{l1}\Bigl). \end{equation} Using the last two equations, the quantities $d^*(S,l)$ can be computed recursively and the minimal tour length $d^{**}$ can be found. In a second step, the optimal permutation $\pi = \{1, i_2, i_3,\dots,i_n\}$ of city indices $1$ through $n$ can be computed in reverse order, starting with $i_n$ and working successively back to $i_2$. The procedure exploits the fact that a permutation $\pi$ can only be optimal, if \begin{equation} d^{**} = d^*(\{2,3,\dots,n\}, i_n) + d_{i_n1} \end{equation} and, for $2 \le p \le n-1$, \begin{equation} d^*(\{i_2, i_3,\dots, i_p, i_{p+1}\}, i_{p+1}) = d^*(\{i_2,i_3,\dots,i_p\}, i_p) + d_{i_pi_{p+1}}. \end{equation} The space complexity of storing the values for all $d^*(S,l)$ is $(n-1)2^{n-2}$ which severely restricts the dynamic programming algorithm to TSP problems of small sizes. However, for very small TSP instances this approach is fast and efficient. %\marginpar{time complexity if order $n^22^n$. Check!} A different method, which can deal with larger instances, uses a relaxation of the linear programming problem presented in Section~\ref{sec:formulations} and iteratively tightens the relaxation till a solution is found. This general method for solving linear programming problems with complex and large inequality systems is called \emph{cutting plane method} and was introduced by \cite{Dantzig1954}. Each iteration begins with using instead of the original linear inequality description $\mathcal{S}$ the relaxation $A\mathbf{x} \le b$, where the polyhedron $P$ defined by the relaxation contains $\mathcal{S}$ and is bounded. The optimal solution $\mathbf{x}^*$ of the relaxed problem can be obtained using standard linear programming solvers. If the $\mathbf{x}^*$ found belongs to $\mathcal{S}$, the optimal solution of the original problem is obtained, otherwise, a linear inequality can be found which is satisfied by all points in $\mathcal{S}$ but violated by $\mathbf{x}^*$. Such an inequality is called a cutting plane or cut. A family of such cutting planes can be added to the inequality system $A\mathbf{x} \le b$ to obtain a tighter relaxation for the next iteration. If no further cutting planes can be found or the improvement in the objective function due to adding cuts gets very small, the problem is branched into two sub-problems which can be minimized separately. Branching is done iteratively which leads to a binary tree of sub-problems. Each sub-problem is either solved without further branching or is found to be irrelevant because its relaxed version already produces a longer path than a solution of another sub-problem. This method is called \emph{branch-and-cut}~\citep{Padberg1990} which is a variation of the well known \emph{branch-and-bound}~\citep{Land1960} procedure. The initial polyhedron $P$ used by \cite{Dantzig1954} contains all vectors $\mathbf{x}$ for which all $x_e \in \mathbf{x}$ satisfy $0 \le x_e \le 1$ and in the resulting tour each city is linked to exactly two other cities. Various separation algorithms for finding subsequent cuts to prevent sub-tours (\emph{sub-tour elimination inequalities}) and to ensure an integer solution \citep[\emph{Gomory cuts;}][]{Gomory1963} were developed over time. The currently most efficient implementation of this method is \emph{Concorde} described in~\cite{Applegate2000}. \subsection{Heuristics for the TSP} \label{sec:heuristics} The NP-completeness of the TSP already makes it more time efficient for small-to-medium size TSP instances to rely on heuristics in case a good but not necessarily optimal solution is sufficient. TSP heuristics typically fall into two groups, tour construction heuristics which create tours from scratch and tour improvement heuristics which use simple local search heuristics to improve existing tours. In the following we will only discuss heuristics available in \pkg{TSP}, for a comprehensive overview of the multitude of TSP heuristics including an experimental comparison, we refer the reader to the book chapter by \cite{Johnson2002}. \subsubsection{Tour construction heuristics} The implemented tour construction heuristics are the nearest neighbor algorithm and the insertion algorithms. \paragraph{Nearest neighbor algorithm.} The nearest neighbor algorithm~\citep{Rosenkrantz1977} follows a very simple greedy procedure: The algorithm starts with a tour containing a randomly chosen city and then always adds to the last city in the tour the nearest not yet visited city. The algorithm stops when all cities are on the tour. An extension to this algorithm is to repeat it with each city as the starting point and then return the best tour found. This heuristic is called repetitive nearest neighbor. \paragraph{Insertion algorithms.} All insertion algorithms~\citep{Rosenkrantz1977} start with a tour consisting of an arbitrary city and then choose in each step a city $k$ not yet on the tour. This city is inserted into the existing tour between two consecutive cities $i$ and $j$, such that the insertion cost (i.e., the increase in the tour's length) $$d(i,k) + d(k,j) - d(i,j)$$ is minimized. The algorithms stop when all cities are on the tour. The insertion algorithms differ in the way the city to be inserted next is chosen. The following variations are implemented: \begin{description} \item[Nearest insertion] The city $k$ is chosen in each step as the city which is nearest to a city on the tour. \item[Farthest insertion] The city $k$ is chosen in each step as the city which is farthest from any of the cities on the tour. \item[Cheapest insertion] The city $k$ is chosen in each step such that the cost of inserting the new city is minimal. \item[Arbitrary insertion] The city $k$ is chosen randomly from all cities not yet on the tour. \end{description} The nearest and cheapest insertion algorithms correspond to the minimum spanning tree algorithm by \cite{Prim1957}. Adding a city to a partial tour corresponds to adding an edge to a partial spanning tree. For TSPs with distances obeying the triangular inequality, the equality to minimum spanning trees provides a theoretical upper bound for the two algorithms of twice the optimal tour length. The idea behind the farthest insertion algorithm is to link cities far outside into the tour first to establish an outline of the whole tour early. With this change, the algorithm cannot be directly related to generating a minimum spanning tree and thus the upper bound stated above cannot be guaranteed. However, it can was shown that the algorithm generates tours which approach $2/3$ times the optimal tour length~\citep{Johnson1985}. \subsubsection{Tour improvement heuristics} Tour improvement heuristics are simple local search heuristics which try to improve an initial tour. A comprehensive treatment of the topic can be found in the book chapter by \cite{Rego2002}. \paragraph{$k$-Opt heuristics.} The idea is to define a neighborhood structure on the set of all admissible tours. Typically, a tour $t'$ is a neighbor of another tour $t$ if $t'$ can be obtained from $t$ by deleting $k$ edges and replacing them by a set of different feasible edges (a $k$-Opt move). In such a structure, the tour can iteratively be improved by always moving from one tour to its best neighbor till no further improvement is possible. The resulting tour represents a local optimum which is called $k$-optimal. Typically, $2$-Opt~\citep{Croes1958} and $3$-Opt~\citep{Lin1965} heuristics are used in practice. \paragraph{Lin-Kernighan heuristic.} This heuristic~\citep{Lin1973} does not use a fixed value for $k$ for its $k$-Opt moves, but tries to find the best choice of $k$ for each move. The heuristic uses the fact that each $k$-Opt move can be represented as a sequence of $2$-Opt moves. It builds up a sequence of $2$-Opt moves, checking after each additional move whether a stopping rule is met. Then the part of the sequence which gives the best improvement is used. This is equivalent to a choice of one $k$-Opt move with variable $k$. Such moves are used till a local optimum is reached. By using full backtracking, the optimal solution can always be found, but the running time would be immense. Therefore, only limited backtracking is allowed in the procedure, which helps to find better local optima or even the optimal solution. Further improvements to the procedure are described by \cite{Lin1973}. \section{Computational infrastructure: the TSP package} \label{sec:infrastructure} In package~\pkg{TSP}, a traveling salesperson problem is defined by an object of class \class{TSP} (symmetric) or \class{ATSP} (asymmetric). \func{solve\_TSP} is used to find a solution, which is represented by an object of class \class{TOUR}. Figure~\ref{fig:overview} gives an overview of this infrastructure. \begin{figure} \centering \includegraphics[width=14cm]{overview} \caption{An overview of the classes in \pkg{TSP}.} \label{fig:overview} \end{figure} \class{TSP} objects can be created from a distance matrix (a \class{dist} object) or a symmetric matrix using the creator function \func{TSP} or coercion with \func{as.TSP}. Similarly, \class{ATSP} objects are created by \func{ATSP} or \func{as.ATSP} from square matrices representing the distances. In the creation process, labels are taken and stored as city names in the object or can be explicitly given as arguments to the creator functions. Several methods are defined for the classes: \begin{itemize} \item \func{print} displays basic information about the problem (number of cities and the distance measure employed). \item \func{n\_of\_cities} returns the number of cities. \item \func{labels} returns the city names. \item \func{image} produces a shaded matrix plot of the distances between cities. The order of the cities can be specified as the argument \code{order}. \end{itemize} Internally, an object of class \class{TSP} is a \class{dist} object with an additional class attribute and, therefore, if needed, can be coerced to \class{dist} or to a matrix. An \class{ATSP} object is represented as a square matrix. Obviously, asymmetric TSPs are more general than symmetric TSPs, hence, symmetric TSPs can also be represented as asymmetric TSPs. To formulate an asymmetric TSP as a symmetric TSP with double the number of cities (see Section \ref{sec:manipulations}), \func{reformulate\_ATSP\_as\_TSP} is provided. This function creates the necessary dummy cities and adapts the distance matrix accordingly. A popular format to save TSP descriptions to disk which is supported by most TSP solvers is the format used by \emph{TSPLIB}, a library of sample instances of the TSP maintained by \cite{Reinelt2004}. The \pkg{TSP} package provides \func{read\_TSPLIB} and \func{write\_TSPLIB} to read and save symmetric and asymmetric TSPs in TSPLIB format. Class \class{TOUR} represents a solution to a TSP by an integer permutation vector containing the ordered indices and labels of the cities to visit. In addition, it stores an attribute indicating the length of the tour. Again, suitable \func{print} and \func{labels} methods are provided. The raw permutation vector (i.e., the order in which cities are visited) can be obtained from a tour using \func{as.integer}. With \func{cut\_tour}, a circular tour can be split at a specified city resulting in a path represented by a vector of city indices. The length of a tour can always be calculated using \func{tour\_length} and specifying a TSP and a tour. Instead of the tour, an integer permutation vector calculated outside the \pkg{TSP} package can be used as long as it has the correct length. All TSP solvers in \pkg{TSP} can be used with the simple common interface: \begin{quote} \code{solve\_TSP(x, method, control)} \end{quote} where \code{x} is the TSP to be solved, \code{method} is a character string indicating the method used to solve the TSP and \code{control} can contain a list with additional information used by the solver. The available algorithms are shown in Table~\ref{tab:methods}. \begin{table} \caption{Available algorithms in \pkg{TSP}.} \label{tab:methods} \centering \begin{tabular}{llc} \hline \textbf{Algorithm} & \textbf{Method argument} & \textbf{Applicable to} \\ \hline Nearest neighbor algorithm & \code{"nn"} & TSP/ATSP \\ Repetitive nearest neighbor algorithm & \code{"repetitive\_nn"} & TSP/ATSP \\ Nearest insertion & \code{"nearest\_insertion"} & TSP/ATSP \\ Farthest insertion & \code{"farthest\_insertion"} & TSP/ATSP \\ Cheapest insertion & \code{"cheapest\_insertion"} & TSP/ATSP \\ Arbitrary insertion & \code{"arbitrary\_insertion"} & TSP/ATSP \\ Concorde TSP solver & \code{"concorde"} & TSP \\ 2-Opt improvement heuristic & \code{"two\_opt"} & TSP/ATSP \\ Chained Lin-Kernighan & \code{"linkern"} & TSP \\ \hline \end{tabular} \end{table} All algorithms except the Concorde TSP solver and the Chained Lin-Kernighan heuristic (a Lin-Kernighan variation described in \cite{Applegate2003}) are included in the package and distributed under the GNU Public License (GPL). For the Concorde TSP solver and the Chained Lin-Kernighan heuristic only a simple interface (using \func{write\_TSPLIB}, calling the executable and reading back the resulting tour) is included in \pkg{TSP}. The executable itself is part of the Concorde distribution, has to be installed separately and is governed by a different license which allows only for academic use. The interfaces are included since Concorde~\citep{Applegate2000,Applegate2006} is currently one of the best implementations for solving symmetric TSPs based on the branch-and-cut method discussed in section~\ref{sec:exact}. In May 2004, Concorde was used to find the optimal solution for the TSP of visiting all 24,978 cities in Sweden. The computation was carried out on a cluster with 96 Xeon 2.8 GHz nodes and took in total almost 100 CPU years. \section{Examples} \label{sec:examples} In this section we provide some examples for the use of package~\pkg{TSP}. We start with a simple example of how to use the interface of the TSP solver to compare different heuristics. Then we show how to solve related tasks, using the Hamiltonian shortest path problem as an example. Finally, we give an example of clustering using the \pkg{TSP} package. An additional application can be found in package \pkg{seriation}~\citep{TSP:Hahsler+Buchta+Hornik:2006} which uses the TSP solvers from \pkg{TSP} to order (seriate) objects given a proximity matrix. \subsection{Comparing some heuristics} In the following example, we use several heuristics to find a short path in the \code{USCA50} data set which contains the distances between the first 50 cities in the \code{USCA312} data set. The \code{USCA312} data set contains the distances between 312 cities in the USA and Canada coded as a symmetric TSP. The smaller data set is used here, since some of the heuristic solvers employed are rather slow. <<>>= library("TSP") data("USCA50") USCA50 @ We calculate tours using different heuristics and store the results in the list \code{tours}. As an example, we show the first tour which displays the method employed, the number of cities involved and the tour length. All tour lengths are compared using the dot chart in Figure~\ref{fig:dotchart}. For the chart, we add a point for the optimal solution which has a tour length of 14497. The optimal solution can be found using Concorde (\code{method = "concorde"}). It is omitted here, since Concorde has to be installed separately. <>= set.seed(1234) @ <>= methods <- c("nearest_insertion", "farthest_insertion", "cheapest_insertion", "arbitrary_insertion", "nn", "repetitive_nn", "two_opt") tours <- sapply(methods, FUN = function(m) solve_TSP(USCA50, method = m), simplify = FALSE) ## tours$concorde <- solve_TSP(tsp, method = "concorde") tours[[1]] dotchart(sort(c(sapply(tours, tour_length), optimal = 14497)), xlab = "tour length", xlim = c(0, 20000)) @ \begin{figure} \centering \includegraphics[width=11cm, trim=0 10 0 0]{TSP-dotchart_USCA50} \caption{Comparison of the tour lengths for the USCA50 data set.} \label{fig:dotchart} \end{figure} \subsection{Finding the shortest Hamiltonian path} The problem of finding the shortest Hamiltonian path through a graph (i.e., a path which visits each node in the graph exactly once) can be transformed into the TSP with cities and distances representing the graphs vertices and edge weights, respectively~\citep{Garfinkel1985}. Finding the shortest Hamiltonian path through all cities disregarding the endpoints can be achieved by inserting a `dummy city' which has a distance of zero to all other cities. The position of this city in the final tour represents the cutting point for the path. In the following we use a heuristic to find a short path in the \code{USCA312} data set. Inserting dummy cities is performed in \pkg{TSP} by \func{insert\_dummy}. <>= set.seed(1234) @ <<>>= library("TSP") data("USCA312") tsp <- insert_dummy(USCA312, label = "cut") tsp @ The TSP now contains an additional dummy city and we can try to solve this TSP. <<>>= tour <- solve_TSP(tsp, method="farthest_insertion") tour @ Since the dummy city has distance zero to all other cities, the path length is equal to the tour length reported above. The path starts with the first city in the list after the `dummy' city and ends with the city right before it. We use \func{cut\_tour} to create a path and show the first and last 6 cities on it. <<>>= path <- cut_tour(tour, "cut") head(labels(path)) tail(labels(path)) @ The tour found in the example results in a path from Lihue on Hawaii to Prince Rupert in British Columbia. Such a tour can also be visualized using a scatter plot with a map from package \pkg{maps}. Note that the \code{if} statement and the \code{plot} in the \code{else} part in the following is not needed and only checks if the map package is installed when building this document. <>= if(require(maps)) { library("maps") data("USCA312_GPS") plot_path <- function(path) { plot((USCA312_GPS[, c("long", "lat")]), cex = .3, col = "red") map("world", col = "gray", add = TRUE) lines(USCA312_GPS[, c("long", "lat")][path,], col = "black") points(USCA312_GPS[c(head(path, 1), tail(path, 1)), c("long", "lat")], pch = 19, col = "black") } plot_path(path) } else { plot(NA, xlim= c(0,1), ylim = c(0,1)) text(.5, .5, "Suggested packages not available") } @ \begin{figure} \centering \includegraphics[width=10cm, trim=0 30 0 0]{TSP-map1} \caption{A ``short'' Hamiltonian path for the USCA312 dataset.} \label{fig:map1} \end{figure} The map containing the path is presented in Figure~\ref{fig:map1}. It has to be mentioned that the path found by the used heuristic is considerable longer than the optimal path found by Concorde with a length of $34928$, illustrating the power of modern TSP algorithms. For the following two examples, we indicate how the distance matrix between cities can be modified to solve related shortest Hamiltonian path problems. These examples serve as illustrations of how modifications can be made to transform different problems into a TSP. The first problem is to find the shortest Hamiltonian path starting with a given city. In this case, all distances to the selected city are set to zero, forcing the evaluation of all possible paths starting with this city and disregarding the way back from the final city in the tour. By modifying the distances the symmetric TSP is changed into an asymmetric TSP (ATSP) since the distances between the starting city and all other cities are no longer symmetric. As an example, we choose New York as the starting city. We transform the data set into an ATSP and set the column corresponding to New York to zero before solving it. Thus, the distance to return from the last city in the path to New York does not contribute to the path length. We use the nearest neighbor heuristic to calculate an initial tour which is then improved using $2$-Opt moves and cut at New York to create a path. <>= set.seed(1234) @ <<>>= atsp <- as.ATSP(USCA312) ny <- which(labels(USCA312) == "New York, NY") atsp[, ny] <- 0 initial_tour <- solve_TSP(atsp, method="nn") initial_tour tour <- solve_TSP(atsp, method ="two_opt", control = list(tour = initial_tour)) tour path <- cut_tour(tour, ny, exclude_cut = FALSE) head(labels(path)) tail(labels(path)) @ <>= plot_path(path) @ \begin{figure} \centering \includegraphics[width=10cm, trim=0 30 0 0]{TSP-map2} \caption{A Hamiltonian path for the USCA312 dataset starting in New York.} \label{fig:map2} \end{figure} The found path is presented in Figure~\ref{fig:map2}. It begins with New York and cities in New Jersey and ends in a city in Manitoba, Canada. %The path shows the typical behavior %of the nearest neighbor heuristic with first connecting the cities close by and %then making rather big ``jumps'' for the final cities. Concorde and many advanced TSP solvers can only solve symmetric TSPs. To use these solvers, we can formulate the ATSP as a TSP using \func{reformulate\_ATSP\_as\_TSP} which introduces a dummy city for each city (see Section~\ref{sec:manipulations}). <<>>= tsp <- reformulate_ATSP_as_TSP(atsp) tsp @ After finding a tour for the TSP, the dummy cities are removed again giving the tour for the original ATSP. Note that the tour needs to be reversed if the dummy cities appear before and not after the original cities in the solution of the TSP. The following code is not executed here, since it takes several minutes to execute and Concorde has to be installed separately. Concorde finds the optimal solution with a length of $36091$. <>= tour <- solve_TSP(tsp, method = "concorde") tour <- as.TOUR(tour[tour <= n_of_cities(atsp)]) @ Finding the shortest Hamiltonian path which ends in a given city can be achieved likewise by setting the row in the distance matrix which corresponds to this city to zero. For finding the shortest Hamiltonian path we can also restrict both end points. This problem can be transformed to a TSP by replacing the two cities by a single city which contains the distances from the start point in the columns and the distances to the end point in the rows. Obviously this is again an asymmetric TSP. For the following example, we are only interested in paths starting in New York and ending in Los Angeles. Therefore, we remove the two cities from the distance matrix, create an asymmetric TSP and insert a dummy city called \code{"LA/NY"}. The distances from this dummy city are replaced by the distances from New York and the distances towards are replaced by the distances towards Los Angeles. <>= set.seed(1234) @ <<>>= m <- as.matrix(USCA312) ny <- which(labels(USCA312) == "New York, NY") la <- which(labels(USCA312) == "Los Angeles, CA") atsp <- ATSP(m[-c(ny,la), -c(ny,la)]) atsp <- insert_dummy(atsp, label = "LA/NY") la_ny <- which(labels(atsp) == "LA/NY") atsp[la_ny, ] <- c(m[-c(ny,la), ny], 0) atsp[, la_ny] <- c(m[la, -c(ny,la)], 0) @ We use the nearest insertion heuristic. <<>>= tour <- solve_TSP(atsp, method ="nearest_insertion") tour path_labels <- c("New York, NY", labels(cut_tour(tour, la_ny)), "Los Angeles, CA") path_ids <- match(path_labels, labels(USCA312)) head(path_labels) tail(path_labels) @ <>= plot_path(path_ids) @ The path jumps from New York to cities in Ontario and it passes through cities in California and Nevada before ending in Los Angeles. The path displayed in Figure~\ref{fig:map3} contains multiple crossings which indicate that the solution is suboptimal. The optimal solution generated by reformulating the problem as a TSP and using Concorde has only a tour length of $38489$. \begin{figure} \centering \includegraphics[width=10cm, trim=0 30 0 0]{TSP-map3} \caption{A Hamiltonian path for the USCA312 dataset starting in New York and ending in Los Angles.} \label{fig:map3} \end{figure} \subsection{Rearrangement clustering} Solving a TSP to obtain a clustering was suggested several times in the literature \citep[see, e.g.,][]{Lenstra1974, Alpert1997, Johnson2004}. The idea is that objects in clusters are visited in consecutive order and from one cluster to the next larger ``jumps'' are necessary. \cite{Climer2006} call this type of clustering \emph{rearrangement clustering} and suggest to automatically find the cluster boundaries of $k$ clusters by adding $k$ \emph{dummy cities} which have constant distance $c$ to all other cities and are infinitely far from each other. In the optimal solution of the TSP, the dummy cities must separate the most distant cities and thus represent optimal boundaries for $k$ clusters. For the following example, we use the well known iris data set. Since we know that the dataset contains three classes denoted by the variable \code{Species}, we insert three dummy cities into the TSP for the iris data set and perform rearrangement clustering using the default method (nearest insertion algorithm). Note that this algorithm does not find the optimal solution and it is not guaranteed that the dummy cities will present the best cluster boundaries. %\marginpar{FIXME: Was sagt Concorde dazu?} <>= set.seed(4444) @ <<>>= data("iris") tsp <- TSP(dist(iris[-5]), labels = iris[, "Species"]) tsp_dummy <- insert_dummy(tsp, n = 3, label = "boundary") tour <- solve_TSP(tsp_dummy) @ Next, we plot the TSP's permuted distance matrix using shading to represent distances. The result is displayed as Figure~\ref{fig:clustering}. Lighter areas represent larger distances. The additional red lines represent the positions of the dummy cities in the tour, which mark the cluster boundaries obtained. <>= ## plot the distance matrix image(tsp_dummy, tour, xlab = "objects", ylab ="objects") ## draw lines where the dummy cities are located abline(h = which(labels(tour)=="boundary"), col = "red") abline(v = which(labels(tour)=="boundary"), col = "red") @ \begin{figure} \centering \includegraphics[width=9cm, height=9cm, trim=0 20 0 0]{TSP-clustering} \caption{Result of rearrangement clustering using three dummy cities and the nearest insertion algorithm on the iris data set.} \label{fig:clustering} \end{figure} One pair of red horizontal and vertical lines exactly separates the darker from lighter areas. The second pair occurs inside the larger dark block. We can look at how well the partitioning obtained fits the structure in the data given by the species field in the data set. Since we used the species as the city labels in the TSP, the labels in the tour represent the partitioning with the dummy cities named `boundary' separating groups. The result can be summarized based on the run length encoding of the obtained tour labels: <<>>= out <- rle(labels(tour)) data.frame(Species = out$values, Lenghts = out$lengths, Pos = cumsum(out$lengths)) @ One boundary perfectly splits the iris data set into a group containing only examples of species `Setosa' and a second group containing examples for `Virginica' and `Versicolor'. However, the second boundary only separates several examples of species `Virginica' from other examples of the same species. Even in the optimal tour found by Concorde, this problem occurs. The reason why the rearrangement clustering fails to split the data into three groups is the closeness between the groups `Virginica' and `Versicolor'. To inspect this problem further, we can project the data points on the first two principal components of the data set and add the path segments which resulted from solving the TSP. <>= prc <- prcomp(iris[1:4]) plot(prc$x, pch = as.numeric(iris[,5]), col = as.numeric(iris[,5])) paths <- cut_tour(tour, cut = "boundary") for(p in paths) lines(prc$x[p, ]) @ \begin{figure} \centering \includegraphics[width=10cm, trim=0 20 0 0]{TSP-clustering2} \caption{The 3 path segments representing a rearrangement clustering of the iris data set. The data points are projected on the set's first two principal components. The three species are represented by different markers and colors.} \label{fig:clustering2} \end{figure} The result in shown in Figure~\ref{fig:clustering2}. The three species are identified by different markers and all points connected by a single path represent a cluster found. Clearly, the two groups to the right side of the plot are too close to be separated correctly by using just the distances between individual points. This problem is similar to the \emph{chaining effect} known from hierarchical clustering using the single-linkage method. \section{Conclusion} \label{sec:conclusion} In this paper we presented the R extension package \pkg{TSP} which implements an infrastructure to handle and solve TSPs. The package introduces classes for problem descriptions (\class{TSP} and \class{ATSP}) and for the solution (\class{TOUR}). Together with a simple interface for solving TSPs, it allows for an easy and transparent usage of the package. With the interface to Concorde, \pkg{TSP} also can use a state of the art implementation which efficiently computes exact solutions using branch-and-cut. \section*{Acknowledgments} The authors of this paper want to thank Roger Bivand for providing the code to correctly draw tours and paths on a projected map. % %\bibliographystyle{abbrvnat} \bibliography{TSP} % \end{document} TSP/inst/doc/TSP.pdf0000644000176200001440000153336514412674612013632 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 4631 /Filter /FlateDecode /N 85 /First 714 >> stream x\is86S[!q[SɎ=ܳLQ$D_> Hɖ'-4ݍ 0"čTtƙɸ28y+a2q% dqq pe& pe\gR↛L hC)wt|iPg; zl,chDgVjܛr6N949Ϝ@G$d{0%E`&LKy]&u5#2o/t;i{/c^f }a'8`Xd*<Ҩ)Bxp MA{P'y*H-Z$Y ei &S'U1PV `xrh€hрCt@.,.@Yf)5)҂A?2RbI l4Zl 7Bh2(ǒ]qm>P Ⱥ,(f5y^o/<;G +}/Nu?t^y'^|O=gd1+LfgI 9Jo qT $T G@3kX!xW:''$`& r fC?a]r׷`8.^/QQS1+E(EK@@!MtqI:S5tplr2-)`0}N!NƏgd607ɋbx;)ަN*Dkxǫq.̧3p[W+ m|mdGFG{֚@< ~t1T 9|"/T@, ?b!J3!v>2qE [iF2f,%LG߂u-86-'~xVVOU](x>ϊSx9;-ϋM8s?iYc2?eYT_eR|-u |zwu7H:sI$t_?:MCCu1⸁ݘPTa3s 7CD+{s-*߂k =?o1ʢXQfGÑ6ø2(HnWj4Q%kQ>tEd? 08J|F,Й69`V gg*4Hs_@C.ow@h|YtR.dفӧQ%jm 4%tu⼜ aQ WOM˳*^-a]Ϋ4obp> #3^N)1M2-[.+I\o)%ރȄ/-DnFQo^se lo@H 5뎾Ż4Gܱ"" qį2(4b3A9.qpB2ǔOA΄avVXן_8#kuoƙU6vʗ|=v}`d[[#C?~~|͖7иQ|Ĩ89];kuaHa6Lwg*)0 QmX,-c ZۀwC{4c[= wxٕ!UUL0L%Λu!Mo[{]<ӯLnfetu9t)擎LsZwzSy3_nk3)k V vlܺ/"WwǛL:=%wz2&Fr5LKU9H!rXdgjH 2.xZ8siKtNkf~.9i&ڙnڄH ͉G^mdFN_]eȅ -y]`ptm4yJ}Sv%ooxew͵I`R=-Ⱦ6KcK5`>Q :I_B̨.7&gFgʽFB݆qMNdI أ5Ӛ<b3!:m҉'8"eI2H$OIQiy88WR4^9u)$i08bK)E.^ؕ$%v&=Itx*W+2BTrk#,K0# 9aX'S/ֳSj9 }땾:hWikL^ЗS;YZQỶ _kҸ/kG_kE*u]4%g3w,o^$vktkp>ȅz7a~o7wuz7G=ZӬF-i둲&ni[(Af7h-GY̫#!i枾=o9?cœ/0*eN)Daun Fe}X-΅%a*ixҘ8A(x`3.M/ɳ1wуgQ|%GLaO,l"&[ӼMô]0~:D:+CCk/vq6L |RZ uGR)SA.endstream endobj 87 0 obj << /Subtype /XML /Type /Metadata /Length 1532 >> stream GPL Ghostscript 9.55.0 combinatorial optimization, traveling salesman problem, R 2023-04-03T20:12:42-05:00 2023-04-03T20:12:42-05:00 LaTeX with hyperref TSP � Infrastructure for the Traveling Salesperson ProblemMichael Hahsler, Kurt Hornik endstream endobj 88 0 obj << /Type /ObjStm /Length 4042 /Filter /FlateDecode /N 85 /First 785 >> stream x[Ys~ϯǤT*wVh)?P$!H-A}o@RКZUJq f", &fQ29YGǢaRYL:mn(,)i)+VdL+q8QL@w43 Ha162ੌgV(tT&2тYPXJf f6?) s¡ zJh"6K}K NR-0*GxGN2jM4P[E\jDkfuԇ64RpP>TP}D)7ƟǓY! :txQJL=z f#3ox /'Y^2j%jK\Kώ|_or2elA ݾ@jM u-I꣮>꣯ut9~u3u}>SgL]%IXop2OW?~㿾;<Lc) G/gb|fUje1-gϮSUlZ&SZaRa]f?RA6H+#T@@ӏ5’Z}lRT V 9(=J4&b,=&$:7%,~9ai+\tΰ:Mȍ1h{Αt PғO gDgÛyqy\b OƟ%_7{~ȏ_!?gl2_ +%W_o1/g>|'EGŬ:~O9Oy4oW-N81r4,AĔjzIkJT=Yrk|(;(K=,~ cWޙE_xsdt2@qY,o,'dr$zNM_pg-cps4]cus#euM3XVȨ\uAFjԊY$ 6ޒw/Kǯ?-,&wM|.U0w Hoaa6MiIKY4]g;(.yey>Y1oU;y']r=XhuyE+&EumMV"T6 ,FIu/'{Z'J mrsJ-f\gmc.*&]ۃU}4wdzOkw>yF1/X> '0Е L|4ri-3IΩՙ1uȜ&wf2Ƈs-vC RwJК,Z [ɔ!Yeކ1V0Ӳ`"63V>&˂mLPy6]A3? zhDȄEim2@gtVS@ PP:2,@2<ypơ6( M; !lpJq{ JeLaJ?)<7!20K`l'5 m4QX ͈z{5w1{q`kV+imUY/>>}eko6:.ߓ߫Sm>l6WνY~&g@p0eV]]\}6ڧ`uw9;D'ߟ|wtrpD/2tv-Ά J:nA:&wTroa)YlM> "i$dԟ'nC[.pXKjByM!/i"VH8. v= (F w,3{ZZh_",k/:|@uӝyW߯8=פ5ZY^zOlOLwz)-wuc~RwDPZz|guN$ #r!fQ?4ɶRf[Ě #e"36,0)e2EI$5J֙;1Cq>Y'FK<&1%Ԙ,&L?!{,vt.3408IԄ 12 NnI^lL-mRČ[(.AAgfjx,P\GQ:#3<e ʑoPO#@Y7X=(gX "iMT&Zo2k"\ VabA:)Q0iA[b"E_G ; )nEWWQ^Vtdb'cdW'%:)U맕^Xߞj ~y{pmr.E4$̚ J_3?& 4/**PJdK TzƵ42z:mNRe)YvcN?mWکLdk/@~/pOWsnn)'岍 8i>-KJMtܴ e>秣:9WT_g x>1ƭJbn,Pd2ٶ'r; ΈFL޾yps &(D+PbkMŎ;T7FYJ4$QJ)~kU .׆)UH=C%f[4k\ƃoEH,sUUݱo{~gp-u,tF|Æ&kMQ;2iznߕ(YչhA4Qs>ES ?PZ"MwX#L$C~=T ʷ>2u}yVaVT]7׻e'ö4aU=}H78Bn ӏ"k 21)A[ Ovnm h~"A^Sj 8[Uj7[K#VsZ:8[M!gklǵ'UZ=}4UÞϻn r6BXzr,ZjK.ULI:S)}<ي3\/ >\|}W?a֤-棙~&aݢ/.+6W?endstream endobj 174 0 obj << /Type /ObjStm /Length 2937 /Filter /FlateDecode /N 85 /First 781 >> stream x[n}Wc=U} 7F67 (LpI`PCtUˌm('5Ye>f4Љ wo"CWdG#($(pD#)Jx Fq5[X'b6@(1)g„9(g0Q9F#)h(ɠa7! :a9q{KhxCQAdACJ#@C .`A)BU:Ǣ֫( *Z@IOV1b1c;'} Ub!r*9%" )e"ITNFLlUf蓘`͞TIxA,JP(ZTT x)`" `@f3-e Y'XEk ebQxp M `51%Mu=@5(D%XdsSռSOj~Xީq_(BMe/WWT57&t{}Vr{f]9!sמooض^]-1>zLԳgXؙN]]:Ƶm9, E oPU~?Ƕ}u 18i^6ϛdwV3hywEJօ[leoaCzE^=:FߺybVL@SCt:’'2dPvDfb/[gd7;A=4N--l:9Ɍ!}HQE?R6ߴmi0D3y_\ 2^WCgZŜy2f;yZ]b/q8jիPQWw-b˳׿cgŷ9dڙŭ0[qU" C)v2ՇDML hֲ:+rRSe.W .0tYtxnj茬@phӋʿTo18E|cV7W_k;J))zab3?5? 8&*l&- :@?UcXNGzw 3b>mF_ ⾦R.aǍR;:s΃+\֜#}\cz\*ʥr \ŕC2N5xf\90 ?]v4u+?(nl{Ə4AV;;C~=W9_\\,nLjMG#zḞגN4\z#$4#6t l=}rNNfZx *X5c H`# w WgQ@͵3AMa w6 xKi(6 `bI2}@$wێXN] yUkܵ"ҵʾk'N 6- qi'Ea?}'?ޝ]-UrA5E ^~<߶l I,?]ߔ*U5N;&Z wsDc}C811|,+'}+;ya9!˳_,?|-ҤF@Csss,ͲԬss6w͗淿*s<]zѹc".+?Z^-XqWo>-QF{}5p~[h Do->KjAcɎRwd;C6b5}@*UK-lRw:087=LT|q. !i)wvK] t P'lg 6dn-͐u00IQq0E R)#|LM- m] WAʰ:ѝfH.Y[jG'"JM:ep2)joT5bp9KQM:)kq@YIJRZQAPM}O_Y`uoTaEZ!5KZD[#e] ՙ7v7&Gp4-uxt \V8kg=~RiES:}TiyMОR ؍os@m7޸EށꝊtNT,1#RI(Rˉ<<ӄ !a$>δ|(8'm{DU 7K [.OZ> stream x[Isƕ3spcrt=S X剶DLzhMB]j;?dޒ d([r@*oޖæŦpln/~v]67Jn0zswZllwvԍ(U}gmk|V"4^qQ/BT/a3՟1TO:XeT5 Wo'|0[ wi@`PXnLUp\uoyoMm^xe:oHBqnAקa{}<1|eDcfgWg+Pꮽ٧nLV62Ղ'q i!r6@{XM,#/CFenXA4=l$kM1IOgkF\~<&/fΞlɶvPc,Ǯg[j%E.FhKU9kinb|a3xH!1gohӵEd<&nc=a 5e6dL'I_}xR\!![%<[H 7NCi`z! BV$@-D X S%gOg* F/R^_ ku>}~ ; 0GJ08!d<-Հ U(P|H yp.YqЀPhYCنQ4zxo~A ̌hX90@Ex!gJUݿtLU-ܢ`F *Y[>cgʾ/ d83"-CUаo8w|^g|]?.ivsm:2)b+"? V/d0%Ȟc_bumeJhTMH1Q7}̖QX\\椗aX& ed8 $x , Z)xm Hp9=*2}VqE jT$D "1-|^KIFD.s &*'1)3ϹV{~Zujr‹ 1}ʯ:oFiYiSg!Br W v]nK% 1[Z3k-7UGAHw@Lfvfredd@\//uYCvflSBPD捡42xG[XL#]@;aRA>.U{ t7f.F9r݀-E?Ke,f}fqs/Ph<~W!* ѿ~Gx\W[±onjp;.MN&c"cI:,eE i.P#w{WԼе; Bo|!/TuARTccoY^\?\WۣR1a*Z|cX׳n.c&IƹY,c8QE~Xh4˞ܐr;vX~ٜQj*|E|ncc$j}}[avo %85+Jn\z+xtH +.Y^MCtPjO}! s~. b]:H,2 Bd@\IEu><$0#~{Dе<wA af{amMݲH'#~5Hr I"kI HUm, )1xuc@aK-&!o6*~4 Ot0g/1* QbqۆĨ.]b=9%ԘbFVcljRbQ 䰛ன_ˋrϖKJ8=@&2T9j#HL5rE4Woj̺ť'U1#w yJ###Ș{n%c؄3Hu][ +v\$5.r?!q+95r8A i)1gxoQRӵP:j>!m&Нj]jJPm2.jY :`Qc]ܐMqFq \p,:0[`Vu ШOhd B )8.B-U?WJ. wD=sZcQh))nCmF_3o@ +Y[e>+ ?#WS5uDg&m<nW}b\C[7qm+zpq[1ܤGCz 5c9lzMΎRcgIS<)IX3ӣg@/V@bM6xsJ3X28bq䷫9)a_Z{!/@R3~TTM%V7x lv t "ͩxASږ=S-̺Øz~xʬ _%q?!|z~JKKĦ7ۘ.xlMi <'>UtRI[E/ed>rP9f1#ekjC?i,q-zfoq#FWs]ЖnH8"oyWC>sZTs)KoS<| "6; @tDVB Pegy_"_Dӯ *fe)fqH '>Mʦ= ̱)@g<ɯ4jyN&#E l6[JQQTal$E=~FK\E=Vw+)e. x f?fl-؋/}".Pf e-4xQ$h,$Ihι|;iX͛c~lE gG7/bš?yک9(u0Y^U3Flf5|gQ%kYgm/ӽ'-L%PqWd&ϧ4DWq= z\7c憇 Nv:wY'kKs|^&'vS^c7vŜFQtxmSX"0^bӊ~! Njm&)89g.,A{8Bq7[ 5U:lql5lv{ciLTO'?1{BCh:"( KRx=?FEWDO1Z9Lvg"31 <;0T8͡64ufsXԏ)"nƮ.6 w13lSz!|@dodendstream endobj 261 0 obj << /Filter /FlateDecode /Length 6293 >> stream x\KFr/h7bn880]؍=HjeEX+MC!vOS&w>zLPϬ/̪.V\t/r}AO//]?'mD\xqk{e.Oyy+}Vv_a96ӗʯ֡㬀؂?k~䙰ﲁa |_݄)I5w&vNla!w5GS"ѩTUWdz Ȯ 8 m}]һݘ :XpGΑSA'(x<^NC\awu3l>w>\;FY5%*6>[D:u64)E/ja=_km䝶K'VS ^6qQɱޖ5>]]iВ҂^+i$f J\+ipAʤ {MpILv8V &/1mlf&n:^)3_x0\7xIT ߆@KN Æ>k"n54 a\`/͖ B)ox6YY !M^.U+ }8-S5tS(8iڥv1Am8 LB߼npm֋L=STn{?s@hy,nxKMҭ7.;Z;zi`}RWh$R/QTNRfi* gnJkZ ˽I%4 .l/ AçcK"9hVLsS5`plO+ Y _Ra - F6: +6=" s~>孛.pubm84FLj4L ] oLh>W }iwii>xGhxoa53w|ܥIq.^ ~@9P4hy7Lt+|i8)&wX_m/"/cȇ#܍ ՘zz&N5e9>}̶tR]t *` :iCYN4W)}3 ?Q;NK!)f%ЭV'Vm]m"Rvo^{Q4EPF.6<ǽĭkE mX3fTUŵ1>i:#0U~3;#zZ}ǢcumlްZW\Hc5EtIs=e $d-)Y) :| t{~eE3O1 YiRV҅\z0T_WX9%(H3oSCE/> .KNPet͝ANkj$[ԦNmve%g,= LJ`iڕM-T7".W#lS`9g˙c JRE }>pee !Xe`úl Qy+ *%84(l\~(ztDٸ^9D ǹͱDAS0bw%4݄ k0%R%)3s~.lgF-\` by2SڼM 1G4 {r8C!ftp,'rȞ H3d@mjҨкOc.9@Ҏ;&@+E.l ޅ;ȥ 2o6m1 NϐqEV*Ɓ>CX 㹭mB$Nڬ1֭ز~K!*`ur̺>86q!=U0`"=ǐKT*{C9Ia_rhT9_cyv0 *nBbEBx+bribJݷF-_~qBy{Vvb=|ʧB UA8*F#T+Eÿku5 L>@8JaKsqbul*[gdN*poM:* ^ Vb1 K.ֹ_BMs[WWƓWh2eGRmv|cdv^J,6>T~8@gib|~kStC3P(ŽBRZ)iQ$5t|^[ULVp1Y׵jVXfZ<7 c PH7~g Ul}CpEk>ЁKzxEm$ZsrDqW Pamk%2M8BhyȠt\ &.pswj2M]Zs Zc)iM[6~N.GlAӂԗ0.4Ns)erH#(?%F]AQDYh<'mV9/Xp\>2nm 0ok b/Z?f|cI_+E,8>tʃ|fXzI1y ghEmK$`*e1)ȣ`zAs54RHؤ+@oy=8TT)#CR3dĭ*:? U=ګXw"Fz);U^%i>Gl)̊EXY+ Aҥ+ tXn<̐ňq7>{YEQl* *{nb4 /s5 upn5MM+c2 崝=#|,!3H4SDf ̳0FL W+![8u Wjzuw>p23*Xd)) e.͘C-&4Uh.;]gC*Sd8h\}^X 'kExfE}3Zt6MrvTIt׹,!W tTq,)BKV Oy:sg *@cӇ(XV0M(&1yu\p.ИgZ|YH4\05Wq,)XWk:o63sfcxm|y%!ZScn?\u+Zmbi ̇Vԣ60Bċ]Scy 7Gx0 b 7ZiQNHy`Eָ.2 $E #t,zjcXD*XdZz@ӝ i؟3»(yTkB ݮoEWηrxM( (| kg*عӹP*#:W~.f &^r(OW}+I7R x(˴ G4ˬx(!z숎A`*6c8|V /;^*W-?'Lԋ?p)J.Pа0b-p+@sj)|h+&Q:6BtaPm*q>kM15Ia5'7Ŀw_|[r "Jd;jJ}7tY%}7!E)Jr-_f\#Kn9Jl>s!7"I3a'e!.x|dn`"6"( bja﹫^<~%,p7[ol^Oᖫ лqLϧW'W)>{ҋ`61WK3FPB"΢E90ŻikKA/3n#dA x4NNT2=x/**1Bw Ry'Y @ȃ|t3?η=}}(/=C@{Y%endstream endobj 262 0 obj << /Filter /FlateDecode /Length 3972 >> stream x[Ks7Glʋ`3N\NT &)>( ?;=3ؙDwfvnşԮqluOa+.+LZ].^UkYݭ5joeնڮ7BiDc{_2Vʪf㎰ [}S$My@ +'- ~<ɖ. R\^_Tf}_//IGR15G8mk s 8xj1V99s7bNVWs.<~n73UFJ `շpJ1W_s r)kaD}ȪÛ vH5`Ldmgkq-Su yjf2]e/cu$V6˚qj L kt#GEգXLYOtwknF>.|:T,-UCgz+-L%Si >s z4(hxjȧ_{OTUaө-*z #S,U;=檐u;PF2Ήbp*U }Uť *[3&j%_]tqW+gĸᜬ> Ntz=2_rN_KC23$j!UoJk_V6pv[7Z0!ф.] k5p̞Rդd`R>G)lTcGJN7^|v /cZcՂ} GTJ3smZWfBx 0[1ΦGpxV h֪`?uۼ9WwAI&c񐍾_sIU[<1Pg>S8/4 eN49ZMiTqWAqkrx 0U;.]9@+Eceťxpxǫ!i&7cxDMxV'T>AQ8>—Եn;Qq6zbQ 'b.UqGsmC:& (􁗖ܢ&ëtJ$}X &YtLbF+@ B0* XK 2S:kFqJFAٖs%);O@ FGv.baqMq 扎(]oې c)oRZ&-ՌRL.<عBDjxbw6Sp ITPE",R}ye4*T91[ c%$8Nve,F/ªtEڤo3Rh_:ÉRLKg8|VAK,(y?: ER3H=v8dif|D>hL")MV0^XI9'|&? V%S #'!EU&a4n9a9 Q ß#y>= wJa#ԿkKK*m>1D(pH#hU %5sp/|O|̉`E `#>s*8Sn \ZK5Co" : )ߕ~b`Ag1> CbV@1OSA-̫nm+ t,e%2T$j4FS_n%)E(7*"&6K 55̿<4uc1Qަ !5!3 RgdeNz<5" cXZM=~2tts:H)KRa+7s^)u̐uWz3hjQ%#U9e%UxtLF4ez)wW3JΊ C' ULKCFPonZm+K ]s*%|yjU.UO+"ieN`বA3N6-h ?aw0hsd&d {XU/b`LJx00 s!?| i=DoI$hoofo5ldSkjY.t|j$ˌ)VE ⒓>Nv+<:P*jPtN%-Sm~ߠ۔qHEq;.R#B3:u G8cXVo#^䬳=>3TONGVnL&bP`nCiLQe}87bmoZYvmjjJ. fi}-W,6:bLT3R+6m9pL3]4 ţf#vTЉ׏M0vqrnm#@o s8IͲ~ž +j*,.w`(+TfdDY΃ۃ&^~ UQ@=hL(l-Nn$x?"^hK7>([(uRL. i=$ۃ>FS'lz:̗fYNc3YXf5$$%^-Gۮ8 ABB|Z13WmD7 !&Kxm̃4r?p9{<|N݇)'rIN|(fj'K#Ob>"AE"OzIp,8dy>P|4xcc=uch;smۓ#>vd͚~|98wunoלU;57W{Y"(:Rn"a]guCi\^sAvK»b "=1jAU`l_uĬ5 ޜQ%#bѠFn{x?y߂endstream endobj 263 0 obj << /Filter /FlateDecode /Length 3641 >> stream xZYܶ~K*g~ sQeJ'|;Y-8eqq% \QK2mY,eUG2Vʢd@Y-IK%I S:s.ٲy{Sc p_fK͗iC? K,~Ey RJlUۅ5fzelKmh)<ӿ%(݋|&{nZ~VV٠ 5s*9ss`2LUڕ_6'E)ca z&K9ۤ|Bҿbɸf]A;plV~)v[@S*Vd3ʫU6b=iueD˝:Чtc^kwq2o%H:\]/-+ixjDRg`:+'J]Ov'hGHVJ֗[3&9y4ldTўfnd隷 KӪ| ? 1pVpr&Z1z=o'Q샍/GE:tޏJ˝{Ya{5-V|A䄡<;5nuلSnR3>Y]O剞4t!Ů,eXPx.-%*lnD~MPݧ/bbzd|dQH &򰧌 QxQ*.sQ_;.Qdд]JFfȠ=_g*7 _ewClݛ/=x2` -Lar'0s&aVRPBA3WPK@mBP*ߓ^$TYLfn3)dF%#y!Bu?ˏʁMQ[e#Zw abEF127}?@`خ=Ip'۔Z^FY:C sgtujmB_no+Z ?W HSک V [3r83;hԋ19H\ۑCiFj1u\I:rTve.>`)0Ao5FYT~áHhgVd üG׼e:iԫj`Y M3g2?$L^aK43%!'LBSV$$(GV=:h5?O0uXUh?}*zv矋6=3J oN`n$~!1p)tDM[e aWoZUjftYc]5vͦgޅu:JcQe/ z-9n ĶaB t}bߐ\KKExtϳ]o6|UQ'_aVc O?#7ƯAq6ٱ\~|D껏Z!;=SѝKHJ|lt#嘂`gO{/ї&ʱg:'A)^r@-9n^)۸}PپNBz6]j+[b(6iD^U ۬wh&$T}6 W\jS2ZOuGsxTsl-Pdl1r8 *=AN2˥XwTR\F;ј"} q墉4mC Mt q#@ iߊ\=FẺ Tr ;@6(cNף s3 Ͷ|.Ň[C\;(Ze񾌺 =YQݴ=KBq#KK&pgj $5芃 -XE4ⓧUVqC"ta X\6,Ԅ+7g'719 ;Uw>2aZJv/iGdA?e!Lt}ZJc)ZD!e} Ágg[Er`X;ʛA SRilԇea6ҴGI02dz oI=_OYYvhxeRB)[;Jm/#+;cXi{V VԅJ?qA%jr͂! ǜO-d;(Te3H ơE"ɋGzD`$1ga>*F1ӁD dvλ ^ TN| 6"D(k^6tC^ r56oI[8-/R0Xi$*Ot~;Ff&DMb_1T#wp2i]v1ѧ{UDeVGHj6n5 ls9`|uX;[+( `*0٧8<)$:eåL3Ym%^@9E,C?sz ;A=xjp=}ᘗy]4K墷v8-"b50b~XLR}# =I;vOE;z'No/=Fm}s":]<8˦.vB~a ^$E~ EO: CO+gTendstream endobj 264 0 obj << /Filter /FlateDecode /Length 3198 >> stream xZI7Аk1%(9h":\ɓ_]Er޾[Լjr7ioOrWu>8]x53 WxeyeZS;V݄f:֍+~M+ o{?NYˎ?g˭Ϯәdm$po6Ο_|7,ڶvj[eke+ɹq]ڿZѕP\ZZJ76;bK#2&כ8Qå8 W; ^mݚtŁS~JD`iw~oNE 2_ Dϋld.o׋u'^ 4?TCHE%ɌnOIuF"jְܿ+zq,Ŭp}o4ݥU2r2[F!"du|?Еha #kY;_$8 ա_.5ć:DdbW-=O YrFn/`oGxtMz>Rfw$57)(Ȯ-D,mFq_m7`BZ'ဣd  ُf~<[F '噇ph&:RvU|,QhN?dA^p7Edyie/FG 6W- qSKdˮ٦^+~R#\hD-ٻ[!nbT'z[DM}Ԭp"PPEla8괋j_3RCA+;*}^Vuv>D$H.U[@ȿ˧)]0< yt8+ج"~*hpdOaP)0U<YJɩ.SGE^1@_et C I0'.#W~О ([ɜGJ/2֛NT͙OLH#@Akٻ\ޠ-9H?@ΓydqP< YAs*q?S,Q b 1A.sd`0`*Qm/e!koP.n}ȴm|l;I ZF 7.?OGۉT jvlrA"uxw,n|S"~~6$:X x+7Q.@cae6Eڲ!6lXÀQXhǾ/J8z p[#wn7 {yQ4w3b'F54/㢋`@\$ID\lCAl$G t`S1G;ڒb6MCB;` 7RKN!{&E3&PE<c. KD=2(Vm1qS.:hiYZ<OEn"%ݐEz'}7s?,m$Yz[>N1b!q"r)Yӻr%6tcIl鶰GϵN18,p4K&Dsy)ave!H%{f"kkr./W~#O eVVܦ7(b=e|rtRCTtUeȻ(J&y Z[y䑕QXza9P@uy9JĝNޘL(\Umvvѳ&džW (mP'[]E20n%n^G0y2zϞ3VݍW<&Rbvzފ#}>n>izUOW.rMIK..=z\ Gҏ\/zq9L}AB> >`endstream endobj 265 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1603 >> stream x}}PgwI*eݬVuz"Z[O+*7Q$'.HL‹V+>!`Z E$H(gڹkثVCj:}>Lۍm3y~|IBF$&icپ²=/n~Zo. Mf0A'F&T(\•M@tȏ- Lߙ(Ygu .BNay`0o9Jlyٞ-bbRy1O.dYr9#G`$\"$ON5<?E "쎂"bKٰ #H!6rbGb-JJA&Ìa ;A9Z^a $QhnKҲH/E(=Z&V$lJu(~Be_l~}45*[ zAұxwa[j* OB$CB9p [y 3n\Q2}ysV,/]F}HD^s3hڽ660?EH\A}@j"ľ=~f╡mmA<4+SE}{SGu8* i7gw*㡕fz>~a8R@^ k@\5J$%Dsߊۍa?zjf!Qy(],iwvh'{G(`t߳e[ՓdjNmFC嫮%kw}u;b:Qc}9wgEi]͎& b lqxoxq^3vg$7wGe)BN&2S G<:*#:BPHTR8 BJCL Q~ {ŔJ>k@WxC# D-u`jJ=]&>(n[á7gRg>@vXBrvr}_}F-@>}p6+54՟BDj6em|/AoèS @qK ,~Oԇ04şAw7pejWm՞*hJ/MN^ⱀsKd}z|r!k3r'czָn jfC̠ Uh6 J|< S.)D+B0a5Z8FI$jw>7Ͳg!9Cׯ\ _ wR5drh}O^SyC^_s(,hs,{wc _WW {<WcїٵMLTwTwv,fsi8|]+j,EW}]. ɓe^=p̈́~SCv1n/JR5.U+U"01c_hPcAZ{b\@gRQ~~џtl) %MYd&TYVa$2|͇(q*̝OUnpOAz rXxxuFסL5endstream endobj 266 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4859 >> stream xX XSWھ1$;װH]\fvb]CT$ =ɗ lR &njuj]ՙZ[cuZj;gyn{{+cz02e+C&M?'=Ϡ>澓^pd::| )g #veq,m\d< n`LM%掟\1aH(b5ʣ?BT'PfllX2ZKbFYkiȑ"O(+ԕF{ (M(ssVg7_k#=. $LRh`|a,]:A, 2w[/%W/sz&^d`orU>;2L:8'qN{: wj:3`gҦSEvw?`=}|cp4F0.=EMޞ1)} 7 dQM0r`Cy@-̅+w枅;}jۙ vFSz&D,xxKaG|`<&.aȋk&|B1CS#P*pfV/pCƅ;&Gƈ8F>:W-^D%%aU NtWa16ͅ޾TJ0̡B%7YjV+g'| 6e&(:~ziW(,&%L !YU߻Qo鯂 ]܃rGYp @,>!Э\/R%}d[bCsM֤] γdoӵ9I *q T9D0ζ0)VT?5\ǽhT.kt.(suyp!͠ON5dn.<Gդ+S)Дܛ^[5\H9b2Nj²1\e#SCF#u򑵣o(aVZEa!Zu8N?k~(Qz} iX%RXOٱ;wU~)>aFNY83RDbѿVY~z:~*OO$1umleuUICqrў)Fw ~ wFYnFZ5]<V\LuUL = ,r=\|H&Zgp8Ul!7$8ְܱ?~+dU.+E*Aƴ_g!`H1$ ZJ$@8O'Ucxjx7ݦ`ϴ󡁳FD6o<"`y(#  T]e ԕ,@GH&S|sDZ<ǝdFtɺdLhR q SQp}f&iak_Ođ8, EC~3byn4 V#\Ix,rDGF5%DLbѦXvketZO;nv'!2=,dRNHk2ĥ/ҭ 75,˄;ϨmWHnÉ S'$*-'̍%ŵJ픝9Hگzirrum|oin+Nz]-YLLa_Bq[jc441 e z׈ *d}Nf㺴Cv,?"F& D-VD@ZN- syy߅&SkX;1ڭ9k݉!Z[zOLl 0MY@^VlA>-ĥ|*"_X_@lT&+*q ]@?V*,8l1$9zPq@QmLOÍ{~U W.CO>Sw%݈/ɈuB%7_q7[ܘx0V[GDOOOTbLq&!]8,kIORZoƊ[>tLPh)֙{{MP_:vr 6q|sRRZqji*yC ={)qZ ɮM6ǚ/pYµXl_&ețR.o&]"w}GQu"f6xVm]HÉZk@MYvkB&ه\Te qUjfևKSqcEN˚l0%$ u%45t$"[X~9wSv?7UZNqB8"I0Az/է˶9B^^IgϤVo_R~̱RYyHe4IPؔ9(wK2VP v2V.KOdO!=^cm3";`F#'ޢAoޟ?DWt>?7/Tw!v/W~!)-%jP7 N~ŝ/,->˕Q꼣t\brZ~݅ƙ.S#- &:dđMAqoxI,ήnehc$Y(5fY$kׅDZ$~*hc#fٿq&`%Zu'+;^zυ|xşl=GFlXW%0s"N"޹Kf$?\ХgxQ.^<{8L1Ď[wh֐FkMg{93:+2܏ M;=[K\z)V̦\G)QkX\cQtߍxݚ >8P.Z0v]Ͼ䙰ֽJ^(z3|ㆎ7+QY2n}_YM}i[HIHt%''gϝfV&$:!zX=tkFhwBlBp ދL?O;s/5q;{V+>]P!K=дZ]mxS)͘bdHd`MIݢj{NA Ts'ªw5 ?85A௶ݸNm8l1X C59IN$b՟ a. % H{0-J| S2 tG솩N^1'>DG&iq-k!j6D!B [V8G2b;=zܔUq6F>5zmjb3K9)?;Vd^hs>~CwDt—럻Q'$U/קa~:6Ct 8TF uݲ.xci\j@5Q1AWg+2MjrճUtt{b=7Qݣ;uwc+On>;*wOݫ*ݜnm8n݇a v}endstream endobj 267 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 7984 >> stream xzwXTfo2 j`ޢQ+MP)kf =[LԘ[1'$&$sϽ?={]z׻V@YZPzJǠ9zzG;BMіh݅c}Zӛ }BG 4aqvv-s anVEw؍ sq [G'ŎΫF˹^@Q 6.޴0Ea×D,\|htZwN8i}M1s{#9uw `)j0@ͤPYPj 5rSNj-5rFQzj O6R q&j!5L}@K-&Pj)5ZFMSS4j%5ZE͠^ToʞCYSb/%QQ %lj PT+DP=@H2FYRKAlPapVnVwDDh'Ee{]Gw-붺7z}/{uއSYY_LUop?(e߱Xm8uwcm=wж m!? =2iXAg9ٖ&m3E!mVҔlq ZBAr+Zf&.a y #K@KpHV⚟xR#c߸p$hs3$L4aojֶjmM4<`3xmCCZ,"Ǡ.ǏO)opp\,pA +V>RJJWXDmmv ts("Nᙸ /EGAieC&ޑbSȔ /A< l0p}Uv 9}xZ%_AEƙơXI6dAaX*a/:N{/ A0/2J%'6Oœ+@D Mdu^gBc )h**g## ~-縹DDWhnYƖJF9Vsb IB,*l8T '~!_ϰ-T@۾V$VFQA8Qnێ堁$]iPrn"rk ՙe(m=j G<MsNa X4X{ST *6"\8ꬩ0^_:({^rx%l9!{$9Ѹd8b517Gw$Z])xjxCMMh: r`+dDczCxѶJOrɌ8T4U?;S"Bjm!1FQj?|N(M啗mv׸^" ^MeoSS~?D"i{uN #~Ui! *m(6ֲ$Py>#&thVۭF4h#n~6K̇=ÊZ}-h ߚЗ;z<~1T.ꀢS!fIZJnЕpJ"Gm3P;+S{s}kge:,ɃsL}eCd6_jsɃُMQC|R&$*U' YmHXF|à9ӽ>ɪ4 Ar K]Ֆ:KҔ:ᅰ"*( 3ʴVa[J!,=Iәޤҏr/r[bqb2,0D<}u>=Px'a7솦Ɲʏ"{24nJMP %7P *`[r6t-m-b 1!|* d"h^7\~MhoO8]yVqt.&[aIyg+h3Kp>eAT4}u>t 75&^dً|qL->G^&)ϟ\b;z/ T`*0 mNP#H0Ac@P:%nΒD\ oD:D6B:;.Ms*NE)䉩%'N\UƿJbI<"Q'ܘ*?=R)D:j< EJ> uׄ*Ci,BC 4y7noX, (UY]\ZRU+?S ̱'ɼ T+].X>I+)a=R܎ ( wB"֎]c&gZBaoЯ-"S-AN|; MDIHHJWI)Y h 'fAmvx{kn`6bG,^ ѺKw\pw!M:][lWΌOX9G:DBAAVLSHآ iq #ϰD[7YrJI[ ߫"yPSw/GH3y1u5XEz&&+UЂ>2 ~C:ݎtzQϰh];YZڿ3  [6~Y9fKh V}*?4" PD"\#QjH ADwM a5, %WlĞ\ū^L 4\+G%Xt$]>([J I,!]isܕaBUguk՝zhmږ*p`57XE%W$x_#*RM\N_^Dh5 nliVVL>dȸcty&X@ot2,IV$Y!6ǞƀpT+2Rw̻C&BCHX"[l%8AF7E6]֡m3Mty!lD%!2S;qw-Ccd/A( hBbMi +^FuL[7lL_ wA ѣ\+ /)(`_?*%u x^؈m#_G@uGWeCmRY/fQy|*Ba&~;ˑC˭/;r.))pwcX^榏0~Ѣ] HYh_v-ؖjPV󈗬'>5͓ O4[k$W{d/psӎcלV]4h@jNbS3 @Zwʴw+]z-mR}>!AfriR4=CێO />{ lNwNɋXЮ;9R=%  a(sh $fc *S @g?~Fƞܝc_"(gIR;*6A`5ju~jmg.r^dg]*/OahMP=!nHNϷ0 `~xE)s=:yY7iWnmfFbcvXmA~Gpd.Aݾ2B\.sa" m4]υ~&?z*QƝ+@ή\>鳔d%^@r?=װ|m;|r-G_ڈ|S]v''-% %/Ğ? mh[ٿ;8s++}ԠQn<̷f͔?6^žR9?1-ⱫNf41X[\ ]qkHݪsBw'8f\5RC-5L󙈉5!.;T$M:4H`Pm\< \:#Y}0X -Eobͨ&.z:6j4L@LITQ|}?*[L{6o'uhSVik$X%B*9Vdt=рl}4:Ҡ>,u3$iM0*Af>foL.vuۼtUZL܅ySTQChAy֌-eIz%I12| >=)l<B/v2QC[vDOϛ59ꊌ>[e2ԫ%b~ F܃€qJ·r ) n(N'fC%U%/XRObӔi9D]Y53{7Z> stream x T'd M'*TmmUE(e@0 Ad]%2jۧ꿭j]^m8VΜLNfr~s}GB$ b7ż)zCpC C@<.lm qg1q wIPd̬8M Q[T'yyTxռuѱ)Ua1yW-M/nTQGFmZ]Z \L8pɲ /D(9j褗QsdT%n"iAB+(mS2=8?rdPb2e#G+OQ8*r#,Ռi3^rIio>(geV#E܈"Sj>U_H y3RW>;EgOaͩ&C50u:%FP02,<5\I"I Csp1p  YG9rAD&Yc]$#fؤ2Rgz"Fuc~J%4 C rb0AQ4;L &SII[*`88QIn*bh Q"Fq6!o[8l7˿E8^?A֘𦔆6NLFujx zpP^;E؄:YjnyO1=w>E?*Z>33t P%wz>_b)kMN-_bl0 U Hi:7x}"⫖9vSv%05Z:2@j_d<uoUEnJ%̌ 4,#.Ɇ$nHT(ρ}+>zX!yҵo<.Kqjǂ:(Ϊiإpq.SFUF "H\u'˯_^t,>풼BuYЪ(NWNמ7U&bCR ^I*x\r׏51͌}\M@x+@^J\0 UG uȆHbv٥M>9Ht!Tf5դɉ1MPھ'26`ov~س/bz^ *jGQ_f^euN<+vV$^c$20G}zQfgĆפ/q'vOVeQ.@[tU c9 =ET#YާJS=גZ}ʌILho%cjdwyAOeoBvm[^h2CAR*這a59p]D6Pa/GC}(2~*O쭆m:.yu@<0#Vbu+O)[VoM<8828tSLyNh塺 !8$핷=7&3Kۆ?(pI%E֓u"oc nEGbG)oİ9k}a ˙_B\5ﱿE'|-_Td=(Qm<`{J3K=ڼfZ±uq{5a3Ɉ7mQF>d؞-:M +ss쒸Xxq6k[ saX۸ӆZwu:ph{`ieNɐmþP+H8Z;c/M//ޅk(Sl$KWFBKjox॑Iǯ+¬&iCob3['^ 5?/ٛe5ᩢ#944**49{(xJGSםf[t!HOi^|ٓϦHA+s)&#a2^X|*eK-HP+qQRo(1H2F2mì*`xg`f˪Һ3? ng{w@{jEHzX{\d㯦H0,jJ覫0^k nz{~y)t>`JRM3*zϓ|ZAGZx !g*2ĽR1GV7)[t?İPUoMQ;,9ԙ\CMKNs"f.R\54%̔[au4O+iC[ZA*Cp(Pg!T\t*/@sO mk9^tb`.|؞F`nf$o1۸hi79:&`5|;>(j塂ZhgsƐw/FǪ(Q +E[cP#|@v&9sG25 ?Ǽs(yaM)"|tÝ"5 ?|@FŬG9tdFإU$Ѕ/7=0;@MIH*ݓϵv+lL 6q aJ%lA޻&?ϻ tku:!*"P Sʣq$u| P^ّ?gt9Woِ֚aW!w xY)}nJ2$G3=ZK3mM : OkPB=:65DG -@$f2`Tob?N X1$e[AlfoT?W7@1k[ӷnhPc Ga RXR%*ch{mVP>{fympl6rrM/yG{Df[;v9endstream endobj 269 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1142 >> stream x]QmLSg~oo{[c@W>^@e. *ZhGF;@1d(sn: l8eQg6ɄYg2 qKgoNN<CE4S܅,\<*J?|MQy-ZV.ꄘoXNcxlUK9CE͊[lYEY*8cqYLxKq9;r#_)ڡ)s GzҐšAhZnHrQC$hN`穨 |:?˭$0kE#܂B 1?BI4t*I3s"LB;_V@܏'Plr~9xnl"Opk6RN])$jcQ[ã<)ĸPV˲6__ZơRŧkẑGb(NS.>ESO%H$#eNH)( "!Ll|D|CD@dOdxܿwsc04J3 4?7*D= ,KZV4.8) > ĪmD i AW *M7=*SNWe^PY 0x!!~%,iZ,3%SrV-b5 &[= ?zI ^iY+UǕx0E;ހIhFy?J> stream x]=n0 FwB7G&@%]2(^@Cdq޾CGŔby\}g8aMtrQnkV-,Ey~ Ҹ[~Cq} 1!_Sq^N(EÿG5'NW5: :UޣVvb@;Uʪ1ho׈mTI (A{ҙ dͤԊmU1c)УjT,/*Fj|BtPD'O1>[`->k|Ftzm]x^uMy=r۩e^#)endstream endobj 271 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4050 >> stream xWyxSu>!4D9UFrapAQY+et%龤MӦٗ|itMe)P@u,:xz8;/.QդήwuDp: L7?4yf--T |+"IdY\PE1:Hc'pj+L>!݉|VC{'q NٽPa;Z=j`Td]@h=-mVwn>y%{7k(ŬH:CuJZ+Kx氃 :d+ϯbl-#ӉA/FWI-ӎaG?X@SbdZ~E%|AI+(?ܻܨl{k՞}s)yR| 0\Y03JC Nߪ P(Zc7::1aoCn8ݾ6_|HxHDSŮ^ޗ'GΎCH3@055&ͥq~=t|BmFɼ* :0ά23fp,=Kޯ\ mmԛ|EMvY6jz`URE:wvqJ*^VFC) :ުu{͎& Bkz('1 M@j^Jfj0` !mീl -vL;g5QAu;681&Y | 3 r*>#(9A/ꍕ,͘@E`N]A8ѩfL&zy:>[Ve]4Aw}}6ryp-6-{s=h z͖3ip81"5 ]IEQvURZ } y&h#8ȠSÔj*]Z7Ԁy$W#dc,*w=XONw脱%iGW%飝6bxՓ o4|t`qL X1MdC+y DҋZ#y=h20Rn6wzd588~A\ZZVZimjU?H:.8-u!ph" $k w\A(VTl?KPLae;F%x->An"Mn,RmQ, n~ֲ1-aO.`T>QQlӛLu j߶ӯmĬzg3N?'\ү e%˒nba4ފfbzyfވB jtvn6|ȉ7.d0+UflNao DQnq iS]B\$.j[::;LXɑ=}lnrQmO]dѐ9ǧWڷm;t ˉ "MU*|˶ Q>;߄,щ>*Sx7fEh[lk;F[Z :103(d1c9.%k)QnNv?sX  M zA݃(G-l-Qaԁ׻:TIDD<7WTfY݁VwA1դ҃15b3ҨZӇB}Aot⋦Iƞú-p++f n060e21Pl]=.?Bȭ0PmjK Zń.VJl `hg*xi=ײ^;cWe3=%rX{7Ո#]By 6R-%,3D-™9vpQ]i?r jRmt4̚oVqV 8TO0Y( 6(hN4Tv緹=b1bYխnϧ8`avhzLÊ]l|fYuZ2to. fl>ьN4y ^J9 -Y4}MMEn9@\R4xuoK`~!Zjbq m -2'*zS~FCU=l CT"XW_8kw|oS.lL6عq6Qc3`/.h$z*׏?&7ʴan~Z5Yi4p1h·nAk(sˬ5P }:W[XѪj%WAm#Yq zl6ʯȝzlGD_-&S/˘:B0۬8ng21xGx^φѫѧUPM*!2҄9e \jK,rW\ahuGN"*KDq|IXͿ%dxu@B.@  ;{_':2]QQ1z5c!b- s9>܃9rvXg_Jendstream endobj 272 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1894 >> stream x PSWo{E%EN ʣn" *V+T^&Dy>rQ@T h.TQ+0ݭP]uW{.ێ윙;s! l@ p MKS&$e+2ǣoqoBn0;5K v"IwDP Ju5)I[nn..[WmR)8f* W45LIS㔉DyxzyDBkW_?pT{x^K̍E*b 1p$kM8B™A0$–XL'i†2DVxEQfcۈQe҉BM/Y,آ39"Jp6p[u '(F`QVo1lM <['V_TlZ2ZDb2@P )m׵W+#B* R[َ|IjF,sZƉH%,WWȫ~_6CsRgp1}luZfz]Ɖf7?MxUoALܻѯ_cMMӷP-pfQA0eĻ*V-an6]Ww@Ɓ=7oW K_Z 456Z恮F2BEW }fh~M͜aSj(K鮯lqd=2A=A4uI,@#|h f/xBŔ`1:7thB{^IHF,52EY_URjd.BrbSTKQȍqv% 'U4eX_q M["y;v!/=c)b%yL*2۔6<)6ҷEv\n^ܤsrMݭaٱ} 9Ix4z<"jDhj˧)&F ZN 4FD-V&D22"IQE[!R{ iM8Bh|4t0Ga=l~(|ԅnJ?œ,ӖW~`USݐUReeTY ̄Q;j1 -sjw_msk9F<.UcnTfjH|r͑xQ'OB5uu˘1]{nu79 %sΦ>ZFn]5r7Z;T {oD2[`)}3\ikc$̙ͨjK֡6tA4G3B2ϓ:v@(jZc4'ДRMI)J;0jM!ZG]D ḿ\f$78$IՀQh=e{ 98㷪k=ת۸ ۫4@!\B~M;P`lNw,]ˬ<,%x,_Tnv/|vpC#q0rXطB=hd͹='ITaTC#eS$B")ìZEuxZ%mߊNlžQ ԨՐϚp$c4BA5F'X(N=yZ> stream x[w6==gqo8iM6u۷k+27RrZ; H[jܗC(of~&eA'% _#꾝Vˣ\ptrC'Zr9\VN//+LQ*ry} ,J5--螥ƐZoڻ䋫 ?j!dX;80 So-$ץ&m{zg((7fU⌬BgaQS3MLf7k\Z#?LLHr^o~j6RnR#rz̈h`r^Ml4~9t:jS7XiKPj%f5e)ʯu:%RK,j,4a-jSIg.T{[k(M2F ļ6 w (+MS¡mS[?L~] ٹl|*xFY$xU&I'=X 7<-|(@/moނ3Q2#J=uJ.~}) C3 -R 8*#:xSR͋ t,r;J\gwsO2:RE\9=5 |`DApnaY3t*/Y,D5nn[j#0<]*{;8ac1M5^C,tDOY%@Bӝ4V0|(g:0sP R-r W{nP#xFx$s\ Mǩ!?^b/Su$U{q[P.y;pR._"0(:m*?4>ujLW]zbk%1u7' mFmBjǫ{7yF?XtP7Pő BKcle? yxs{JXf]5mR4\d&oӬ*GlLiUNf+.2IfevoI^gFMZr'V6~^VfW}x >`Aߚ[_PX-ݿLh`[VHYBY4K9BVZYKK0x3oGmO7*rQBS}SNm}=٫Qv)R`̿nȋ2@8c0 Ftaj F` r|kFrG_bjR9]"E47׉ߏe.HKoCE^T-LKCw}ק[+ 㢆m=$>VtK4̍WWܟc6KSp~ӄBr]fmJG"-~E%4#)) a:=,}_'G8з}6}92L*ZvI-Q@diؒ`U!.gC핯HpJ< 9B+7w EÀB܅+`4PkZW ;HWNimuWKq<-jYwB?dg¢t|1>u|&riDNoEgF-?ރBPoKc{BE[g-ei=C>=H݄2e=s\^t+ `N{ɵm#IЍ$w]"[ˡ۝&܌J;nI4~Uj* Y{ju셗z§6V|h `pTRd;ymFf~et|~F0 &pb'bn;Ew{_0w,ΩOԞb[3 K&ٱO 1FGߋ&Go*F8,1hzXK~l?<&hVvqa+ n58rs٘};mSm(_Y7UzAoM$t 9$rOd@ЛU53,R SR>JUR*ށ*.9tvPendstream endobj 274 0 obj << /Filter /FlateDecode /Length 3977 >> stream xZKs6=7,gؖHJ\hi4b43'H3#?R8$_weJ /{t=No¿ǧ7EUVjwBEiE%|Wv\6]໖'1rf(Kɞ)V] #TTұC좨[XWA5~EUvL܌sV/MzQR=ƫo{cXe5,K:M9[% g5g|_ҬY'':_USzeòL>e L=*$[9O{%C. m{׳.n\ !H[XV/5M]Y?ZNn-%Qp@jXl kV9FٯnL,Aڰt"D 1Nʃ1VrXe$E * o٧sU,v T|l_Ue!Ӏl&U&ED![5Ğ ldL|peE.1rꀫB*#Y@^ujtB}7DI[}}lQ {}&qKQ]Qr6L]ZvO*FG#+R?}ޥh2.~.S*\6Ş4w#l2Wðt_V `wM;iV7=no*!0 j c"F;8w_^mm>%.Eۙ.Cf6=Hu:k3sZv /kݨpN{4 Ft"7 @Њ,!0 m^֩$SOC#x}܆P-٣4LfYq> 7m l>$R2רpX1j q*#B[ܖ5Pߛ9s@E'˧M`m1Ⲣ9@rA!f٠^,oE\"\&Ǝ8^Mj|w1a>o &B@䠉K˫HTh#`ɪ#<`t 0]8JyxD5;% XlIO?>`D֠'|oQ zWwB_40 QػE8x=z6= 2 Z @c +ĝ[!lIP3!P&v&9WBSNP2 B1Rv^޳Ccvq]L.o_Oc?cdda=~Tpah-||'$,)"yX!h ^ vC2!u݂.rh@H{t\!bBWI GVF/q|*ȡkd&<+P`]6Amf:'_ ~t,' b!`4iiX.4z]hg( z !#í2+0Y!D?4zlz6ȵyxq 1O 7h49:zGV> 4ȓ0FR3XIp"Ǥru;N&qZmOAQ"A@joٻrEEwEr20_Cu=@B9@aF2Q_" sAjxF:*ث-d#Krf>J&)@:(i3pMT.?$J9_ vu4X ZtϑTC[4 oȷO"]b `]qiSȥN.m..~%m =dzfy&E^VA(腷t^^ESE՞:*L@|Ϋ] t]dAx,?5>1[@9PPlYAWKb63 6ٍWr c*H,Ց_O Y] V48uAB,/ʮ >^.DM Q> _z˕Dԣ) ]kx܅zpkh؅vk*+ s峺nGqA?C"D΀tgm<:Y ?A`1WXb'b1NE7Ʊ BP}Pl{J"ǀ9 _CV_Q]``7-#oA %$o~ &âBOuJ" 'ˌR6( ULaCp6AqUy5rl?E s3 Y"|Rll`{>4a%AN=>mGL7wSi[!lQ(ًGg>PZ#7sz $_cB"U^$oͷ/@8;OmwOD,|StRw5uJ*LPXh,z}= X(}&`%x$/M3W]6/K߀dY |?y!0?ofRd,vtÜ 9 K71Bd4Yv9Q/+oFiFpۂ8&X! b.B]GEoBy`Y#kTn߰=ֳ,RL<ɝެ;eAx@2 ۦ~ QWҘd~ʾ=oQa=US6+oOw,B5Z\:N6ޑcO[j ,ngXly8v36Go:$5pfl:cwدxk;OOoi^ƛhsǧ%ut5 0~4xh)*Vѳ)ۏ h4|M2T X%{)R=Ǣ/}jPcCb< A::$:(w+~MNDhʋ~o~dd+^!g_U-Na%@-Pendstream endobj 275 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2681 >> stream xyTSw_y>Qy}\qV6[, " !KBBHX ZKպV2ViVmlߣjό==''$~~~C@v]xNVbvDfbvY3S䙉y^8?/B~E_C΍9>5A;GфP ؔ{eNna^z|YΘJJW̔ILږS}[41;Yf溙9tl閔ҜTidҨU6FLA۞*K[Һԍ[#"eN' F"$)D41XAL'^!fDxG%# ̃B|~Va␿PTM%thJ<,a#GGAx9WDOZZ Qukg5u JH^Wοfހr*]qJFH o((v9֊k|LQd~d6SO8r 83s #P^#aF BXʎϊ~ ɵD᱊N9ﱃ'vc)w&8J^ӤP:oٶޅ޻A[΍[Zd 8PyIP~Rr0o({SX$==amo@3%~w( z\rjP _tm>y礐(mImE9쭸h=z. ?(ˤTF_[c,WbPE N3@ZZ_$k\ޭXYzbRCs A/~A &ّx4._/f=BA P-D/_wxxv{/H*R L(TӅ/A|h:\oZM8|q S]6o kEi+V%`91St=nv>M)rHg[JMZ2_,ϐO>פˀNj3ُ0hZ<3d<_@W)JI/z˛y4oU.bEHDwS+襍W3]3MG_<>)Es<~jҢYh:0TS畢\qX}Af{]. 68nO`@2, @c?W?r 0nIu}_tҹWl?K(yMzqJʏZ;;2:c aY2LUUgi0UBfcӎ8PMUY̢MxV.mn8{']pEKc`AwY1xKO@2 V_>c }RPvt7p~q`/SV#,ӌVJP0CxYU^\`YPv~qdkxsy7A4ǭF#ĦЃ :&nf"a[ h^{,ኡ2X+.h_c9@?pڹ,g~<Ɉ!0u։{OjR uy uz5CU\H]/i P+`Lx#-%?=5?RƖ?od˖ST̹kvcE)6}l$iwᆵE~o.ZEc7zP6z c?Ƚ.v"!"yCA\ht^ҕ)umҦL& (O8 G}J"'[ei4*l[Ukf*M*{F1?ɨ!Y&v ᢥ2SjIg5 {.Un~2+Ői޴Lje4ؔecv+$w|>Sa~,> stream x]Mn0F0c R4tE"DȢ4]t>S/y}['8e./|C9LyMͷ~-k~}\=7>/ |_[?_8qyTW\V$bC9k59AcCQc$ԘȁV[r Fr 9oONhhm@A#Ɏ16B EA6Y6ͷZqEMI&W4ߤ(h5+oj5+oЛDqE v*qEFTW/7tyIneӣC37jU)?endstream endobj 277 0 obj << /Filter /FlateDecode /Length1 4572 /Length 2924 >> stream xX{P?<,J냅؅}$X› H&hQS5u:N騣8tjNZhIGo{:os{@ {-VWk Hb5@}Qa1OVNU+)哢wtgԏ#9 _ƻd2]Lȫ˱%ye.F`1g*^5έH: E| Et B>XxrN!8@ǔ0v$alk6Z** (&VB*tlLPn^nLgB )Qh4lrLS ʴ:dZ 92v$*Ȧ[dz2 ;odZ|NLEL2|FFk,`V[E?<]Ί; yp{Cs?tCQwxvBjBqVV1s@CBnq(2%ªUϤ(D!<.D's80}Q!zmbHh>14''HŲ`̈=LD<`3iat6™X02'Y]CKXx ͘XQLS+TϊJۮHaEQi-س0 cȉG!0i#7sЍ>AkP0ԠN5u6[B;'TA- dί, &nxW'-X=ǙҬg w[p/ rQ@^ Fa G>.Eyڠ^DYpǥhˇ.ދ('Q;U-g Y5n\S r#8JZi Hvd+~1n gw@̇p f!p0Mqb"֋2<48O+Q`}A>(sHE܃ʰ5Fۓ2: x:99v#MꢸA\R\DdE"u$I1IW\¢Pa]NHFGzzKݻQ:~e0Pjmvͪ7Xi贙 cYQfi ()ͺx$$#{;nrxcWVyDӦΞR2سuM~cu t[wksuN`ss:k}R^m?MDUU0EV}괛* ]&U{U Hr΋FFRcS/_j}56xEFb#tJ~/}#EbdPl"]s \&4r\bS6Pi*[ou:&ˏ=w^+KdKǞ{wu1 bSs[5zAˇ=vzX38F%-LA^OF0G1@XliUelCktբThWIw;ZɤMc075o~Nőw:?n_%(uNy[zKPߔIElS"!FO :(1OöY8xЇ;*馽C3ָ 7Lu{頫IiKOz1M* -촱HC{2g<΢枞]=;%ut=Jr94r 8=2LnW#g nڝ\wo;&,ʐ1TEF-ЏGN?B3x8AB=ox#k/p'ތMOv{KwOΓ>|Pwm O98}c&%hOB{i^UkU4{#aw_uW/=}m&)/&Yf+Ѱ%*]z\" $b%#d> stream x]Mn0F0cIh6&VU 3D,Eo)]t"}d:_^.Ӹ:Oas\^6N7߻ίp)> stream xZ l[y>^$Rd%eQeQ,zZRWmYDJW$edHiwNmqqj8]uÖ~C ^m6 `u 1{Ҟ  ?q.mBzQp.cr_Bxqz1%VJxTʬ+bHl;w![! ֎Be.eĦ\yt"<kx,r`* _$4?R{V߾7uOF:|5r,*cڄ"Q!:Ʊ^8uKmNiX%|vqq Ft?Űx9R?űPp6x4.hYsa=Yscъ \mǔhBù3G?蹺A)0FԪ&F٬9ǔe)e.q )]_9ۨ|msx OqlD#e_vP2'jF_\ǜ9fq  ?wcJ?0ܿ=_ȳ)Y[I.vH Yc%B:c *:X4/τ;cTg,:GԠLq<:ou}5>hLN$AmH^ SO&0,fT(fa- `MB`NNI50*uQ9H-"ii_xZ&eG(7,--9Z3ͭ #|>BWz|!<}T $bKQXiY['آe)_]fbA@1@*RT%u@Ս)_Ӏhe4 5@Ý͟4O"Pg`iσT =Heh'P`V%QHAY REhqY@+8ӏ6L#0~5\7Kg+m <E)03ƞ({@IpNW1/n<0R9!_!%.!av?!!'Ń],҆a6ļ-g1@ 7`#̢RlL0Jpj볓l2:EpZzYcIǀ!,Ph \ 'a|H/:XlxvIp%{~FQND"Eb".l!94cFAvlX4D#pKO,i/O2y (_ǰ +GFE3?0 +-0S"t}~l=G1^q˼ gH[% ̧QJDPН3yd* VEʎWbYfY$σ 'l|WY=PjjN=ҏbLb^I:"ʖ}Ւ,s(2eFw8U%:UK ]z6luvVi̱ZgDq&Qd*MͥfN6[1:yuU1fA%d;F=gQݠ+ܰ] vҢw9^?dOڋȉ pjF5M׵*kME &Rk5]rkՊ?ᅻV7ZebnN 3C]#FBbx\:6b1}/M&shm R䏀b ^fh.Vfeb,04Nj~#$w^dvglƒflK]mna~.fT(A.̃[_.*J Ԉ/Ϛ̊C!wê[C<2*-Hux;&5ZS]#EE 2at8lZ"a-A *FZXmu`8"= dktg:䯞HOEgzpd֠+??tDk~aWk?Ѥ6[=}Nb_7(ʊ}I/[3ތ0!oLY?|A!dQM>Z*z 6JT̴ exjaFw&vg\ l p--ζtA6߲s8Rm3gI,q۫7RT!^/!_=ufϑƋ~O1lG OMӻݞxӓc2wڳU^-M55J!><[?xN?蘚a7]Jѩfm+s;ZbJJ&[>aRչAkEh,zvWdWVKn/ #{Mv_C WW݀ ço l}ss}s_q"ڄPV6Ňo_Ը ܀;Il :yj6#yk2f*2;Hז _"!"o^XOP&.OGu>u2\A tb+k 9UTTm#}xe4)Jv+@{b?;Uݱs_:p wS)gO{>]\JȮ]Q󟽻^3k&jp{Gm^tNUtoMA#t!C$ū/UvՄ+O yʿ.\ QhuYzCNFek!)*.y᪢UWLpbWf8nE P<~tB#UV?WAu'oWMv]8LwA}xoɵWޘtGЋ:uve]MxKfgXendstream endobj 280 0 obj << /Filter /FlateDecode /Length 222 >> stream x]An ExHlMxX#,zx.`~s/).,EBY> stream xY]l[W{ol'iӺ=5qM麶)a[qb4m6ibӪV$il0F'B`<iD Ϲ'I3I\;9W@ m6S,3kr8>[uo%0=ObsK4[^ױ{;zK_Lጐꎴ Ǣ!;; GX_XFXu+dNb 8y@eZꁇa"" ڷBbR.΋ `cV U6ka#ACiDQX*ԐWVq؄. RT`HrlFEzV`H/ 8?؂, #G6Wj?ᔼ$ەQKyL`lTÓ/F]U+:q UՒ+,0MM[ce:'0|cӒ18v h4f8e̿u9;ul],XN8E/__ 8丫c<{F9?qnqɩ95F6|yE`ּ)0kc~YF#jXXq ,;)0rlWc6CvNqF݈N~M`kI`K+fUo39Nq盳(0|L`搞Ok2(4zT(f4:X!gCl`DꪞN °>hg`>k 8ٽg'J.7~\ɣ\xDM1P6һ5h1Q}&Sy:)əX)-^?4JkYm&TLŵl^ M P2[ qd.4tO}.Щb&65-ӄ ! 3X .C#=gbLbYB;/Y(b#/qD94Κ@~;3 P$vu#uaƪ IiTJ0W /o?ruoC a<;l[őpbQfaFa) )@Z⋊wkx,f:߁u:M+3hm bkLWN膝Ѓak'38fK%b{WX5eۇ}:e8,Bg 6{&cǰ)3a [q*\ۏ(5j|Nۇ9;:k`C˒N4D9?t92}NLRtAJ&RÆ;PyHxܸ~$芐?b(NH ڝQ<N͛KøB?_q21iz]).4iVgu:=GTu,l;ި#ឃ}#mm_>9J:6d3omj&oS Z667ѭ.Zj:m֎~ߍlr+` `x8`=ܺ"Utb0n=8E9mٔH$9 ˔,RJ35b8$˃BFQ[G>sc_V{"5w JB,5 u{풏Pn)A9+r[r]wm7嶉IVLfKu~)K綵T’ /A T w_ Tde\4}˲ynup_|nq]c#;RHd{/I197/VDxz5+ endstream endobj 282 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 6179 >> stream xYXT>+pvUlYأ "E: KYA`;RV@#vbòIMbb41xI?ޘ<xsfg Q`$P2gLGO0w$~7Go/~5@zP86#~((#)=KB)5;{3VmwId!~>mg2wC)@sOow==N͝7rhqSgYc,lYu*uH0p[]QB6CkQx$ (1jg˻\#}8ŁR7rGAOlA"0b1WٮZ wG]|VaSaF2nV!YXP0GoRJ̝"!~RPO-5}0E54Mi@p6W +ONjP%T.H*m;{ƢR.roQ0%&FҦ̶b|$ܖo!璳;[j}3£ {DŽP$C",/zH$'ny{ݹnN'TMh@kjV]76:oT;zrK$!9e 0Ze m Frҽ~ |hcERt¿(B*8f_f {.G7֑!)^NZіP=rL錏STQ `Cآǧi\kgq`hg>ըV G&]NS nu51Y?P;la,zԈm!E墺jihXݧ_v}$w/RP~mz|.?m Aґ!dJAog 2 #yaiɻ0W&ʠ]AFqkWqwNhvQdzeT*gf׊2\6<8'86]S{Mj4f-'*&l ,瞐āU@Mt]-C23J3KP}qJ#"&c_{&X!NX;RĔDy> &haDRp"7/# χ#&0 \/wx4,GL/'}AChaGh~9 l8#IXݥ*@) ĔGrlZ=y X PAz5푚!H' ';c/X[|v4P:ߦ4j-xC-ƌߕ '%24NJI&ofsPBI?@' -(3R9~hW˓`R#mM:;*UtY2}9-\q3 ck>FL*yT3bux7aG4;o1Chcg\·,Bİ3]*-#;r+Zoѯ-͍shbQR-+1K3j*)N?ځDO3s-QS(EMq]NIf^B$_|@`=y{ĉsm1fsd'* ZZt-&PoSeqJ 'b-!Z0"rF宪&'B]2=Qt5/q?w F^$b^Vl7xWoME"b GafTU(!ѵO\ulnަ'o/SÏxN.&Hƙn0y×wcykM$3FQ3;ӟH@EH, aQ/&3:V'i3Sǧtcr`#wѹpYӂ>SC Z{x_i<6#t Zc:z[u,>xWwa(~_so!R_SA<9i@ 16qqd{?ؤM1GJީVi{+ۦ&֚>iY${* =dڈPA&k-\yc/!GG^ .搤yH)]".Wx2=Ė,"Bt([˅uI0;J"a1/Ts톿OrHvɐ\[3DPCU\xs]T4(P8SmέCc +ο9GIzGfKP>Pnmڤe@0Ja2z6_Aq1"%..\$"iejYU{ޑ\l:rR+\7HUxvOGH8H3#}~QZ_{x8t=Ԓ|Hynq`쐘֒cr)͈x%d]JKaj1!+~Ŧ kbU۬} KS Ӳ[O\b~ttǽ1Ԙĝglph7{ׇEŹa}=}0o Ԕd.@-'iT[["AAH% Cܼ|IP^ ĕVBHQ@-!ngi`&||8 R3be8aґL[A.u8z%jf)2Y * x%yp:WxorW #QhKeNn>2I+%+} Y8o_>qށ݋]0< .XL/a.$y?pf׍DyrC<>7|gT+:.L#aaWV/8 ~ ^`vwR%eաRQO J ե^ׂoHD>(,BGU *h ȷ m0W+}$SUN*دRi&O^Y^UtIp<~Ԗ/9efӞ̓Q`"8:ڻYqA+:|6q)ٸctLk8-u6ϾXJIfLvգ ^;y GuV2f^`!f`Isaйs'bgw}\*#/j]L``^ CQۺt{2T#tAx~|ɻ65K4 IF8,9'v"G/~(/Ae}x'6x9[V6!QCne5\a Mw,;CH"K)JM",( 1 I(F'?; 4gD~ Nt ~*$(!* %$p~>DRӀ0WRLp/NRhl޴, HlLz0o/o0qv=u,,R>#)qlS_}im4Z^!l$=xQ*w+4`^~fV>c=:noBZd*AW`ζrƋk$> stream xcd`ab`dd M34 JM/I,f!Cܬ<<,7 }_1<9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C50\``````(a`bdd?3qG߷0~բxy؜u̙[r| 87mBU\XBBy8yL;ódKމ}}}&201g>endstream endobj 284 0 obj << /BBox [ 1030.75 5607.35 4999.41 7330.29 ] /Filter /FlateDecode /FormType 1 /Group 45 0 R /Matrix [ 1 0 0 1 0 0 ] /Resources << /Font << /R155 46 0 R /R157 48 0 R /R159 50 0 R >> >> /Subtype /Form /Type /XObject /Length 1815 >> stream xXKoG0 53ܐ-JRZ$I Æh,Tv>daP(zh,Fg]5 E.).tY*Hy&X{:Zua<|pc ʲSP&fHU;W8<`Ļc<nx| x.ϻCusendstream endobj 285 0 obj << /Filter /FlateDecode /Length 5375 >> stream x\[u:/'$*q*Z\EK.ڙf&7>=;٥h\s~Z^OWޮ?7oOÛ3W̬zuzaY mT~ rzwu더gLvS;wK׽)'ZX{` zW.׿K^x{\_*PCT(ITp|eBx@'٢]3%_wozt9Ysj*/+uoᴯqwzglwsIּgnitw^2awwqݛh\Yhr l6w}.qkN#a~8#(퀟>{xVݩ082-m )z|̆^JYݞ7y\#16NTρ#.{ni.>;`&|KBGYaiPtT7v];~ݜ2_#0@sׄ<csZV&-sޑ~J {˂̀rȞkv8&۫n\lnt @ U;o0l~WB@E[ͽb[Qo`ZK_r*酤ô,WGqg8XA8 2NGWe {:,z njQK XβYˆ9Ls)6Lv0,^:@I8~# c%rGvoD!N ܄ (~T D>T9'΀CK$cl1Hi0X/eمObby7TϹCӒ3Jk% t_KY6_}KR>;^H TVf(s`QhySA)pj >,j@Y{~Y -CFC|O6gWNrù ۔hn ,U`}ŜN*rRf01' 8[Ulr*u['۸.f$DްmH:TV2od(!'Wز]H;! *AIb4m@}HsLcA#vƵ @zVf#\I裐hpy"8^ULF x !$;7`1zpPs:T6%;3%;Ί|nGSeEZ+Bl*xyLΊbo⊥p * ʀDF=ȿ{8DukUXq| G*f D.k_OX/:öfx61檠Eky*m@'E'|-uT+}s_F1⢆ZùEB45vQg"sq3E,eƻhc&iw.P6LuY(_ocQ뻡 5(VDm&~>?"D蚁6D*tdoko0NfV} |fފ3EJ*pcG"ڛ8X(5O-=  9XfMR=.^8Ghd[$< ޜX0YM.HmˁQ9=lOR!Lq!3&LY^ T#QePڴBa Apy)XͰ-%%xdU*#ePJiJn g%>]$kA% Sl@F_,M?7v{2Yg1T?gMrغml"5)mXRJZn( jBAw̐7q mZni,Z)}s^a) oSƹn%&"xfKc$V^(@ i0s8OMHX;%kr)̞C)m0)eOSǦ5mU;Pa@7k *|;mY*,fYYaeӏY}fFtlet{,Jc8S J8 CZJj(}쟤o~j(矪blFQs :h,ېҔ 9|cØ/Sڞ:%C9Hj[Y]:~эROA 5c[hD-)/=Qyr: %\">Ax3&?&f$×3&%̔cV%S,2KW&:nSONk2P d;ƏDkn E!G`_LRlwy5Ą\UO!{yeӬ*|I xU"x\,뻉lDLB>UHXhwډCGcdzFoHk젪f8CUo_- lƍmS*c*7tܙ0U"MMxp@nt4#_kڣ%$/˝"^~hZE㢅 %٢+aīVRҁ[q˘'uuߴMZ/[p2K[Lr*]F@@?OPM# iB:xWB@dtB<|bԂeI^zLf<Ơea"(-ucza…ۙE6V`ɂ}+DȨlO\O}JbE8[`gsk| !'e]Eڅ LyMSW%+0\ ۋmezGr'UsjcI~q!hNŘ"8<%gO͗n[Q5TꩮQq@UXh#Lp` g78h q qytbv qrXzأ5}:4Q4歜!CYB́=>{H#Ї9|^ዪo7\FW.\Cb3~f /x}@;@{ Ҫ=+6O 9t܆l<)]hE]2Nm=P5'0]Q0~/[`@NMբ 8s* FUd!jG}̊`|1?Dy:%+'; $")ZOϩ%iOZjQ($:kJAna~lhnޘd}A%|h26fD#N2a öJQ"?Kn@3OmKbNj fGZYn"Q\4coI7<(*f#=ĉV] TˍPf-Z] 疇>{~|V>cͬB R>;$Nh ?n~G?N5¥F1EdsZJ2+iM00/?s&)F+@u DE{vl~S=L$fhC.PKDوu;3 &@|چҔ[CRL> 6`!_QoAIS ’Bqbi؏M)R_kJ/V4tܪ\;ׁm)̳e(A4@-W/r}a4ɭ vkLk`V/9|["!uLxxv 8*:5y]8ś^Ea05ƥ=D"PBC致g&YFRŏ%@b`vl[&xߕ>y,,keBҜzH]n ]8[,!BlB|2`&..+df դKt1yRxt.hKN,\h#}˸sL>wfs4Q_f&ǫendstream endobj 286 0 obj << /Filter /FlateDecode /Length 5436 >> stream x\KGrVdGc|r+vûaWHr`0F_̬jCIv8x SGˬzwWշW^^}s˯'}y{"vAUW76Vv0erb[l;lOWkⅷ{j=+u7_;}rVm9mU}ھ)y P-?N?6WH!AۼZ}!cm=gib75|/~vd}srǧ. >/p&c]޻c2@"9`M9m"r)fG(lĆFbpT0%H o^FH #g`e8g$Jn֕X#Ll\Hst.Xp-L)Z]TTǻ|ǤߥzNc|nFRBvjnfH"-J%<ӮP'$+d܍wAI> ~Z4̲O'nُB~.HR5(V(K3\qx:>0 `_vl \N+%3-޶ K/ZDmGսy i]^J<[W||]PJˆ:bCcvVy[;mt Hr 8{&Me6=:р(tݱВv; g#I!ͬ_j 10Hߖv~ l9j4d T QS-w$a`߸ vZ߽Og􍘇33U@2k%Ӣ4(i+PbɊ*r p]>>h;  8g=oup6/NǢ:^B0zM PH׫0_Jw-t/e2:'Ԓs:@ԙE^r ďNr%I& O**sc@ =WJXG.&jq uM^x%\[LJ6 :r@bq1ieP+RDEH|@6ehc?QvDlka5Wצ%N'9O}ϦG6_zW=>k.@fLe/Y \$ `tFr Vѽ/ S%'xl)GFFS9n\ ' VD8%Oy9pY}hڅ-q D,Os,N$U،LĶlD~3^"7G pB|88+i]KLJA^-5Ȓ KIi^M7ݛrYr 90Iצ{q{ZͺSDpv&^{B,sȠ"[\"Q uYʇ >gKi-EYDMvE!Iߦ槟8kBpݻ&b ,YEzV;D ˜ Pi@R:{pU'԰ˡAQ`',dr5Ίr-43~!4^5D69O4c. XI 'Y!0Q5Ǹ~E.io% =Uzi].e 'mEÇTU]5- „EIyͤcg*,3kO=8g  f ^ Prp} F6og26ҟWxRFC IDI޽ɓU"-~-ՑՑ*` 5OS)"Ma,JDH~qe=V15݆NaRUll1ׇOhh#o@cU6F\ݿo_=w+`PZM1JraF⧒9 1D_øL_frS1=ЈD0r|V6; 5pAP<S#6zorD b|@U%SLM6BKU~J j1oڥ)AS*,tX._׿g?bFTX2+n"OTBG,ISv_*|THDGHBӏ9#.AMGuL҄q32V?iCJrp [8,HMO}7, 5_vD)>(༘ h+1`!?k3Aw..wbd g膥8kZM3^BU !B.2%#̈MjoX<V!Lɟa"Œ\Tc|L%Um*X78O4-H7;Bo#g"֪ 7@=*|-Ճ% :ğ﷈D641_D.y06$N#Jda[_܇ۯ*\k#/WQO]Q]ICfolTz?k`DtLoH]i[ϏLUƐN4eAki%A_ 2UhT0Go0 ?/=:b2zۂ@Zsj+XNPvbt99k0ǦYlM}n.BQH,y-)G"0oVC9僧*cJ=sh8m9AӎF WR\h0`6it7:/c%TH xP F#x$Ec+#U/^⡱_v^bƱg{ nxۚ'Ք,WAʊ˳1KR;4Q/Yy/./7%T${Zy"\⻆^aѫN66 wgsFzT$>k4[dǫ {ZG꺛 f^nHYMIi/x~![Z5<#N[uE8YO@ՔgU(^K.&!:r&r腩, KJ{;πgf4rYSmA\D)X-z^yDWR%(,wuI™|pF;su'j)Y&݊i=7fgFhh@6iڅ`3:ͨJ۰Ok,Ktizٽn,Moz1̙~Ͱ VxxVr+^ˁM  53S!kci 8_0UKwgl2Y]X{# _KF>ӯ.N >#iuI<{L^86s DS7yWL|0!a6_2em#RTC[? o2bYBMQ ml+ [ _ [ ˞Mw.fʌ3 okR-f$֎e bG FϱvޜbVKwDu_{.+em F:H]׹ RCU Ƿ{j-R){*ts=䀣inXRkV5 CĒni.VfoƮ&aN\.' o-H|}VYDdqWc"{|/n4'?4̄qPtW,%6 ];Y;;>`XjP5Իc^1X~/{~*G` @)52oc{Bµ#3eX۔7qMmֆ0Q)x|) :&%C՗[7\Ԍ3)]tnbl|*y/P㆜V twWendstream endobj 287 0 obj << /Filter /FlateDecode /Length 5894 >> stream x\Ks8>MDY.&vOt+-%T6dYolf`!Ad[>\$D"_>]4~]]V_^g7^.CJnW{eV7OZ⿭n('_u mzFU?tj]f^MC&6^p-ٿ__zesװwY_bXm[k7wv8ь@o:j`ޭe :hcdijاiFW9R@p*dS22m<4նn G.U3@:vF5lqD]؞}>%[@$V]Z_vcOUvI\NQlaB+j\]xqoi 7 y!RqlyImk FT% 4m:t> ZNކm9ąiAknmknEr-%`<]̦IneǠ6ѺEʧf-,L<1nSy$lNm-"-Ye 3/P0ǀSIuBӦ6vȸip"@6yμDҁG`T2ʂXW>\Zm$'(V^#@зAhrwmajƓ UK-?;26{;Rok:e_F׶i avv|# $1up]sH]EҀ)~\?fVԭYj-CϜUipx5O }̠q\l>"fh?woE}[}̧8Rn]p 2nނpLRZuM8RhI6[c]Ds[^G/nJPcUa4'+AG h}a.EX7L4X{e?*Bv~ޅ>޳/cS gD~ZdJJWB/\`wu*&\"] L3se bʭ+ӌgd"3Jx; ٢%aއ)gҡJ57c~W>j>.N 9v_rPȦf^AwڴE͠wa7ѕ,#-mrCX 0{>dK镩 THDAp'0`  Y V#c# Psµ˪l5έ']C}-n|+e"INm|GsCMYY<%0T Xv:jdd2Av*D #8p+P 6P@xe)j!`B%L["* TׯaČ#,7J1y3>-om!i,fd;Q `x՜5pɼjlpeRФҷ) x5d#T4Gӌ[_kpLĨ! L'݊&lNeFqVprtzBGQ&SSojIߣO~Y(D,c.xʣs 3I%JہcNu 9֑7E5=e>S:6k"/LuaDa1zXGVDQCX:nP*0qC1hD2pB䂼/EbZcF`Au9)#.CC9noLa G 6é4fL8.dhҦE8Ѐ'XvWMڌ?)>rF =֚դw[T uh DL٠JM1/CC)n杰GBG0dr EI&G[L9{s7lyI2b6$EK vx&' @=4)8c M\3Oz Lt۴pQkzLZ翦W;6.EBc-@<5!}Dr(@keCBiI$ c0fL@{3gsbqk<MMolɛMj -\-[;R!sLtw6WBޅh+8;PޕI5^0u91uTeI~.2QOl7g5= g[  slR6pZfjS iGթPQ@ܚm^V]$i  & nOV9Ӿ5J L^q"2*N#7v_YfB7DCM,sBsm>f:JTD,%k`2 N^ڛ'Eߐ2fwq-V1oܐ.[ԭ_oTvuS;MPR&dzns EKG}gsN^dI')&Usi>ct/P#HYBXӣf?P!:rOEv!+>%sBs1 ýGŬ}+nL(h.cO8w?wd "Ȯ`3MN3zi)jgSpv._şyNUA1'(F. wׄ+} xr,5le5%y kKH"45yiFf3M`tjkr2[T|Nv91lj9Ũ W`"_όDHYzOY&KDuߨ+>6q"h0l)hA,~~XAIk#Qzm`-|Zq?|<~=ll4x%2u*~GL(ID/^S4βU][dh6] O9{`Y͡*M (0kŢf)R)'Bpv_7c&8񦭭?x p+#oGn*U 9?e6]˶2 >+yNDNi0#j @û= [hFV9C{lUT @'*zT7 //F&X?)LmC:O2r\J"x ;B˓jO_]d's [pKUC? G,&NF;N2XՈJ`, N[47CVn&?߳Jkf7ָ383{śՆ<dAРry>Y~cƶ6C B—cr, E2/ޡ;u B[Pp9⟾0^zHRǫ7e*Kx"CLD~Ή*R cE).Z&?3B_PѸkH,G\[NUy ¦ur5`3]* V'LŒI GR9A}d!;x!chci-^6ܥ/$#ny H˜;a& AHWY)}ԅ0\̢dfB(?w܅?6;lX *ȳ;^Ðzg\L!"a.lj]07n@w$'ij@wH(X'$zPc9?iS'\. Ahg.Djo(qQ3J:ͿWa p~nLߥ?n9tkn81wɣwh2 x/yxHDmݧfؖE+_}Xk۩?n—7Ꮫ~ƶ|sm4U aw2b5T#\R M.>p`u`.a4)vTWѯKbz7lh/#YTڬBtMM ׇ]V/\^ʶ+)!zo'%{a?C3H|HLJQ}ck&LK}By%$ ^SԔy ?q/$֧Ά5%/M 5 "e;WjO7n)QAىd)") ZciO×Y&&Ll\(`*>pr)aWԫҶ̷Y΁(`4hoGŋg!z(1Bvy'G_`I rcCcwPMM5pa(s ܸP):d_`](l46-6asd}o&},:|DsJo:Vxn,= 7Z )kvc/׎!xwVhͰ}]fOmJcD|eTߚ"Fҹ礴cE#!ke̩s-O! ~Vis1a 3%菫YWp[L?Ŏ髓Z&D6FȆt gG~$݁w1c{3v141gHԃLFƞ(U?nBRn߱-BEi;KnBNk6)۲r x䏇H= VŰ~|}d϶l 3&-tT߿]?+Pendstream endobj 288 0 obj << /Filter /FlateDecode /Length 9898 >> stream x}[omGr;B@f`g}H#$y H#qfSI﫪^<( NծU׭v; gx~{7[ϧW_*szmnpJ;Tn?>ޜq[E_|uo[I-l;ħww)%a ?=+w K;}r`^dUrooc̻6Zι>soC^Vobyv[4qEvpi?ǺPz spy璖FSqn6[8б &s0~ދC^~2B0»҇hp s8΃s e[o`h`d˭"HF-Xz Pp0:@ Ȏ0[1هha7_\mF=qJ\ Va;˲Ŕ Oa*9}!a- cvه* }ݎɔ!-CיfgQ7´ OKWXv% m BX8]P S995P11g,O-y1&9-v€$BB,dvi\8dmv u[6MTͶs#Lv іmiߟtwEXf+w[zb(v;0+k>8o~jؠ˾3g4 %[~.P=cdRĕfhV]4Ŷ. 9fjd1暐,S!:  [Tt;8$o uM ,q<.QƢfdA"Ԑ(df4l8L;5,"$,>0Af.R7w7?NB'ɐ#\JĂ?.6f ,S]0MIs҇hp s8C&Ã$fl To\@[Q0;̃qn&EG7H1>H{ r>ƼAcGhUFun(rL0R>JpM.Q$pT*~6vagBZkt #Gdrf (( `(9av:AV%Aʹ!I@MacnE"U[3([ fl]΅qeˌ6ޅha60 D? 顢¨h'Z@P}c`K?aVPW)[&tC { SYDXkfj/lӀiI!gOaDH&,wXP-|Nty̸yGrx-]f-Yj?{ apj00غa !2` [BvYDV' ,0bǬX_.xȼ8E )0sٻyRau`ŠQ:yčDFzVC PbzJ5;h)- zs&1:^.9L>32q,- ,`"ezpNt)U8d N #9esƔvXٛ"&e휁 ^y stN`ؘ W F$ͫx H'uc^(đ aÜXbdNU=чT6 Q:<,]S#` c@<^#43IxpP `^|<%@a480H}a9Y"4. ^1n"$,2898}f8HjYq`tĴP(ۼ[\aF Ls=ܘ,7g%Mz!bNwPL2E渂/B4>4k}5xP]QxFN!!Ma8 똔C5MkvUB \*VGP-|Nty:)kM}..2&UڈM 6vPl wjf 0}遠IpЛ`ގB1;$NvY "t`EuBbg`nމtCCQfS(b8\C[6f<.R4_5):̾<n٠L?O!\Feq @5}(Lhp s8CK@posw( х҂魤8~EwPEfȐpr@u@_P-|NtynaDta3%- As\8]ap"wr6s=(HOц`cjh\jXM8욀 DD";~@˥& WΠi'@ajz;chYz]X4NvQ20@P{(/m>NrYCBX²ǻq}Ѐ)Dpf-#F+A\>UQ89aFFqD"`d: UFҤ@SȓÀO7#^{o'rd>f)l0׮`%+Jg ;Q4ʀIp'0̾k28$` J[(|8;f,ӤώIEr]vފ=! }iv@0˜ѯ3@-=(LW>Dp&&zVE뛄;-\URB暲odЋaYMJ"/Pe0KT ~AHF(*-#Ja\ʯIܵ&vXdi Q=NS ,"bVj"tv6f3 ’y51 Υ =`c=2Uod1:t/V-.4teQk]Br#+:B;L Ug.v6 #tAQ!$/B#*w&i]HH_eFD-##0"D¢ny;LG]1rcI(۬~X Q-RWRVN`Tw/X q9I/b @>k}֫AL BK? ؾkMz4X51*rH;='3gl呥CVvTU 2+\(jp'Fê0JU,$r`TilcdžxG--gXJ B4hi _Xْy:at"S.l Ire;RMU 1PjKvqa;Iq9>L5QTUڸv3RFZ'=f$HqRJ8ҐvlT/i氩ZYlj)Mm%b9(QzwS9 EƆ?"6X2]YUF3֢CB1YBhV TZT^a81/w.GE47+cFW/gNc/jAŋǘROp?*jԜ #arLV]3-XBt0C /.CbtGS'<a4N !e¢:cj忺"շa =Nex-Q6'۴L00k0$K LMìv6+Ao6zjӊ7}S L 6Ttwea$uQ0bP5VW1e6QM):T>e0$>.零S230a6 qőԮalx!χBX4dfyAfQw#rľcPXŪQ=fdY$,è #)jSl]N+Ƅ+(=+_wVgsycMg\ylvY%&ΗzY./VLytp],蘞yh{e*5j.S&bTJ!"MuS$!1j_1"'GC746wbNI4 QgDiCqB4 a>.'@,D=\u7jUeD?a(Ž; .3.&xuNw](= Dip9 oROq W0Wc_)xei tߡI+7 Z%4XHĶO$XIl 2?oűwXvH*W1͖\4,x⢰Nwhc%"I'͖RvB׀쑺l EӁH_N_|:iNIФM Lxg;_z _nftz~UZyZ?gwc)}U#}ϊ.7>aO f{4c!/5h{Qyܰ:,q٢Π8߼0*>8uGP|ʅdQ)QpkX̊CJ8?;H7}txOI`X(_~zF.*a^O>~~lrz}1Vq䇫_^ca6=+F&Fܶvz5ƽ?zYW5*\N/e=}}Xo٪T9Qyfϵd99g%SR9=Yj6; p.ӣ-xastsw*s x.IiBw',Hԫ-,syg eϯ:ls\W!ҋyůi */ָ_ߚ+a1i߬LJ"WW+3(3$1AQL_ 0{R*aL\.G؊>Tdy)Qog9͉;=W5o.EuRF}GRp;њHO܋jm;EV5s<_ie(wyG+ʤV99:@L0}fڵwx({L1~V_ JO3`HГ)D [>}g*3k>|l˧?ѷ۟)z<ѪE_}?U?9E*U|nW< ?XQs[<0ج?>~:e>~i"OC+y~2D(^a~|?O?>u:o~?S>$|NecDty[~XF~]O )8,wGTE,h%6nBEg""?,n:o3ڸvdL~_U!uoQ[9T_B]_yZv>a>=|* ׶b&˩|t+^ozjYf덾ɿ\(wHa/O|C|_˟y>>1fƺɣif΍~P~g%LE޴d>$iYѝgîG '.aD_;sG'N&[s r%'{y<W;BvV}~t^}*nVJ袽I݅zzy ֥oMNY^!XU||\}r؎qu'T?#cQY<LJҦ&W_xp?w?|/Ex8߈Ewq0 iwXw LҕC}ioBT:=3G}w9oW B`ucK6}kԺ.Iiӝp.?Q^⸈E~o/Y"1^i6zγ6K"\5ICPƥw"Sv!g9C:r:x|a;6w-31V|7眷ߍ{c& hzǙį%#r>n~ǟu{'Ϻ(QR9x4=ҼRCs隈w缾Ԛ(}}řcj{o\OKB'0E>`魩!Yiy_vJYghׇC^GN9mrψ(z/?s.=:,g|: 9fN"\p>'^A"OGbp{xqkP[|kQذN~jۗ ܒ>F~8\O~`Xe3I&5?,g> stream xy xSa3F+""xAZZ(t"D ',~ϺylJ }f%GƄF$DEn%oր~}&b7V%NM~+/uMu2#6f9f00H-nK͚=mܩ1'%f9b 1$'YVb6x&^$osU\bG$|2X@%W?ī&b1xJL#Fc81boM*<O'Oyz)8lWy:짿uz.g^Z4ۭ8ks׽_I0cQnޡ7I@ J-gnzL1kMPG9i\v%( m' ˮI(ggzSdrd eN ڙV -PNF&>߂ń&.?u}(Al-LLt}IqmA<ٍFBy3ȱcNJuL NeDlgV`pǜ@A\dh% N#۲+ ˬV bvXAq05!7aJ#! 䞆wZl3~K9~'ԗ\G.ȓ16pC:ft)jFPJyh:Fݣcmןcy;LVhûUKof_X,;błj1,UVXDӴahш*eAN_>6~G|S6C} F9!n)Ѧ@k?wEtur |Cy$ y.aeͥ! `Y(8hQ*ZJ.g'_ Ok˟o_|%I#n2QCb9ќ!uY~S݅ɏ@5HT 4حU2{\LZYcto`*@,k]^)ݎfZjOrpX4 ͦ ,9w;6dGf[O-Dvlzz[ N7sf\wk=o,b/=*Mf(^ɇx;[䌇(Wo~ՀOvSПCedudW_j4,zu_@42 %kLj $eǰsؙz|otw7&k|\ cmn3A ݂<"򕱛Ky׉Fkv xFթILA:‰^urλW!e`wJͥ6T:v!>}5x]JUle< :%#+d,ϣAW+6t5:#m)Ky2CDmD]B5\`H yFԐh^2sP\6fhu\)J0%_oф/ɩsOJ0g⺤ ފIP{+ݭh3RPtR#gD!s3ʝ=^f}ĉz<0/亃]IhSt=p9 d~!N.HhM1^.g'fi%:^;+wT'`S=2WKE,]D3wG[)LJ%^?#Z%w?E.b;&u=^ h$k.ZߡkDZe"(H%`O_$mPS%.|\B7!\Ԅݛ^D{ws7"ܰ="Mk΍2 Ba)Hev(m"(TMH[% E9g{HW~! 3ht4)h;Xh1ُ@oKEvܣ1۲rk/@2wFd"ԖZ@_G^2p͗:Ьb0BVeɊt  S*KJ@*i8LJ[Pf9D::n_YT |[^ :m6TC]eTE3p^ 9vM΋E?_;0yg ]hš</G^W4So&ҹ\W}45% 2 ꋇp,ǩ:M&t9=@=r˴\ d>gvz;yY> v&)E(K'&`S'[jU%³Cv0C]W}S/Tx#X֡tؚ-W0S@8p 1}i}5 HυLUgH7 . w5sŧ诸.kMOMNMͱ,*&$)-aǎ*mk]2ZJEbEοփr9.%ur~up/M} ݰ˄ABG9ۣf%3Vl pUvF,;Z['.JguS~{Fb Va=iDQ}|t9+{\"DӳӂEo">o,.ī1k}:֞"P2JEL 퇪um*W6.A Js/}u`FB.mYeNv oͭ{P`2Ҫ5ғHb $ yL 53%9l'Xlr @4fK6pEsjT)F ԬZ(!RH4gpրȇ3O#R^_{$q:cdz&CE$;ߓ \m@P0wݽՄ"TR!yc~m"0ZAhҿlS&Z 㯭*>?)*"%+Sijz(%$LjYW-|7{P%Q'F~+߬+zBI@}';J_m;-갮$O;+?^?H Y4/ gw{t"牁Bi`lN3=CS xk0 UŨ0% \ ޹Y*Ak>3pW2;:x@EL\ǔ2Cv CA 8?H' (AڪjsY3}G?|LMے@&( 2dYدVZuBLP J%@ʕK$bU+qUi?*? ˓K%N'kL`Km}K-YGf6'ۙXkHf&votq^0yBX 5COĸT:%;b`7*S x4a'>.0fAQ9o!J]H4pלmOsq.xh Ma%:2,:mѭygak=V| JD_?}v&EY(a>*w-φdWu$܋k9h׮~GĆf_냦]( !5Fmױ+x)F>Wxo> ٧<4Z8^ŧ 'q| ǃvdBΎZ[RB90ZQN(9Ѡ \\#@,}0^7jz r^3Zd밟l tE84dZzC_rf-Gؗ~K<4 MM/8{v䞘!ٓxQ I(Ew{ o>7Xdx-%mLl;bYt݅tuzP+'D{ ܊Xވ[?|އ,i9V݇MhtԡJg_UҌk*춻ע W0_9-{o՘JZR}C@)%oВk1ȏ-J٬U2XR2*h+P4L=sfU@m)1zuKMkы7Шsw߹gciV2"ɱ+㠫ȡSvdzei G_>@Y:T]QUTf7Qmp~X\| 8Hs`tILiz2w|Β*+0N-o3՘hST˷7)w59Fߞ;} z!wdɕ]Z)dW]Z;oָT? gM6(ȋf1X8})?B~YqRC}]QKQ}QhY5W[ F"Mj<^A-%b ?qGMwq"Q(4L =>Hs7phbC;9)3i0k’f&o~UIz6K~^@-P4z<12X=*ر/0uD)˴KiM_+UMv8<:\mZc5ul}H>\4]ur*Xφ8߄ y`g,W+uf獻w`y!dFz lUVa}j57&WO8}N1vvd< H0iwH%C f2 UK7W@h*7QC}gECZ>r N(936̴ P}7WWU;O dMtJ.uа!eD7!ݓPMֆ|#u\LP&QlՑC ;,>&^LXnݳ\2|'4 JK(vpB҈![=hge}mUV|q{=I^~v_.OId }xs?⣻[+wG)WرOxXX{ ==;Q˥ױEM9 q(!JۗTUli~Jp{0"tJDw:Ҡ'YeX?c^( v.Q/  (7ѶktǍSV ֯eC]sBsLB;Ms\8;erܕBmuǖcgN_S[!w1Lj ll(!^(䛻u\%Q:7X(lPF7*tK3sg ·wC4u@ Y*/Mݮ;ߏmhPnę27 }̯T&PRqCy?HG[=KşAWDDrLZQUiTʈ-!FǀTi,h4>8}9S63bE5y7pд3QHB G֤_X6| CyH횃񘑗g\$W^M~?O%ժV}jm;-``bCRRXhghm @k(NuO'~;ѻъMɮ,UT[4 pMޓ KHfɕ{g̹^~^źϫrE r5:!4=@E{]m=fQU,~^4?Gg\.J=o։TԞg_Y+B̘Tr4ڱF%ie'h8 ll0n:Ԛ 0S(Wmևx p āZTEePh<$ׂVJMxld*L|65Վ#47xP|s`LΚ`TN߃s+SE q^vqjߗ&'wA-9Yp Lu^-V!.43UɃ'hƧ9\(X9ƜKgh7a _g7 j,jcCtendstream endobj 290 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 822 >> stream xU_Lyvw+V@6@z xZ$JBQ$"j?XPqv--X D#> &*nË<1їp11w!!͏D>2|瓙0b" >,_vx\^|0'UNF`0C$6efEv}X,$f9/tu_wz<\.#ֈ- ×z@((rqG![8Nω>xKCs|xSKeoxHa B^1)͝ӚhGRamV.c-^L3C(T 8gBaAj;fb߇ z;݄mW'; /w~)Aΐ ?s) =wXj ;O*֠lG/f~e}?Ìb5\dї4p^Uo1mXLOm\JHV(zp`oen7~t[800mw>ܾo֊ú-^ +%z!v~T?6RRVA(_G9%CﶁTK[ ̰™WPFe%^x3ϡk5/}-8 y+}*Vp|b%؅3ɟ;.k=}Si-,LەܔIh$eF}j,N&G=LKiյ.hPxH -46(qhS42ڍyVٶlkU5O$MKN2h2Qmy endstream endobj 291 0 obj << /Filter /FlateDecode /Length 235 >> stream x]=n0 FwB70 .ɒA2E" 3!C-k1ϫo>B߼4X*δ>͒.foa/8=.|`-%אFSB9{%wĔG Dw4$ݸD4$E嫊N5!T Qh(> n}]Pz5V+9_e):wxCendstream endobj 292 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1990 >> stream xUkPT>r4l15SLuJ&AAT xYevYvمe}9{ K`oQDhST&i4mLC'=Tљ3|3w>>KNsseUڊՅխ ?&~ Hrš0Kq4[#GN;4vы̚@(lIsT wK.M2Ar($NJi#H4|6 1t* /vJ L;f,Ÿi/H%ʍt7h!!1t~ 1w(g@ŧ QU &d_}FBQ+L.z,['cewRu/q[V^FI(_{|ĈWq #<2 Sm NW=&zM%u&eck.:<:4FD[jՆ Ȑ?4N8/>ɹ#ūd~}~zd UnttIV`WlXV%SY:>jLrnMaji"3=; ݻÕ2S`# >'H;{4K;7$l ]DWgs}b9KqZ׌fۏt30j5_A6v].Z€{).鰩D9ެJbr[=Dg*{`%JCG OŸX9R޲8(͚fhl86Lȸkb6xwXӹH lC]>@z~>$'$:;x9>|HR7)Z*%MV|g%`<$A;Rz %?p#,V ^sftvS UKu 4jP !4H\6xTEt@ X)[|̻_;]Dtb0@×sxA̭_{-:waͶ=tE͗KceP-Z>8`!ϸN'GUZT]F.]om77J46Sf<(~ >CB!Ac=MA"uv#l3Td~S?Ȑ| |ğs<>z!~of 4bqr<} 3 C.wIOw4Cڕ .haendstream endobj 293 0 obj << /Filter /FlateDecode /Length 230 >> stream x]n <op:I/UӶ TJM}a>c?9KU)JV)+ :>LpEuw_t;@'-5%ҵ@3d(`hw(G`* aa} [(bG9+ rNi/x> stream xu{LSW^3ao猊 +0QѡLHGCݼ}䱃H6 ]IGطooϷ7[vC6b4l5jpZ]ͻ-M`? J|9PߎT-g+sa' R.g-t9GliiחH֢P4SɚjVEe_㱫(p%&ɣJg0:{ġs|0rylM'QHvǦ(p7ޖ,74{}/=p⮻{KήAp@#\4@Ԕ5U&j^n+}| RxւT᱒{6 51 yh!.NRAF8Yv;ئg3a3h7<WK8OVA7&Pk Q3Y+?aRxLBVTV (b"}hzz9;mno7$289ՠkAf}~h#kMUHDA$Vi(nZSUPvw|uۡ(vſ~ʫC-Xzo> stream x]1 E{N L4m,t".3yaV,kfCt^Ӓ-! .I:MzH|5jWlD_׺^ u%0K4 d4Lm-ԑE',lYH;dzki!μHBߚҔ(%Q{i6endstream endobj 296 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1180 >> stream xS}LSW-oZh0$MGÒ.km)BK)B}/CAH-ffdY2q2LkQlt&[CvAȲ͹;;"ΠBVU9u;ڂz_nO}]M^AĢ#+`/Lz0X /!0}O.!?}tyi}@.(Y^ڵl(:mencEGK]VU&gkFsxkE_hwk>(_s#nk=svhnihpO|~p7QA gn{a̺ϻ̚6,.:p|u[qHF8JD)29Cj@uucMAUIጮfgWZW'_[CBRӚ*8^sx;. z{olm'|@A&^G;λ.9'stdcVl񴒱/ӓŀ+70nk$%!h"JuWQ}h;t$I1 dUHg}m72^1+ g cbj8 M}t5;<$[S5HJ_"f"|"rqWM/^AL7,K-k&_8SpL[ @l~^]Z4Q;K8ɓ$5f J` jEf9ÃΌtۇφqKM ˱>9mMMי!q$<#a1|gXsELXu0@]JKKj7ЫRk2*IaMBΦTsϰa;ƌ>hηA*4QVh >m,8aT՚㥸!>=|F px6{MflR K~eOy]t3vvRd%BG/C-wezЙQ=IPNy @ Ĺ|%\0~ r7S4Pzv9ԞgMVaS>JJp l\Xh]`L/i谚RJ"]2t\.qܟ-mendstream endobj 297 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 950 >> stream x]PmL[e}on/Ppm- ƹe ~82iq|1)c0>Bj#1G7e "-,L]$fa`۽l3ϓְvkg hbi2C 91ϸ9\=Z::yGEjfcn`-tjaYFyk 7TC㨔A(X# LpPFN:Br9N,*NτLuFE~dendstream endobj 298 0 obj << /Filter /FlateDecode /Length 196 >> stream x]A E h Q/@`X o/L1.$?Os} o.9.0f3[>|`-壨$N&_ yi@곙J)]lqNb6ၬBwia:0 @ H"wET@B}JiBAU(z[Ry}afbSވubendstream endobj 299 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 914 >> stream xmmh[UM6 Λh{i旹N;VYW79-IcJfMz;Ӽ<777MvsbAHQȾCO~Dd$禧lެ+C9ΟߟB *DQԫgzz,as=uZ.2ɯQ>X ԦvN <_{ _}i(=xGB>}8moU9dB6;s=~ *x=uⲱ^{:5;g>zsnY]V9Vc#vB *SI (JyԀ:(jQOT{OT$tB0tQ)bqIGPƭD\C_GdR_itv,BZ ||>tVG [+JN da_x;ɐ<ഹ? 9KH@07#M.i g_w+]sw尸%G2e+kp\5TNWO7vd_ih:a@qu0Wϟmqy(_^M/5>Q!R4 @ÍB PR,=-#>MLp\LaZ !&D0BLb4330f|_1p> ܄2K>ԄB)Ȃa0_WauWq>xhKА@qD˽O &x r$HʍOqva=pYNW7ݗO"qJ&bL&K $)yC##,]TwVw1;t^ݮe1%eLZN, ia1Φ݋ yendstream endobj 300 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 502 >> stream xcd`ab`ddd v541H3a!3#kc7s7ˊB``fd/r/,L(QHT04Q020TpM-LNSM,HM,rr3SK*4l2JJ s4u3K2RSRSJsS ӃP9E A L@00ֽucź>c9lߵ~L^2FrR}_nrlsguϝ:W>mr-S#z|gx2%[euweռG&Ddlk j讪=W2Is'} }wn=eKӻnn ߡkEt9`koߢ9~>':yn)?zٻv/k񝍭Dɕ3{VY3vgW>> stream xm_H݌SaQKP$R o:rmHmnwFNsVAkHKÝ,0'\(zVUVܤ7L࿥H*D32,ͮVRg|{7?!v;#J4zԕJXBEU]}ghs7UR:ƾ_{iSP-z-\Llomh/P ܏ H#A&W0tq)TzjcLJ pnlY^+oq^!?W-AVoP7/>|IRtuv^fF NkOie|k?vb \+`ۓHF!gcO1cj8SGp,wmz*-rr}cd&O{0xz9x`> |(0G}s.pnH0􈏒Ⅴ!my J@, YF{3uiow)'7ŪX\ZJ|k̻*gfgđTN:ȑ0lP.7fi^HGrɰ("$@endstream endobj 302 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 409 >> stream xcd`ab`dd M3 JM/I, f!C?uYyyX|/=L{ w_fF|ʢ#c]] iTध_^竧_TSHJHISOSIP v Vp Cwd %p5|7t9mJ`W鞱F.ݹrު)Kv_=NE.!P@xP; ʾ9?_]Z]+l3vy7~_g-.,\=S7j.^2Sg.^*WS'/`u[%${uOoO_O爛yx6n?w*/1endstream endobj 303 0 obj << /Filter /FlateDecode /Length 1767 >> stream xX;s7YŅ̕`Fo8~EJldNq("'(E~m~F,^@8vFHX,?%&Ei,fFbY< g6!jMHAYKY(a,oi}1h>y) Ñ-#.K^Ts;cҜnk0 w&߮ca%iWɖ+4zj60 J_#I1bk)[tP\24k`AqI("bE3F±Q2 ,!xXXyC,!CQզ{o8$ezQ߄ E@,M~1J.-C|q cmcK*W]ۖGqWU"M`>+~*KIm|%;2),NU-2Ζ$}b0A?+.DJ@\";5VԠc-))-m_5vD5ZuYC4۫?D tEȰDKĠ!f{E!C8TS H##F !'4p 9rQ24G# Kd0*}mڠ{^/il9U%GRw)bf:ͺjc%r-N?{7QVB*'dMŻ$o_[v.56'XidF"N'v%!Y%b]?GcuNnq5WCN&>4L .~ g_;b5IDō R-pEj-Z8 lG˪^<J(bR/y5l/S[r ms߷|_ u_ =#H.hEާAJ78-J w bbf_aT^1{@#e:Ǻ;_|sCaHۮhr|xJ^6Xk>=""JY֘t}[W3nV SB fZ_?ެGzO f oOGw{0&\B ?3endstream endobj 304 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 6499 >> stream xXxTUھ!R:ARDH  IBL$L)wBPqa +e\==3!d⺻d&9s}A @yxx^jU\lzؤWO],ݙ L% 8`' xj̸ Pm$,M}+n_jވ$ӧϜ:+w4߀{}w j89;).wWXNio\oP& 뗮[|ݚ _oms(jq4aYd|gʮ[n ҘiLOuFfya޸hK!lJQ/Pk@j>5ZK&P멉T5@mMbj35B-RP˨rUjOͤרYJj6ZM(j+EviJL8ʓzHI(,5L RèEp-2m8yn`E+A=` 6f!_ ʰ&<5|p1qDGmnf>,^#4z蟽}ygx_vsZZh̊1W|suxeW|}y~ϗ|-=5ߡ5U[b(TZdP^3ȑB," =2 ,:ۘi `AWB=X[mr?rh6mrI}t1P)Fc&1h4]9m@Av:PÛmK[ֶB&>?|V) o5,!l/XP t0>' uD3R;{kEKEl˃NHNAA\0,>|ljc NkG_=x@Rq >c aS> /fyX1Mx\/W_+p*@1qϰ{!#4IN(6V&褵ēEt'6ښzk5ģϲz(;>+bkmQJA$l`zmAgE5=SIJ;oƁ~rxh֞JP kb_  襟~Ӯm椙[5:43[b 4ZAƴ՛K318 ݍA1Cw]8^B/9O5#)B $uaS-V( mY5QFa5Td= ;Ю;$[ beK%N;Jy©$Ŋ{ 1VqB?iUfK^I$Ҵa-Y3d Iye2dgC>Ѣ-qŪu+#)Rݲoo9p/R %QPA%Czێ˺U  ZjJ!oZːRk*Ǚda$5M@"d.FC>t\Mbm`brF((C'dKCAu?ӧ7;⇊պw&XvcmVpMgR&W =iR"v_˯K ~ʭM=D /4бG~yKV\|u2GN>WX0}EИߺt1Ufױ.>AeG 'F+~ģjVb._w7Ęi6 u`"h3 ]5xDF0;Fj6|Gt n0JcQ<#eΐOh(ϩ|7┱ O\@f{vnJu"nv[[]wh)nFkՀ&6?A=d”)͒F)^0^Xx-샆'ZO*f`  -:>.'^$!v:9|+-5:!M*0; AIK8T"4=l KL-Wi2/yz3A ' >λeݮh )Viuh7/ms:,VO"^Yђ`k=߬ށ 'H}-<̰+5P)J GjCУͷfO{ xW M0x*E^ZU'" tG՟"!dpFN?3&ڈN*$2wh @q䈵ܑ;ҼZ&WꂴJ(N"usrslbw5B *|I˻xb[ :ssrsKsJH|]Ҭ%xs'3rd?$Y6V34;ٜS IzT0mvPKVAv-pm+eśy䬹4 EDG5}DL|O=XIx2%M-nShpo@ D#xD$ĝ3= v͎D8U*oE˳ r|L>4tY{4P…pOIՖ 2 ->CtfywvN'NF^v>umA;|Z}+DgpUjT*](j#҈hiFQdv 2a1OZOѷ/l`ϜpW[Bґj(*$@l}يP:B꘥F>)j MAbks,hF\o0\*&X$IȨ'[Wama`)þ|y ~o‹Bx]qCpC̿C}xF\KXDk B)ϒմaGhG"f1۱^8wd \..<^ M''`=!腏~M >Yg?D9 yFi96@ |ŧiWxYo0RAeNٴ^~kk:= x(qDxX88wVWэW/~| N™'_Έwқ* }!N> Jhj"q% 10d5 'Jo|\tbugۋouhWق,[{"eёXv{ ą. YeMǽ+~Y 'QT '슓 p}1B!>&yOTCCǶvd{8uIc^]]uiGqY85T|_S3q =jLӄEGDIIBVnF.29ܜ<ͱ+d֔ i7^hXy"~FF$=G8on: TjmZ␏3uooa8jjD!x.Lio_؛[R3h#z uJf%x{ ~4S΢znq[hq5PRv$T5Q-P[қ^*~EfS;1&W@ HI@WFog,O_S}g#?YOzFE<ߗ_y>ht; o8_)l/z3Wq1b`GfՁ(茸djC$,5p p;(lيs]G%uP ؃3{7u_;OFy;y1RTAkˏx%~ĶH".LgFj#;Hɠt1[D2BNl:_q&0 iդ*,/+,ρ>*Q 7!+_aoZy 01+ xl)dޠ֑nuq ]NZh>7YܒT(>>~QӐcxQ?!VZ[s!1{nF 8Ks[[BWY"!͕UR@}x]}8iutV>/tvzi3Ap fMoJ#_2d4ȵQ6@VbJ_pU4P(zr& 4:!r͎fTZN։+~X=ɓHخٞ㐦߭X*]t( ւU[оX`9W|l䙫-r0 Vid̽T(QUSM?C 婠O6hvr.zs!xTAx/0fh:HTY[NN_>[Wk.6G7QɟvEgB HP 5WZ*yygΡN#o\ ~F $AgAsL_A$|\q2i2 2'jB Ii)mK4jG[/ŪͅBɵ7O_w>X޸ǖD0F\B.r my;hXl hPQgr|5dE⧸vt;\w DG #ZVmb)>so< x.B'Md2lגO^Ϻ}=\+#R2dJdMB:Kq3,}!]aQodO# .V=a[,2*ke}pNnneCK E­OgϏŪM[Q,w>cz[߈U<\9t 囫|,uiS ekjC1Ӧ,Р8+Q :[ꜮtzE"\N wƯI"hEQN rYtJYqnHO0.@7dY$CJP ?/a,`>"@%nVJ4PZ -Zҋ?'"*4E/}SYo-7",\ C^m|tij@^qhw] 8H'[nRMYx2 m<<=-[3*L\y0-d{qnš)48 {3餖a}h_B9]ZKެ?@l|^Y-|2f1ljȜ[5#S," # Dd>s B{PBMq[4a $Аjsz^ItAnTU~@UOΎ#旷h~X9߸@̗.*E[E"KmܐAqðm9?k6lܢ⼜lMÞ&=endstream endobj 305 0 obj << /Filter /FlateDecode /Length 162 >> stream x]O10 JXЪj8(NߗNN>ˮGֱ4%"@cQ`}*Bv7ޟ@n]O$\VBoh)jI4J 6/mR+gh.q\b$Nii 83 0AS4endstream endobj 306 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 335 >> stream xcd`ab`dd74 JM/I, f!CL<<,o$={ #cxz~s~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k꡻ /,/I-KI+)6d```Tg`b`bdd ˾*p?nv.WVUUY!> stream xUiTW4BY=" "*",P@" 7j&QGAA  -F|3y 9NMQ4MOɌHZYf8EO"ل,q! %Pt&l q 9kԬr;۹,onIJ 2ȌOِWf%)6W*+EQ4ԴMc'$O(E1g\y:̦(*FR`* ¨Ք JEPn ʃKyR^72ʘ2xj<%P(S&RtO6^>=+$<ے@I䕾a&c|'fO,SgR3|Q&Z1v8o$֢"1m}Iks6nmq\eշ6_]#ڻ~uBh%3:Dj8-^{l-s<.fNPi2ġ.Dc%"A 6*lf%)!^FذbZǩ/@~*n+|GV7 qx p j`Nlq`NU%Z:[jS+8TT  6LۺuSvf&^4.ŶvA0|.3^㖢=E&HqSޣE 5mU [ 0OsV΄\T68Ydl%ȯ>p?n8Խݔ"fNp _r@*ZK־i/RޭU~Ĺ(Cå -f E'2m3Bk=M6Uk-'Ah`hA_UñnUs^qʏ=v ~%JSw(q=. Mlnb6x֬6D#κҺ!g2 t@amؕq޹XLPٱ*p&&bQu^.*@ aԀu2(ga.FgoK33Ɠ v kKrr֣I9Yel½%,*?R噓K 95ydx-콵>.jX`~9v/[,0 q60LT?VŹˆ=x}-6u2LRkl,~s`IQ(ŜPܧrosZC zk6E HY6x(k\8yA{Rrh{se2;wVmTf46v.x>$/@s]/Pu ;4){`D3}8HGH;+lcJ$%.B)?E$0Ѓ2/3ãy+*ktKe|][BY.oV~o^>ބ`,Gy| NjI_~~x;0^LDv<.Z$=L3}yL)c m"zg@||mq7ÿ(0dViU#b>۽m?=2b̻"G RMO=$Uh#],;Z_?t{yTv0L̀iJ})(j [ZV o)b;6!!f$ ^kP/2M +3f!<:`Et MQ҄rO9鿼aWY3DH1r h(@X h 4l lފdq+u+֓ _"T Q̑Ư.k_Oέ'9jLvEoO'sSU?[@}e6!r$1iY}&E)6Bp`~colkUn.0cX_|뚶0nq;6K}>&%EWNAFꬔuٲ{ra`N¿\I,nFaS1Xjبiё葪 zLv̕o |z,L 0C!S: hWo s~SnS n*$.{įlS zǸm)FV^ BB̆^_`A̻o Gϯ}tmZGY,[ŋ|oօ%P)Pڋ<2pL%l~a`I#O [eRǔDcҋ)6`ۢqk'C6/`bچEWPh|Y֛e|W1p}@|ކ(ybcQ*/F|:hh؝o8~uendstream endobj 308 0 obj << /Filter /FlateDecode /Length 4706 >> stream x<˒8r>/xu3˞7`cw{w>PRkJ)Hz :ED"ߙ_6C/6= Ǜ_n7zwVabsg\o: Pw7?t('нgy7^οf/nok6UJ|x?}){Oaۄ27!k/Cwgw3(7^pAsN^uGb%n͇~+A Zw# ^R>Wp`A[X惐]՚1kMv/zt}UBi,#C\i05bRyw;%hڵފr*x {7wys?t#' LA0m!lݸ)pF8ݫMc% )D)ysA[`I~|OWjCPODZ^,F%[=5 xHj65ȟ.t?v [p9r+h&z CX HycAP cBl0b.xx@tl k~Pgw"8EkwE&(wv>RTU>T!!෨n o6IV!B><qea;|wȔ@ MnH.3@KMC*-3b=}b F=if-A H{ֺh$;Za;]Q-"0HĚ Ȧ'S*tJvi"=>ǭVjՙ7JdTp`׀zdJRRG k9%Xni B3]9F-FqVmw52 . O]s=Tq*Þ ᢰ+)]9!GC x9oɣ`G-(8ģWAK D&J8'xAd-Rא"=,Mi82BJKHl"l @ < 8\9NaD@<ɶu?"IQF0e"U Uʎ~S$!\kw-u]*WE;!lbfn7Xp, SC`x-G!CԷo r_zZOL+9pNJ8yF'p812%3~BwtޙJƒ#٠R+9 hEj0,c`}^Uy;B+@ %{K5*Zy%G̤!~$cD@ i<)]B7=ZbxWj=TRZN*es0^%R&?4݃D @hQycիy*NIV[ dl?ͬ Xc6EfeP*_ͩ@*\야U㯲\sU̪q("f*IwqȷT<5eg} Oޔԛx4)yʐP@ЈM#?l-X^腿2FU!eVg˴|[cv=Wev) 9:age: -^ɾl"B%騧LwhPlv `W)V zx. TaW^J2H/"% >)s1cHe &NLiZw[e3Kr 3tw,edu*zyq:*`A(,”e m RL;B|?c"R]xYdoI)֚]:W}#UJdP<{i& YLvYb㢱t<7db2ةYyk+M1iT|2Le@+݇;.'Яw& kRVT`-Jˣg8~%'~& ʅ.ڬ f_r WڣZm$?ჭ; 'Ep'sD%ǀMؗ&:ĦʾA<ͳ'2[MI0b*(3PtS97;p{7>P >ixCLC!3+cNcLU:} өU YU2w˝󺹱LYɕƬpı5<Vq_e=y!L7&}9h(&L2U95!% N}PAhgҸ[vHv X+|ʤ"ES})MY"ꖫ'GZ"h#Zʹ~^5O/!Kx5$$Iƪ݄BR9!9>}ȊY{L4.8CTGs5KVQ,q Odz#[Йđ}g-d+ h8ϸKsD5qS Uj'9R*N1B 8N SacS*kCJ2|&V3RL[azm̐ZMݢQv+pu2kҼTJKPFWnv@y?x;Bc}n[ǹ.uA !6{݀SQslWdq`~/D%ʌC\X\3~`T.N֡Ek- 0$rSLmKxJM>2$?F:0c);ά-ce.MLL~̀KCvu o&DŽ4!}XꀁY9%4rb_w\v-ZJcpQyjS҉p6$ O3P%0ǚ@0ec"xA"GTA/gvVg@x{-pn@ ~qa2m`˯y.|R;vDY9OsJ^°6 %,zK/hK?[QZ6Jcz'ŷK(JkBj$qkQot(7%U$1y2L.jokrM-uST4r+`,ē1:7 qBrZJOA~_2&؝&W}$:噼G ^<=yn1L|PMM/#l"u]oxV:ytKq~p{qܿ^W TVIC;R|`(.l%!S~`c?e(F|ya l6pKMe0s0`r,xnFZ5zfKLc' #3OɎ/7C 2\58%,Jmڀ)pҾ1wֿ+u4["B[TzapiD;Tٸ]2eh&4ꆮ:!؀{$ZmGak_vttIPTfp;cؠ09"e6.I:IKwޕ9EjG|Mʹg CyT\vZ{8-Q-r3WZ&`昰y,i ܋]{^\";ƪe@0Cy,c_7lL5*9FD)RRd&/c뿒144\kH>o[7%]4i8 ]H\di?N%"y]+hd28%{h>ʌ4V*x{8D8{qendstream endobj 309 0 obj << /Filter /FlateDecode /Length 3713 >> stream xZsܶS^k%׌&8ؗ$>ΧyG}w <ˊ2~b]4)s/vG#NOݟgˣ=$&5xN"KT*OLۋZWYS gY%i/+|cT^H* &+)N4ZXY_e-OAL #Aj|C ƜIɏ2Z㸗gJH&c]}Ӹ_Foں]^nʮ>Gݺ/4~]6{ݷՂYoĵR O߼[_tv9ߎ\Te_,3emL\hܘ?<-,%+q&"gvT$wF=O2-39Y=>e][%{[q>v۵Y&-t87tjtWw*`ec_.Uf]5E+vlaɟ8O'CE[] -@8Z{.n(]*_VբTHvMݎ=oպޟ?@鵽lIRZ?8qqW2XM/_W"f0z43KuӮ>vwy<\+"n^J_ϫ@*^vd'}הոWm>]f{Y_M|y2h"峸Vn[lZg?{z:xw /}W*V6oʦ tmBc*ٮ7`n8X]dc氵=KTk4jǎli,7,-a~ I ]{/Zx[qS̱3`LBR@= Ho$ W M&i 9vS. 8iլetx=b A}/NK5 uUl ϥ 6tڶ X_DlF{0۲[9fP *HC>M k|rgoa.̔V }ڤ >m83@\M?pu#DN"Ș&äPܤ&#׽ągXG;WbB,۱-NJ-_xsϥf 1 k/ 4/Ss'ܭSKV{TwC\::@~2P *ՆQM褐ڕRY! c˩tPEZFc,:&ù =M.eë4%.d%H3(n_ds[uQݴҠ`ݺ7(M$׽Yu;9G%(um ЮJXiG.mzCmpTD'.efvʸФ<1T5>Di6j̧Xsx0KlIvPdqy.of"ɂZ BcJM./EߜQ,І@'յA `Zs[ )Tf?Uq2W`?Pj%r@ۧm!!ٶPN[( n E@uX irPhLˮ<-^d9l>\Sؖ`BģbA#?S9"=ՂQaAy2ɶQ.xXAJiۻC:H b=~{J 0Pmrl oe}E;#Ӑ/.rgU<.fXyp{ν3R5Hcx}'1 ,Xtܘ%ʔV@_^( tDwva?>_v|qN~H$xE &`܋iso[6w*^N!,1w^E9j<Q +<d*A@2ҏ)1+qp'F5AYU}%W4-ZPci$Z2h^9ʤY 9f9Pvw>MEHOt>l5U~I,Mes*$z*|Bsq*X]*=08f"MjbݩJYn;Nw8Ow*8!,*62*:V#̗7 11R/VFӯHvʨ[uHb.=52dtm7޵ʣ~eDȾ#Y"yo7{Ps,X2)D8$bB@cwF3z)nLAgy$# }eZhSZ#ʭ`PXpNLLw<[_{)y r`WHb.:p Й-](df7sK5rvUr psA؛)!TPC fUgJ0*\]mW˨:6 IͼARYgiU L5TgYT!*!Ga:;Nn| t38'^6iXQ-$.$ T/ e۵1^ l@ʫj[A愲k{6T~oBXNC705Bg-}qI > f6,i.sKuR}ZZG4/KS[U6h34EKS镙kF58u3v9,LUE%,tք 1 >](1˹9ğrg dQ3!W#B7-tx \xˮ( < ZfEg.a7\\dD"9ҿy5Au*w*lR?$+î,ݯwo^^BƇŠ ?HA\LOy\IqG@%~8t=H` 4Ǎ1]#Qݸ5yT:F)A$nN2מ6]>#o% o v1kK7 孶AE,/vc{rM{%ГC|cW.+%YQ9,-go4(vݷ)hW9޽) f[UEjaK^p5Dӈ"W||M踸roوN1ӣ~w b'ߟx{=~-K_BMLLr~Of?W'.^k_K2ϱ?_zwzdJ> stream xU{LTxuWIwZ+nوT@@]G`3s^ak`QpT`".m֭vMwu^l6MJnr|pl?)+U$؛R#*_;#rY^\Nh.DGĿE{1.+LUɥ~N KeRPTQ$LMLOfȔTGV!<_\"* ebavqTۙYw2:mX_cS!W* Kv;IJlbGX mb0'3q8b/"z^M_zʧs:z68ϥv=:0FV&eިw.do>W3w/扲*JܜBNsga>PL&03aj+j;ۉ A p>=& t󯔏/ ;C׀EԶȥ heڽ&ŠX &Ү\5U}HptE14O. >w6derh_?K g=b$tӒtC)L$ⴾP TzA?906 :=k #K%S#ڄQDHNwLimpE[n3K~V[rX-#.+JHe괇#4ROxc(Q>S%ղ/btҺ|KfƍJPs)6`kq|,4DxgѨl`t=2L$37@c1 "qI&>c\[8Ih΃"IWRBՔ l8%Dbx؜Ziv4YuVYudZMSsfAGsو Aq- *hcQ=ЪL5jžir\[0shf-A2Էԑ?f :늡VeeBVQ3 bO@x s)?Rl^ XqS ̱V̸ ^ (!x|Sae$k:^{5wzMP%[W TMeRټh'=up\0~6n8Z37M vݮVOy+//n|dKó|8 g$ I:{Aw.ڼ$5(ud 7kȎSn݈HtUٗ-ٲRvux!ES/kendstream endobj 311 0 obj << /Filter /FlateDecode /Length 5540 >> stream x\r9r}/|sѡ.c˻YNCQCRT4ٚ(7'LUU7f5 D"D~>|3FOWw]OBÓ _;s΍2B[zuJ6}VNZt<Ymcb#]|ϝ\\>̙7LqZ eeQ~Wi{s|ӽo"4l|5- '86&{gUc;/8-RS]ņÞiݤ%wW}/ڂs3.zxv/7UvH%IBDhzUh2/PBNK`tƻA^8`-x{*ÂY‡t{ָ:y1U*L('`mP=qRJf:"28c,n?yEFN4v_V<[86dHĬc|ʿh5|slv= 3Z4`jlޠSA7=Hlߊ]벿v3>vˊ;~Oc&\{J1 ĪM9~ˎt }sh!ECYM6 Ϊ|W8MT"7nރ_\l`d+5*A¨|-o /rHoMv$!̞H՛a6-3LTGؓP5s2aR,"\ۥdL}S_V'0`,1$e( ll׎nR*K|@blQ1r&Ϭ߆O^od,r[S mBpFn(ƺݾ݃Cطz#t0CƱ[/0Pc|B.TÌ_/5g{ŬC!f| C{r d'@kjdh O-KU  /SRagV8JI莿(cLvc4P Bл㗻@WaVq}GsUd) w{"!Y9GLPl~eL55N2T c:ݪH:CgBR8/ؤƼ>6b&5+|fǿnjyRVd)*jn-E2WWV k^>CŻ>~7f`PB<.8=v+v=Mu-?[T!dgtexZ,$n xRyrpDFW0xSM(ΟUvJ3ϗg:$:?<QY;z-$BOш7/$Mm71_yyzuKRo[o-d ONBq3_'V8=n X&08O!([ ~0 mYȌSH46*0ڭ{L^+<;7_h6= {`v$7 }9vcw긑H;jj`6L`ߒG瓃HGp(^o[woI:(b |c$AQ=n' _!XNq82pK I#OHk'!yM9ЖqCs4!v)NA:EXIaOjzZlir͕%,}A4L3n}8l fط:9c4T6_AWlާt>bHKҕ5:FtQ._̛N K8^9>Wk)!#D%B˩є唃h+xl^' }P{i("73ֿ$N8:l2- }"Sin#9?8ZnhSX i?5VPоcIT'CBȌ=BgLhsM 2H?HtZ60U7s}a0i>g@umc|-cu$e&*a/r+*U\"j MF:@~b94-a3A~'C7 %D\Pv)cf p]d>R = EL.c|<~`0uNl u,U .?]&VE{KO* ZAM r};M8Z?]9|9iFݐ<g8{Em<pNLHiJQxM=Dl+"L>z}?kAmXO{O.tU+xt'Ne ‘8e*4~Z#H*0YJHe- LJp80o ´qv:*dR%fp=񕤕d`7rVvnS:sW"pWd6?4-|4bZ}Qce 3҈#[EEq~UB%2Q*c,Y$ 0rJ >~+)SUwJ5[z =Ơgd̽ȇ:nCj. dIW'l;ܝo5ӁW} XBIRa~O\K rG}*6f n3K(q-JP+1ӄ Kw q¤5 @yVxY7NMQCW42Sr.QO5og|$к)l2 ,NԶMRVhS0ilV*W&ᦡ&\U,7l5(@Tdp_-zFIoK dU8?㼢Z"eLT扯ؕiFEh"$ OFB$¤RDW$4FJ[ HۡNLZP\a-d4)ъjR%i}*`K 5*KLP*t-y*\٢ãNbF Ui䄿bٯrԸ[qCsWR1dvʳU;$QO5}.Px@&™nh=%k+?ʺ?K//>0*/~'8>N΅ i̯Q5@"prL+Ca$&(lC`9I{ &,7DYV7a8څFR1Ri 17˟./$qf ~\liuheO<?R ( Zԕhi¥ŋYLt3!x!`EJx:O0W6b\C(osFX!p\UJz~!R7!V`u^x[ !: M[h3O?KMe :OnXZNA fg[8,w C޺@J]\9IiP'ky#? Ӫ~ ._8cŝFA+gIZ3H\6%oH _)*fQ݃5??2QCmҶP[TWmN2Yܠ9Mugfc.kw@/LBL>V ë埥"#L |)J6DMmf',$4?r,*mV!7)Aendstream endobj 312 0 obj << /Filter /FlateDecode /Length 2411 >> stream xX[o~o胠Zp8CN- uV(%Z,{\& 9s, ,?fvgϨz;3moWg2t;W,baY“@2>[Ϯɿ"gsP,_,)HIX2Ƃ0d"ɓ4ISzt5p,%x%VWyRS i $U}pDwA{&\#Itltd 9e͊#17(%3m-*Wvf<+Owr~*BdLED.Evʁ5QL}N\qVVSTaqhlaRx+'7~y~~8[\mQ iSm$']'R~z&ms<1}f~}޴7šk|P) x,gE/{MHuؔYt.Hl43{$I$$74^2UrZ( $-;r9讝IDʧq&M!dRĜSMsM*_e-_F4w c~~JaxʝIHɶqr:lI%`X!q(1  {A'J_W45ָכ"IprĘ~jZ=x= W('ltp}eh%VƐP@?+T^C FVxt ri!7%3>tM;MQP4Ɣ0u|4j\ VƏ  %rM6J@opk5ibKv\,0;f[p ?&{c<0+ա[ R*g+"T >MKۺiCp3\{챬) UHv虶tT*NӼqXƛO/mнV00%"3u`D ꉬ4*`|nKkHPx+ּV'~ܹPT D y*gwո,4Ha`^jDYЀqb'/t[[V^Y2k$t#KM"QKpMBtH w8U s^~i$PנX3B`<ۮۼlJzan:,IOu9_/'v!w~ή2ߟ@E41@oakDt6a6?Cwfm"(kc_]6`]6EwwlWMn#NQ2 Tj6Op]eu֋(MEuSyrTU?܉&N.gG[fA'`W><ו KjxWcű01ۻͩTt7=~nNz}_)7)|74n㯫pr4cR$#rWS++ @%վfۣ#U$jwr4H pik g>QB)y)݊| "OC5WF® :$j͸7ɉU/C[ʦO!MIB^}(3Lq/ ;ջk ,р骵BD̨v̓ 031zL;9Ay1M:8¼o@û~wwdnjX) Z))<5B*p!ۜ1v&L8(iY JUe@k<.(ZwHq1~4`_ |3Dz;/My9X!"h CתR_#NHVnQ;C+ճ-.I @I-OY BV} sxU88K#S-dwYfHבּJwb\ 輸[T(0h0#N?)8 :dw-fCmf@KFٹmY!+φ9#qDhsA?N6hYv,s+ɻ?P9 "upU?Ǫ.sNad[vpu8q5:4-ÔǪ8 Qu} ӑh8O1uᙆ<kۈQٟP9 !.`6?ry\luX.Zv?huF?tX{m :"<yӞ*K<A^yr.o| 9B @n+d m{[1xzuo? 4endstream endobj 313 0 obj << /Filter /FlateDecode /Length 54112 >> stream x}K5RݼEv;k8䁵 X7kkϖ":red|D_?yǏH~?_;}l>gm|ݥ}-?OK>nM~?\_W+#]o۟?xF4hK) v ۿmˏ? 9rsꟹ+ߟ95>嫯XO/IO޾+L5 x-ّR5r4twNs7:I[ <$\]!<}G~զU is֣X(=w{Jn_=N~{8$J@}8s#a}>H[ "$#<ǁ1JlJ6|{}'\ZK1WUfN&Vb{~lE< zc,)_cuQ{6'gQ+ #HA>Si_sm9<ŸLݺo qv?njFT0sjrmFO_)}.׼ ɗ5j:R2 4zhNA*byilm%_moz:zS=.A0Wgit!%B•tsX^_X&L{_ޑq}5oW܃ j}6A~A p -~6w$פy}rL>W/x{5{/:۬kk' Sm <i4.: 9 fk[_+ߍ=8w, ^;ڰćǟFh!NFl}K'5emp}s۳]tgp &X\,4@ 4$]'>D[ i%\K!9ٖEcXtZԝ\Ov:} ΅?7OĽ~hTkrfd}r#v3o^4vz-sa6hTƚRܭWځO. :s8֛}}rZ46-"񥊴O:o(;=Y^;eͣh*Al)Ma_XkoX*{ C9֮|hiUR-&f;Xz`K&EO,$Wumqwy`wGSf<-kGEhRRApans1nඎ?^[Ew;79m:Y!~>FXfY_MeWi!-BBZcvn[pz5 b$vhx4@ qᤡC]&E:Qp_ȁ9p9݌)Xk֜ D<;Yx~ab jo 7o f%Bhxn̊i Eo4eغ^9kﭞ689ޢ PW?zi*s\.^]̵kXpV5/wk &;H[b־7SafA'wֹtIk*@h(8LdkmS'SXtFw,DCiX)A_ mz70PMCZ 8*^wBpTޜi6UZ?L e7N.lw73Zp!o>V?3Iǟ]YoPq;;6ǼR$ݹ*!9mk̚z=%4@ dS@pp}F BQ8;o}rMg:vc3 ؅c{H \d;^~AZ!Z 9d!)!}rvnP7ʖoڏ2-w:"۶[| 43)n,$sk(uwAӇtpQQp ʻ\u2'肓ƍd^[$8شN_tci !!aFfw:I#*MkiRy 4AwpSpq5Sz@.: 9 ~]`; Vqٵ6F wWy jZiƉ^bsh!-BBJ:9=)4Zj ۜU}}7w vw,C̓Z6'am?å_x PQAh:L}r>nMWAb1Qy8.9\&DwC44p WcHwl|7g5}Jf;nnmlπMKHTT:)v?c$GI@@N ?& ]tbFf4.H;}Bb؆@pmΛ{|>: R%\EG8F@ݰԽO C47'v%2p6A}s"Nµ Rq`kYؾC~bsD [Әo@4.KHG?ke\|1+8‹Eg,;bǠC|8}Iks:t#wqI+tpZQcm)]k]_;G|gh\[uKTzJ:BЗ_8gtүKVĝI<>9~.Oݧ:j6:=$ܒ !/x6~vNʥ#N~AڲnxmZ8 O ]|}lBut(88Au$dDhQ=%c}w76!Ql˰DNw Ơ|nw@Hp1ءm1"ݾMxnƄ 4A]qe 6<8V@cí[ pB^4"#欟ۚ}#10?12U }K6wԣh!-Bv8b3+j ;87^˺Z9U̶p!Q̵VM.mrP8"$\K!C+-\µq(@vrN0x>Cp+<~}ݨd _ v %Bo!;6qW!$\EGx BaĽcJ#53DbXWH$}B9 +#C4[µt8tWq}rpim.pUiRA⒑N!qt{u8=9r<@ SXRp}ٜ$x2$td3m$8zHEs QQ`d2D4~qjEw> y 5T Kk3MF(>H[ "$\K!<ǡ$zڕ[:8r44ꧧu74!al4@ 0@ Tf>H:IZk)8𻕌+ )vf:,;A6SKe 0CޡJb,՗ TB$P-@7c5⎷+H).zn*>Տ%$:ംD2$y7܈v .! `fcn'Dz[p W44jޅDAwj# /'rfhCeI܂vw؜{vh,p6Ir75i^o:>c`k#<}fxm&]9"I4]y3!E 8.ϛs)p. 9]A_r-OS2lgUvdq)X$bp,#nhGт:4 tT޲6fb3u- X$H㶇3rHtF9@Ys .{rQU%T>׍ZNAnB\$vB8 vk-@zugsvBXw4!Z:ct0uy=zsz~϶G3EPCK `v֠vр:D((9{%QKE4͒ |cqU7p~qlOG p_Wa0rNv WəqY)D,fhn`a胴.Z 9 %c:.-ls2m&:2u+mGxCӗ#ZA٢үK N$E'ruRV-w͝2nG`_wЯ~Tbg&$茉EWU颇9CbC&FX1rAit!%Bµvs:t[` :Q69M8tRo%=,AEu .J 1 xWk;U^8qWloT8%҅>ȡ+\V 0 \Ax A96jS.)߬mg΁T<ަ5٢? cd2KP(/Ƅ`__lM}[o9IwX!:N4e.|bR$r sBETY \>H>!Z 9VcgG<8'sE{NY‚)1,V%F}F i#i7>H>Z8R'G+#urN]$[gLWVHe;9gsθx9'p#ua|1 }s,A6ǫuX[dl~Z_xH`NH6!m^SHK+C2W{F mOu/=jin3̗̗Ӄ6|#ddэ.@B^:]Eo )!``͡%.à]aI;67|΀_њ6 w9Bf5`u_a3bB9dZ,]I>Yj^YmW#C@9Sy.Vٜ3!,_) EodJn'/?8z3I_4tY4a l;g0Q o w'_ob@E 9r. .J 9dH >8ڊ}#q$;]N @${x}lFm'\6:%BS}VjfQݛ98o qnw2|V$>M;$vh du_g=\ewWP͟CX>D ۜHt8 &#&_)p+K89tk*̜]|}lBut(TQ- ls,w:`a0nFl3)I^S,c1pWH>>9|g\GRHZv;W1x=>3gUi쎩 ~lؓKrE88HEM={A{g?%.Z 9 leCpnR rQߨ*ghQp څi΁bCZ> {PQ7=%j (8xQބ4Lҝ.`*Tt8g`#G\-!9&ތPW +lvk1+h D dsph} $p ZADseWov{?ꦡ:HAXh\V~Gp}>6s6蕹pͭEHH@xCV" +[G)TJۢv- ^!Pʲ3V upQQDQE-lMm߼hzr*hΣqpGX||Bilϡ?GQ%>99ROcȴ/I){KD{ 8?qp >GġK攷yp2r*usde%11yJ4\!.FfNH ?C[~jVy}|`[UphYuףqR,^c8G~3;-|;\A<Al?;&́*mGZ003 (B0.<1mt_FLVNfo B#(h7KkjRFBmC!GNrrFA$]F )#|H&{ Ww=n-\µs bW ;< y0̓N9Ji BB:c;L<61-ȿR,)YI, Μ_tkmPzUb.d$\C?/ W+2* +_<C\@IƎXk hT1ڟCPX|fcd'+ NNgc F]]:t (xl`mh/Z q7*TO :m8׍Q?qA-KBxC7Ψ<˪U>lUWeĵpGΠ-QqvbpqUF>vbh!Rqȷ N:`OT~47$NIX4)Vt|)a7B8o3pב?F!7K^MOyzF#ʙ9 . EDv ;@aIF_[p1 L93+d9B}F821D3^MW$G'%K?紸VO,'qrKeKIzA~ z֘>6GI}!cw@Up cKv<Ok8^On=/ gVS/{sU-;V?a%tJ}Βve< -ƒ4Ȝӱ QuihE>9 SU{:2*ğ +xö$}2?wvcv/?G9F{8s6Og 2PA;.ILvlgp} -BBZ;9e ot88e)"~% 2$ל Na @@U$%r$ c6t,[m?S#u1YZ~Y9]b"y#Xnl` Zvч iqcʡ'FfvoC:CWYd7[blI7ٽ 1wtH;$!l"td Eu\GxBӥ FEDH{}=l9!{ ~gt Xл c ZQpΟN>9$ .[AÛ+h`9O[zplyUCF>DW%\EGx_YϘ68L5laau-ھF-1d tvs3o#5kBN1N):':EOO\#_nޥR! !K>&[8g}~}l-BBZckΆ8a#[=1UζMiKf<]Xv@,Cn`%XKo#8À@PCKBx#E񻫎gә D@W!p\JB=lcNr7ޅJ+I(ނlRT92[8\MÝ Mb#8]pnsowl.u!Z.up Сc,ӿTV?B*薠a8Y<rppH{*]Ao?{pX'gt,>q3eK5RUeF(!lڽ7/F5oA>4B[K"LĕnݦswvhXwrtH[[blA֬y@p78nbLqyLh!Rq]L\[_>97o.O&nV]&OeD ;obh!-Bµt8 ͮ|?wU)ã؁`9"$\o!(CNS/$:BYu7粹d#t\[>HÝBZ+) 5Aysp;pR >$bd*sJ@yMp {omk!RqgMp7 N4Ic}8vA% ]ɬkύ`c胴|z)Z;clŷz t6DD2_pCbAgzUm`}%3]~}l%B•c n)dW ;)xq*H&e-&>ߐP@)ts`<Ǵ@K"cfbMxN94DhkGAL8'>A݃cq=݊$~jEfe4ۛ^)=LGmzap=vp';F{<ۡBHEoCnd]=onl&@*D6pEbҶĘ!Y+Vȭptp.!}(Ϋ_ f64yae Ip \jbF `yw@~"W@[A%l| NŢXQ[EXv}[G7#g.SdA-EHH@xk0%(Pt4I;b ;hqk-2t:(.-\"sr]d[}mNF !H: ]:з Ks/V%\GGxBLD NQ.-.q RZfW;Z;8[9'KP#zJ L>rVl-Bµt8t]+osy*Ѱ³)4n`xK6.48cosEHH@xCbVg+M]3nUd)U+ezHYu!`46R"$\I!9;$j%N=N No"=8suQ(,=mŸi NV bD=Hrs$նvsm CHGxB0| O3,UWV9r/d "I}^: _uBit!%B•tsfsrpBڔŤ>nY%andK1##tcЬJf) ΍Rd=k2 oi9ܤoV{|+Ϯ7/L%O,Q//QMFYCJ@QM&8# E P\E^,ʾJ/ [V3%֣H yJ~} 8EZ65V@%X(JDM(4z[qə^e%VrBJ=LTEL#-z f rnZSu1Kxz[8%q#|# Ơ %*n -BBZcSӥ<1 *7tE[er 0p+gs6%5i  %? &ʨ1  /rT 6% r?hbvz# K{{UM VJ /Y*99*:d?e0oHe 8}y(d tG_Gΐ * uX%\_:ZIi3Z{ ڶ9+KHS ۈHaH@ X^~A;ei1'1lX+ßl7CfYjv*-˷@p}sZ;:v􏿅jT_->9EYC :#k!VkK"5Eg[XҸ !!9H@NӔuNg~5~J Ɓr;a[>o-Bµt8tY)i M?L;yp힇)JTes#0r*6>H*.[ IBxCadJ.TsYҵ7eMF:%ӗSQ9f#T8j>H iqp֯7v9F:AEv] \{#fh5?7G@J-(xs瞖.qpmgW)3@DDWzHJ+A6ƍ`e .@ʩ :]Eo,{R3pΤgM 3 rK Y'$,tgsh ̌iYKBxCLy0iob>şqT!7g|qLN52lW8.HmQJ+!qHKNIR ?^P9jP@ nFXk up{msS%?¼8K̯|AaH0De̕4gMj nrŘ詫K;KW5nMI 7$莽_86@AkwQuJ(sZ ~\3f;1E,e߄%Xh#8tg98#iZkqXR TѰ=#sV5. [6L_7WM ئw+i̞m `}Jӓ~1H/DG>yyRf2,$1zv#!:-9]B*st[h9V5 *Hf00yhx49򎰞 xB~:kiYssL]lpQ@Ze ~\[z(3ɭR/YlC6Lye3ӝt^/e!!͡g\ ؓG_[ -U~1c>8~V 6-\H;bDwAÛ;36ǜv{D $\gH>B l0?FKK!VtT~НOJFp90^b݇בQ%BK!<ǡNtkb%NfγR/\=K‚Sp2ybP19iBHHEGxB+7d&.9yHEמH"6&H0h$ *d*Ų 건M'n$b9{n ?7@=i0p7>iKpA&3cp4x={- w%z^YI!#\%<ixKp-fI1ߊ>8gߋ4&5,ѯ<`B6ӗ:g~a"xA-$BK!Ŷ''c{VTs*QucƖ.=.Bezm%\KGxIz`:#E^ lHڂTёNDU%QpltpVA[g?i$em>Sg-1{P}iU#g1 Nc.H w^z2n7bCGiۊ+>$,<DiZ}~}[v8tL햴-[[M)ZF2Ń :yX,FH}~}l-Bv80anM͍Z-bz'6#oHNLz&Qdp@4 sT,gUEl(;N.$&inˈ[dGO3p[qhA+L~9tAc(M#`,OI|yJQj@w᲻,/[ p%'?F+ XP:D9Dk|JD+ݾB" ta@XsGq3!-Bµsg׭&19^.H%~tHhNcklx:R^wc`f2pZeg,A[\vn>?B[o"6Yl'vf!8$A_^9y>ӆ}~}l-BBZ:sZڎYs:cێAVm$qJ0Fp3lm}x$BK!0}ա$BK!(Jjf>Qujndd),EԣeC p>#v .ג,OQRr|Ͽ\/>5\S-ji m//R )dʧTp)ӷvƇTpԐ3~Km!eu?~㖺>i^?u6ojÃ̧%\Q폩_c5BK*?(;4 Z/&ո3s݂Ӄ2\0NV.sI!{!C!r{>x5tB ]Hƻw@E̓?OJCoߪ;ߚ˴[?㐟Oo_.G[e>[_^wʵkCXmA^3tR!5ⵢ@@/L?_3ǚaӚ=m;{{~1k{IYLΣф SB#g,I 9[خ0']2ki"~%G>|j!ՒP}U|Xs7M&f0)]U8Vg|,roJvpn*hFz4vgbݓD8Ӎ.p.~|Kk-9~GܺGe x ԴxKu \0(6}Y\].P$!rzv侻[VFzL/"pE΍.X&E'c ""pfxwl3 #dd(aBȫ%5ުZ)v?Zrdlb~*`oVP浒Ӈs aVLxY- ù, NP+aJkEUvukd֪i~#xZFsekQ^ʩEZZn9/xX|7Bq=M4Z,m ;)g#;:S/WĴ 3Ҋ* !#v:HaK#Yh{=[A}wO-8JQ+msSicF03 `*,$~Vi5 MO!7J=&ߍ5&&7CB/$& jʮ.2e]թ |J;Y8_Z9mjJHgVN#JܰVwn. ) LQ94KV ;KqعѰj kM~piae̛7j6G2܈ye\!Ğ[S괃VW"1p\*`rmܼ-nT(~.E?rfˉ߿Sڀ8I;vDٻ,i%WgB5-UN]>&ō$ PV[}?Oowknnb gl˪߿ 3 hz(C(d`wۚ>>*x?!0Oٵ;޳-ikό"Vd4h pH7!7qN%k*R!\H@fX>1}ZE' jtٖg}i+bHoic45+e3ՎH;{|!/У`0MV]`bc 9w<̧+yzn('27$IOt.8gn {Lof_X)RsT,ܷOfZ)$TIxጙlDpf*aӖxXk Vl8S-UX#kSuԘUgJʡ޺ZVlC0ɑ yx*#v5XE@kCde4 !q["Raj ^(ջ4aL,X-٧Bpe紅r?,i#¥r:<͙&/qx$48-,<6JN FCD 3z=2kU9v8*bĩBdȱze0,AÒx* ?1[96gjJQܜ6̥ñ#FgWJ3YC2Ll[Ƨs39\[ԏ,ۂcv:'דsӢb)g_hI c cmPm[mz9,I4-r*Ό.AOWNX.8Dv} G Nc^剂њ fכiSp C*B']@>ۭV󕠉3\bPuLo7K[}2a;aB.Zfzor.h']a^طQ:K9|Jh1ø{+Seޑ\KWFR5* V gS\Qd2#a<_Z֣Sͼ7o?N`3{4vk4 Scz]0^smϣ3nNiwat7+9< [һ^4l#"O} o^i{D~G#YHV6f~~|uqn^t rhѷxZ3;))$M|qpeçiVq8{ajfN0,ƭ#b>L1}y4ҏ=Hޖ-otff8Þį|lldf0btA\n ^ܖ75l|93 da}ʠs$mӵ"̞Jk_!3[nK:86Ԥh!xh!`h,ݜ1oߙ#5#j3&n鴴S]wv֐zIQ'n;۳QTVA$MrJpv#`7Sc3ʠOeVL֮b ȸ7c3NX1X=e^󰳀_==d;L^)ק>ff&gs˷`sv Fk&8SfWڋ= h؞!]rQSnHFԲ[8_YF AY#O>Dz.^cdXXdC>)OKIpd̫{1tX ׬Pws,_p-n`;)&5bn.2#|)NB6Zjwҁ>stҳtLw`(G/g+i\lr셉pP;BAj`gL+V螽P)3c㝳V)"[O3\x;U-N _^3+ifobKL&W>iSP4KSn#ㅙ9+f .o'p7з7Q~ˏ}ff9DQ;߆[X!b5 a-P84i=0֏n䶇(k|'3^bWr;ۄk&~QFex]lYT=u D"=}m"ho!^+F6tCkY~?şs͕/#0. }uowagR 2i`t}3t,ͧ7K/AUmLKݍC{R< ZRrL*GŘo=< _gu$ݛeVa[U˭lxϟN?'lubRyr.$;n·8'(Mʧg߷ު15 jց{k {P'.Tlw4`@v%3[So86{H `Qcwa/-| cX8b^oEeuYh=M+Mr>ꖛR7,#j& ƣv4x"K?ra+CK2SV@S}>r)#?;؈ 96Y2v~ ߈W9ٌ͋XJ&l ag-?D.eK8cl6nz3vDgfGsDۖQЉomQߜ@D=f!r٢0Ys̢òp޺QDF9RpK H OrL Uv>m]G+|KEᮢQ .llY0[663]_*zDcO?0F'ymWlk3H"kf˴ho9/h+[Atm7/3R v,Iu~G|퇚 e{$uF{imV<H]&J|F$Dn6Oub-Pm YQ&>`n+{Pv\5ʘ Ϲ]W8tD+FaOg $oѪ)6 j%huӊdHPrƸjT-q ς?j10s/8!z෠m3]btT!*,vft9lH(Ξٜͺnh96|r܏2ёo]Lp8%d }sZRS' f4%t^4ws\9:OCq8m-Qo`?1k-t CW2Ff,82>;e2;̎rGo|v a0GgXy w2mp9pӓYl(کȼK^Hn1p/2W>b(D-sh LU`6L4׭X*[giMVD6͵yyT*.leIz_9Ųƹ[`鑻_9uk ;؜KY:R82 Unp9E3ѯ4Dh~^ȷmOODڬ1F@2Kt}xxsX˨SVO G0|A |l e3ڡ۵vd1zj Q9+"B0d5P!_6`{52F8|!VB+mc'UR]KDO>ieX _FBde{jZU|@* =AGa3{ nVAvac4uCK ]SBx;`xǁ%2Ip ONjgVv ІV/K Y&GP?LhJN_*ra8NҨ758#rq1L:'Zs(2klSmF6fUXJb ΗIcٷ*Sv􆮍ntܭv), %|NIĖld`eu{%݌5I(HJ~c %7EWz Kw*eyeOW h$%xY#3>2o =]<5IV;٧7SӆO^;1wVՇLc̅DIeS Hf1h:`#Hn>,x8*#0 :l/cz+37[M}Zi+^.pYZ3vTz?JÐe 54j{?ܵBxY$״j[JT%Ly$x㵰. #wu5QuKH2FXvSbI|o8$%^# '(mx0uYitn ;|8c_mr ˎ fT݃ϒӌjbI*}%UN5}76}ěMvmeTQeI>'jY0%6N\@uKqy3§ VKg6Ė6RO~ !^kmчI)Rs)4+J2]x 4">qM;,i 男0t)ӶR쓤R`\?0_"3G]"Fr?m`eCHI,ڌ(yC*JEKp*<$NB:jl) @+Hx"gTYSh1YR"aķX-ʜ*]5*?'ߦ>hGUy#42N1H>y @`njЩO[VC h!}ta䀖F*i-Q]Q#(O'1iq99<׳nR|UuWu.!뱖Loa]KɣQ.nuhC-%UA/nM"ΑGf7`6^@&?AFFNa *P4ZP9JxՕQGFůOdn:ͱF,z=<NiJXH[URq5-Eʼn'(5ar>w069<$I"#:% !&ybg}8!O N5BV+($=_[ZO!4sdmQL%IdU,I+HW_%p Gi {Vl0d1v6 FMö< !,+2 z%0xh $;;t*`݊DЍUG 1 D6%Ag*Ĵg.Z5[̱!4Rk Z扼;$uM)W`↉ e%V\8\0e;lۛu |kE'5%AB*>7D}I)N+&osbs:2bЭY6ewN@7+\P W;[7Ap C&ZϖPeAы{ך0iNw@~x Фl,VaZ̰-_rI5sJ|3 ЎJjz:]pwrw$apbAH,!:T~MΕVm€l:Mu. aжV]&Jr9=*/vT RvS,~C8X"`g37@ί8Pcx=Jٲ݄Q'fsla̡2i`b#Vw8nm"d` ѻ`h]c6-N }H6cpل= ޑ߀@.0=YW-1@Æmֶkz\W'LrϾ `5Bt.+hC4)vP0[l)TչlBG`8!d&*VqD MxԵ\>g0PT4yJ9|9j4ٶ'٫]V#D!/Uƽ+ L,+Rn 3R?\0I|Y':YNN}0Zy#' CT1c;"|*e0 n' DRɍ<>˱- O' [~OWcÖO@$HzvP⢛6KeZ]Ļ"+WKǀ`h6)Hٓc$╱<.7% f6ʹ1{m+a*-hl& Σm SC2E+ I̎ ,IUR|sc'Ub{*ClEny/XMFA}F.̲Efc\Huszs[[*S*wGҭ*f(1v7WfAcyir~" Hc9 fA?Np4F1eI4"*/='Ls9kyɭ&lDWb\#fayy R;Q#ƃ />C[Z||PO\c'-3~pL1SXdݘAmt$͏Ƿod9}F'&N)#1M[Q|:``>|PФޘ'%?3c*ʯ5 [bqh@~9HkϓdD~8w',ai>5`r5]BШX n%~T9f~L[ޟdά٩~P4_Gi}i~mE>hu;Stv <ƍl*.r̨Uk6J[3 \[f,q*P._-3F̠vv9aoߙ HLpAҩx'rމr'`) 56>scI'6afŷl巘u_zSA#泛Ol쁮˷d-[BT2A?#VЗύCf~&;ȴe!D6t(Idlɡהc ,%CS M^?L8`/+^gCI>;kby,ٙ|0GP'*bx2p)2G\rxX֔U%_T <&:9NxjF`+xXP^k ~l[!KFpHw*,K.XUPfj)udYۧPNJux}_-V$ FҐ\ bkjW2"|xdU?J ab}t"Lyh+eu&H+txDE$)ZYKx)=))|?v*!TI)3zZxrh&!"c'x24lMo.9a*[<ȼWD\o-%mn >)櫈AeP#s(V*z֠ήBQ:  cF; e>-:I$BΙ͠$Si3L+?,Vp#ϋۆ]eK,=h\ysKky+d%qZOO(f3E[L1O%v=qIF(n1Lrɲ!AiYMS\IJx4=4M?fqtڪ&-@ẺKR|QVi XZ_:,VBط!( OdW}C\MB ]VoPn }JVcF+ՏA{s DZ!nI z*n>6gAu v6^cE<5758e_3s[# ^tll!-n:XFwɫTDo(ǵdUڧweW}c B@:[,9);rQa2ݺ*-rc"IxmfVl#I#t`TX/ׄah`1Wnju|\(&`􌶩P-}(nIĉ:5H!V+9h`j)+&NFP=A8{sv Յy4bEܛfIG>PHvvSJ='v(8Ybjb5S"AAhQ-5  H&wfd*Gfsb? ǃ>=)f1w  H!>ޑBND6 *<=ak1㓾45Sz=P]H607z2f;#;M\M%NBU6DŪsjRDdzV\3h'Tq1T=ܛ5۠cB`J'monܓ6=0+6ؾ#l#,diN1(svIn' 'Zٝ;sw}U% NH0iIZ!NKCXWb'#`hikeL H`AX0xDJ73'6HB]I!T1r 7";ZޜM}VhAy=@p28RHaqΤLMm>$Z2 0cX:tGyFv IY"Jp.@ѻH-J1OAGVE:> .DR!HXnkހ0azm%Ayթ@GCPdnrIҺ㩤4u]~*Cp= |dX x< !z]˸^t#NS[.nF.BRkOAGMxRnUckΉ]Q7MpL#_P}` BntZF>Ɖ:nGcÜAcbV=Dda3M{/y`fzvB _QTl_)+,A'0$GQjgIE4Tpn`k|Zvx38{ZdyjZD/=i]a$$c槚M]-[o94n-23ޯQLt#p;y&DZش X3fp"o"ަRp)Fau}2̢NLJ;ȑ(n3 7+U ngwY/I.wp䶁Ԁѣ$7H VU ul 𬼪 e*p|ژkiKG SA,NЂ,#HADu3ۖp1vD5kdS4rJ@ ,ӣMUK. %ŀ/LnHeyFpL Q_AÛΈF\{B9A"s=%ޛaYnCIοՖAW`s E(hl!(c:֖S?T% `$QӤ jkӒtL+{Yؑ03O ~"=Zw8I7lߍnF ph"{(>lR:5Mjcw*vwsl!fg v,!6H znpxFХWwټpaArߗq6M5ЄOA3lu,A5F2gh)YTdވՆ^oßX0F4!?x dNb{ajcV_: fo au{x4Lmj'_v p*)c(.;si6HL*)#[8WI(MװIut>rޟ *^_mvYi),ilG bKq0"rbDkbaa9 @8=^1$A0Jr J# 3p O\O$<m+I9xOFʸ%/Ipkc)Ȧ 6SjIf҆d@SDn"N!j`,5xI ҝ0+)4{[4Jj;CQ~VmA;:]ķfQ,Fl-Zr:2HWA c)#Y`cA% q+Donlnpkrϒ``)VG0E|t7zؽhU(jQtHd5 e5!b̤C Qa'T5CV͆TBo`a-k00DlT@3Z"hiuA2씣c.-2QAs)fhzJ ַdĦ:zKs{t7p1T Ն(f& 9Z#f+"D(MCR,Gj gtNVsV3RafΐV)D}ܒWIR@7|%r݊0U7-C^e\5ͷ )֟`Ϩ56@۴Jrqf&К$~C5KVLfZ0}ұ})h*LVI+ T}TEqt xYFnG܈L`ckDLt ٬ t sĚ1w*k-ddsDQ1#IW?hz1ytrKiaA*c0+ᎈ<'Ms[h{#KJLkR!u}0):zq9%Q6.2T_£c6z(&_L[WCry!J!pGBjh(;,I`l6-R{D7@W@Jd͖8lo3gA4g SMH!5y}Ae`,D2 ^Z\@̫T 8Ea ǔcě"M xmz/hS'Zz𭈙犜si4Z6-P#l0uy %N%Ӗɇc*] G4{})~gYnCX464Z+ ΢KB82{'L}n=$3L#d&fFm)POɝ;2":-D!3yG$xN ]؀pNǿѣ"7扥uԌp'-Ls5c/rtD@'=PrxcIpsYb8i+rwgۮ wK%~} rOd7xN~l|pq sn\G\j1rq5ckɝ=`[19M[J фkZU<}Phg3[X%OKIxQ03/=1 44btѣd[G( tND@D~[®&A nI E1oP(48BD LX+Dϡ.%NGYb]ĘUen8zG`lI>`,U8I9 Zp 9N q6.Ls$߄t3 \{ `0ATt!:4@m$Vŭ|m[a:EsF2>SB⓲&ޥ16bDS׎[5Zyw-3->c*pA`K? }m[HWvdk'2mwGmXu;=әcCq?6 /Dfx! !AqW q %:B R;tXud֕so~C$DUwS'5r(7^C,", 90Fܩ)r W `$X="e_2CTvy:BM %^XFdunqȹt{6:ٽ i 1)|е&sԜbl]bG>d-t23TO>,X&YXfh UaIaUK?HeCLf&HJ]gO)䝬{m園HtP)AUt@S:T'F*^e)gcfcaƓ0[HSDle=`c B:`Chٸ4uN*K&U<SE߀({җ9e9,<<"DHV/*q !{'hR_|H"9/ieǐbh5y*qhojӜK4gvY;HkVc(.\Shb$1iA\lQ󼃙C!7Oݡ9r*јk=)+f¸ά%& Ļl@bp뺝LBpGNsۙ N1ijՙԴtT0 4CiuO+; A\̒.'DUP"舟FҜNN|V:?Wc ap(thy_vď}EɎt:zG^Q~c7 "CI2&gyT*rԓ&krʩË eIh1H"9oy4%ÂϜ:vĞukvMX ՘dy5ʇ†T3W9[سfSJ,gA]<;q&Q:](hWjNΐ.%JANڣ;E Xír[e'J MY,M(M47SY$AHJdqon^^otyEs^%I1Вdz^;HvFN7AMm;H({8껞4Nf3:Z:K`hyYҹKUO_T.]a,RzgE ƜgR?WQ+$*Q؃(6A 67ƘG.OB5QYA rVBs@[<39YR\rk*1ĔRG7`á{]}{ig][9XgπW`ٸ8{'$G-Y읹5:*:J`u./EvWID %(cLFro *([BE/d qY_ ix&(Y^FJ61.Ȳnşp uc5(lVB7)%.ϡ.nug[b`[0َPB.J 71%[Gr* Gݭ aw}@3 HCzG}ad+>Y $֤S-$# #hװ>Ol,W ^Rm藄같)K+5ۦ3E@aj,ʶKS}CeBIqɭgߒhW潎MIN?8;KRǑ@!t⵻bV#%潊[: A^THDr .: 32]iseyV fƝUِNڦ[/8[\Ts2t ,FGrOXk!lw= skuL?,[IF$%|fS|9s&HWIɩf Fmn~4s47A,奕_h^(?rw/uRP']&ܫ`bK$D \#MP{e.k[v X'Xb &+wȽd jlvHkRtl~74uޣH5:,"ҋOJ"aɽZMI> ܷ, jj1X0cS#?ٝ;lZfã&,K4ZS"pgI=&Tb.{+un|Wc@HfԑO߽CUCT<:JUDf-:`gJ~itF[|ٲ vw=i@kS;5JH |_K &mQb{7ZSs4XDvt![Gk;r:e=|/t#.`d r9븝y$6ުIfz)SGWI*n"EdW:rcfj2\uf6S)x6"Rt(yQ7wL˅:Ч:^Z'6LRP/u{W^OnAĜ$*V c )Hδ3qŒXZ4ˣxPNԢ}k`Ah[1K­QB;T`%Rd߭?;zTǃRG 2QfN&Q'5R?бVy#>u(tI㓠dD 񽉎:2myC}< NhUa $l$kƶ"fJ"~iias OWDU )JL @5- z!e-4Rf 9z<(EZlg2OPounxPvq꺃 z;];´r8>;*:Sb9wmSC9̂ZBZ #3'ppɻ 1Yf]+Ng5 /~bmp(qk,C W&)3]|ab) f%(0Vk|̨Np;#(Ēwg\$ow)h\zKDFb;ӨU (Z z-j՗VF[&-$2]ǐBiq0=ٌ-!U~)=.8'>CpxM9]#pڊSUO3/>@m* nP"aZ%Vr̍|t3{B.H*e"rHLvag[s~_TxDI٠EK6@عRCK(Ud`rA%`d0?޶'Jq!s3gl/u.+hI<6jC9ȇ0VɓIRnHNڠ{ǖ b_ &Te&5V=\H! M&OҋMK5pzIٌŸ[.iYɮ{k8|ukǞ}"rn xֱVunh;4nsC%f}آdo[#QI[IjZAQW  ,Mv"Eb)ZX#QmQҷwk֓؝Zu8$ۈlo^ &l}$=7Mk$}$N!u~ɕRw6 Etqt@wp|z0o ʠQjKm!qTQA\:,%QYOX1.%-j!3 `Y~gټ,wKU큷I.%:b)z.9Pbv!,EkMб;u ^QheEfc3lCV\2CDmjoy294"Uc^QDb9 !42a7z_m=کla*@լdm M(!M ,qZԨN>~<+ҀRq'MJ,b$3Aj|W]SQ@Onq8"jxxj̎ v+DT${/ލkYoޟW6x L[+EE9CF3OA%tb]% ~0&;Mܝ$Tj<}`$9C.O̽tw-x`/&Df10m@v7(f,O3 :$U!bVpMט>Բ?jeLpvȧ6:p 8j9nbe}&K =^ <12*w2?8<\eł8UzP9+~Qb[n1D[ٔosNN>#ܪ342ҒH2DN'H$߃x (UWP͂0У3B(Q2s'B 0qQj4Be<')5)*E@Xʵ\pxLv&5 +G1)be*Hb[fܬ>IG7ȡtmx ")r[eiZBb)X\3{pw9`NÛY.3T1%xɡ$oJa<<y2+&5-l/$ \3pU:zӛA`" D'pͭS~tΜ$2K?͇S3]-ʌÙMІ= Ob5,jJSw L>>v>J t{ X'*R z^Oe%Ĺ}Y@LO/Kt?׊S88Q7Bq/l$:mP95[Ng%Y-揩P?*%&-柢vS[\jw2 踷QYʽPc`B, i5ZHyYv~ZUbrVJf;XJeO-fKC 3I+3̴𚁆u"icqM)kI!FB Kft PJ:W6V;4Ŵ3ѩw09aFPŤP,_<0l41F-||qgUY[!h)f' fJlG2TE9یO91f$)J% IG9iSiY\)G #Im鄲'j ;AK'zNI+[y[ Tu&V "Z SP|,%E *beMf^Mf8H 6IAvll.GV E)ɎW7p}BCA{)u,٩I9t ,C^ *r16:R6KS LjN: mfrX(~( XkVdwawAیF0&Eޮ۫+.YM6c[@H4YN`BC1v Aq($xY8۸r@ p*;h[`m'uUͱ:t+-FX` Dsl#^Q( Z2EI>1jaTR%<#9K7ч5P?V$c$ׯ:EW "&{rDOLmSXALJ #f{Rk LƩsͯ`BnxMeɂDHC!!ZN1oLe%4v\իf\|V3x?慷OO,iNz&4.dӊ8MR<(jxP3|qMgl{a~TyƻܢhĮPIց>̨qxhx r>n*ذxS-_7G 9̐n>TA y6ְZA5ȥT,l37XX  WLC^JF e6ɢ$&%rg(>Ma%T@i7 i%* $ +Ǝ!+ɥQYMZWD_äDn1L[V| Ƣ8O?5HxTʚ%8^m˶w3JM B"Vtӓ*DE1Lrg`B`ɝޫDkP?Z A=Lz>YCHCF"b\fȜc|}gGj I$[ub!ʍ0޾HW=X@GQĮL`4Th?AL#C}K0L= d+ꃙJv7w)O~&.tj0.s#|4G(!n=0VY A:t~HX4tLGIŁ:a~وO1>p(ː[QSo>Iή {2X:\)"J0F ض$H^LѓIߑWJoKٕ%th7ɦb" &:\$.[<1yDx;W!b>bP1 AXD~rSKk<̠)|rxČY$2u!r2}ّ-w|fڅSdM!dxfSeI 7ԼߚUpE^aPz\I<}I2iǒHuyEJns-9\_l"]\N8:8tyZ\ z$" 'AsiM5!n_ih 7hIT˴ `Tg6'"][xҼwd{Brk1 t)< 2`en b׺HStLD6OÚv8nęe ƽe־~|KY6d†>Bz,`.MC۴7x?d !C83ztG Ҧ/H@@ܟs5H-f*3<3w#c׿]MQBL ~Xq{5 UGIaAƲ3ψQDep(^S ǯ E~I.$?*#$<9z:xy ڿ*⻯N!] ⻿*LI6Woڋio%Ko[M*obxaoMw>ߪ?<߸Ñ֝췏Ϗ9Úo,dѵ՟_Z헷gjXoշLտrw;=]ZۇwP߾Ww^]]ohz >55/*} % usK~mс 0]ݷqG}f6ݵ޸ʮs_ ^%v}{|G`s\O۟hXokϞk6?f7B߼&!{o>3 mey[>T?'k%REkӏzàŭzQ,K|= 'y(jK7޳( [?ۦ%@vߦdzw%җï]p4v/淞'low?ͮٺxՙ_yBxMy6CW7OOΐ!Lw߼9SOٵ}UOϻr"% &ʷdXۯz/9in?p[izm(O 7? 7;uȟ]WÏb]gVqy] ֿ{~? Ͼw@y ki7غ_O6%~ڮo2glyh %>}y)pXoԈr}1bۡ#w Ca/x/?1~? +ܮ뵼n}{z9خ<յacIUN`~vs.A G}?f]jûO۫w_+վ,nsrGoǿvK<|ixw4O,6}˥Ļgh~s)ݧ>=r y+eŖKq bѻ_~ n|Am} elQ3L=݇^uxz%sOO7(i3}i[`CV3^ T/e8ػ5 \OqK`Y!Twns]W﹕=dz~͢Ŀ$c{FY^[對?u3h׽C,ƻ.Ϲ!?=L|o՟?_TX OMkz'}4.=QLo@iNm#kJ)tjO/|C?a W^ZOR;IL_<4Os1W*ו>6EL3LfOt^ Z}-;/!~g/~MU`odz HOzw߳F_m)xc9ˈOd/mԹ8Սi*UUUgm?M%ODi }ӿ|>֏W}8ZqHv&nK[Du8msm|}Ě_'ѭ~wl[Uj~̻?4y#_zkǿ?>ͫ͗s߉GTPukc>gbOW/\2r}vlPB9p y:OOW^'foGtuY+ǚ5$Aֺsg]7hC&~PEJߐ[wa_S;p_D.ǟ $>131v91 l4++?_ ?pok;՚D}=|a|`/7CEfׇ\<\W>=UƻSˋœ\iHl(5`D3ᷪЋ '[ku$UuOE ˫0PUskj_scMmnOMn3ڽ]Gw-.X>9Ux-8ݔn`zbw%'6s_$1x>Xpֵ/YS?s7shwCy:\K#14:`Znާ0ΫK$t]t9bwu{t]mT8χky>s7z/&_ESdI)R>Ar ߼}=.\Ufk=ƙ?g$8YZ:8~Qꁟ9,$}rXTiQbs틞O mWy[@OD~.Ɏ_hԤ} _|Ͽſ۷ b1`u> stream xYoFp^nUX,Cs@p8 Fm6T\_3KrpE|f<x(jXiS~~{~Ey8::+l>VC8^2vm]nφeѴW`wLId5\-ƠȏݱBܝO q.8YKaXCOf03u! {:tؔ߾0N抔هlR}t6r/N&q]UIG-+Fc8$Jɟ_퓗gyjw2643sYDV^J_ӗe/0oLe"b]۴++op(s:W]=jܺ8&Tovd% c411쎵׃߭r;gNt?mjr*XXRlEnKyį VnfXM)[ZX$o̗͕9X -sZ|jݵcvt]1hEnʎlɨ603>10{:6zax!bp+ ,+ )ř{T} Af<q?+k[CiXVl^'I4C`BV^G5dCF@v\6:0`׶CTt dc0l\?9EI~UAi4/vGe9V+M˖Ʈ`nl1"[&̄ſKbĀՃ_mȎ^8`ݕ3F0$tW=bu&2W)";d~јp~ ,ٱ #$S|>~o^l/_?+fM_ˎ~YGGpu޻fo+<=*endstream endobj 315 0 obj << /Filter /FlateDecode /Length 53434 >> stream x}K5RݼEv;k8䁵 X7kkϖ":red|D_?yǏH~?_;}l>gm|ݥ}-?OK>nM~?\_W+#]o۟?xF4hK) v ۿmˏ? 9rsꟹ+ߟ95>嫯XO/IO޾+L5 x-ّR5r4twNs7:I[ <$\]!<}G~զU is֣X(=w{Jn_=N~{8$J@}8s#a}>H[ "$#<ǁ1JlJ6|{}'\ZK1WUfN&Vb{~lE< zc,)_cuQ{6'gQ+ #HA>Si_sm9<ŸLݺo qv?njFT0sjrmFO_)}.׼ ɗ5j:R2 4zhNA*byilm%_moz:zS=.A0Wgit!%B•tsX^_X&L{_ޑq}5oW܃ j}6A~A p -~6w$פy}rL>W/x{5{/:۬kk' Sm <i4.: 9 fk[_+ߍ=8w, ^;ڰćǟFh!NFl}K'5emp}s۳]tgp &X\,4@ 4$]'>D[ i%\K!9ٖEcXtZԝ\Ov:} ΅?7OĽ~hTkrfd}r#v3o^4vz-sa6hTƚRܭWځO. :s8֛}}rZ46-"񥊴O:o(;=Y^;eͣh*Al)Ma_XkoX*{ C9֮|hiUR-&f;Xz`K&EO,$Wumqwy`wGSf<-kGEhRRApans1nඎ?^[Ew;79m:Y!~>FXfY_MeWi!-BBZcvn[pz5 b$vhx4@ qᤡC]&E:Qp_ȁ9p9݌)Xk֜ D<;Yx~ab jo 7o f%Bhxn̊i Eo4eغ^9kﭞ689ޢ PW?zi*s\.^]̵kXpV5/wk &;H[b־7SafA'wֹtIk*@h(8LdkmS'SXtFw,DCiX)A_ mz70PMCZ 8*^wBpTޜi6UZ?L e7N.lw73Zp!o>V?3Iǟ]YoPq;;6ǼR$ݹ*!9mk̚z=%4@ dS@pp}F BQ8;o}rMg:vc3 ؅c{H \d;^~AZ!Z 9d!)!}rvnP7ʖoڏ2-w:"۶[| 43)n,$sk(uwAӇtpQQp ʻ\u2'肓ƍd^[$8شN_tci !!aFfw:I#*MkiRy 4AwpSpq5Sz@.: 9 ~]`; Vqٵ6F wWy jZiƉ^bsh!-BBJ:9=)4Zj ۜU}}7w vw,C̓Z6'am?å_x PQAh:L}r>nMWAb1Qy8.9\&DwC44p WcHwl|7g5}Jf;nnmlπMKHTT:)v?c$GI@@N ?& ]tbFf4.H;}Bb؆@pmΛ{|>: R%\EG8F@ݰԽO C47'v%2p6A}s"Nµ Rq`kYؾC~bsD [Әo@4.KHG?ke\|1+8‹Eg,;bǠC|8}Iks:t#wqI+tpZQcm)]k]_;G|gh\[uKTzJ:BЗ_8gtүKVĝI<>9~.Oݧ:j6:=$ܒ !/x6~vNʥ#N~AڲnxmZ8 O ]|}lBut(88Au$dDhQ=%c}w76!Ql˰DNw Ơ|nw@Hp1ءm1"ݾMxnƄ 4A]qe 6<8V@cí[ pB^4"#欟ۚ}#10?12U }K6wԣh!-Bv8b3+j ;87^˺Z9U̶p!Q̵VM.mrP8"$\K!C+-\µq(@vrN0x>Cp+<~}ݨd _ v %Bo!;6qW!$\EGx BaĽcJ#53DbXWH$}B9 +#C4[µt8tWq}rpim.pUiRA⒑N!qt{u8=9r<@ SXRp}ٜ$x2$td3m$8zHEs QQ`d2D4~qjEw> y 5T Kk3MF(>H[ "$\K!<ǡ$zڕ[:8r44ꧧu74!al4@ 0@ Tf>H:IZk)8𻕌+ )vf:,;A6SKe 0CޡJb,՗ TB$P-@7c5⎷+H).zn*>Տ%$:ംD2$y7܈v .! `fcn'Dz[p W44jޅDAwj# /'rfhCeI܂vw؜{vh,p6Ir75i^o:>c`k#<}fxm&]9"I4]y3!E 8.ϛs)p. 9]A_r-OS2lgUvdq)X$bp,#nhGт:4 tT޲6fb3u- X$H㶇3rHtF9@Ys .{rQU%T>׍ZNAnB\$vB8 vk-@zugsvBXw4!Z:ct0uy=zsz~϶G3EPCK `v֠vр:D((9{%QKE4͒ |cqU7p~qlOG p_Wa0rNv WəqY)D,fhn`a胴.Z 9 %c:.-ls2m&:2u+mGxCӗ#ZA٢үK N$E'ruRV-w͝2nG`_wЯ~Tbg&$茉EWU颇9CbC&FX1rAit!%Bµvs:t[` :Q69M8tRo%=,AEu .J 1 xWk;U^8qWloT8%҅>ȡ+\V 0 \Ax A96jS.)߬mg΁T<ަ5٢? cd2KP(/Ƅ`__lM}[o9IwX!:N4e.|bR$r sBETY \>H>!Z 9VcgG<8'sE{NY‚)1,V%F}F i#i7>H>Z8R'G+#urN]$[gLWVHe;9gsθx9'p#ua|1 }s,A6ǫuX[dl~Z_xH`NH6!m^SHK+C2W{F mOu/=jin3̗̗Ӄ6|#ddэ.@B^:]Eo )!``͡%.à]aI;67|΀_њ6 w9Bf5`u_a3bB9dZ,]I>Yj^YmW#C@9Sy.Vٜ3!,_) EodJn'/?8z3I_4tY4a l;g0Q o w'_ob@E 9r. .J 9dH >8ڊ}#q$;]N @${x}lFm'\6:%BS}VjfQݛ98o qnw2|V$>M;$vh du_g=\ewWP͟CX>D ۜHt8 &#&_)p+K89tk*̜]|}lBut(TQ- ls,w:`a0nFl3)I^S,c1pWH>>9|g\GRHZv;W1x=>3gUi쎩 ~lؓKrE88HEM={A{g?%.Z 9 leCpnR rQߨ*ghQp څi΁bCZ> {PQ7=%j (8xQބ4Lҝ.`*Tt8g`#G\-!9&ތPW +lvk1+h D dsph} $p ZADseWov{?ꦡ:HAXh\V~Gp}>6s6蕹pͭEHH@xCV" +[G)TJۢv- ^!Pʲ3V upQQDQE-lMm߼hzr*hΣqpGX||Bilϡ?GQ%>99ROcȴ/I){KD{ 8?qp >GġK攷yp2r*usde%11yJ4\!.FfNH ?C[~jVy}|`[UphYuףqR,^c8G~3;-|;\A<Al?;&́*mGZ003 (B0.<1mt_FLVNfo B#(h7KkjRFBmC!GNrrFA$]F )#|H&{ Ww=n-\µs bW ;< y0̓N9Ji BB:c;L<61-ȿR,)YI, Μ_tkmPzUb.d$\C?/ W+2* +_<C\@IƎXk hT1ڟCPX|fcd'+ NNgc F]]:t (xl`mh/Z q7*TO :m8׍Q?qA-KBxC7Ψ<˪U>lUWeĵpGΠ-QqvbpqUF>vbh!Rqȷ N:`OT~47$NIX4)Vt|)a7B8o3pב?F!7K^MOyzF#ʙ9 . EDv ;@aIF_[p1 L93+d9B}F821D3^MW$G'%K?紸VO,'qrKeKIzA~ z֘>6GI}!cw@Up cKv<Ok8^On=/ gVS/{sU-;V?a%tJ}Βve< -ƒ4Ȝӱ QuihE>9 SU{:2*ğ +xö$}2?wvcv/?G9F{8s6Og 2PA;.ILvlgp} -BBZ;9e ot88e)"~% 2$ל Na @@U$%r$ c6t,[m?S#u1YZ~Y9]b"y#Xnl` Zvч iqcʡ'FfvoC:CWYd7[blI7ٽ 1wtH;$!l"td Eu\GxBӥ FEDH{}=l9!{ ~gt Xл c ZQpΟN>9$ .[AÛ+h`9O[zplyUCF>DW%\EGx_YϘ68L5laau-ھF-1d tvs3o#5kBN1N):':EOO\#_nޥR! !K>&[8g}~}l-BBZckΆ8a#[=1UζMiKf<]Xv@,Cn`%XKo#8À@PCKBx#E񻫎gә D@W!p\JB=lcNr7ޅJ+I(ނlRT92[8\MÝ Mb#8]pnsowl.u!Z.up Сc,ӿTV?B*薠a8Y<rppH{*]Ao?{pX'gt,>q3eK5RUeF(!lڽ7/F5oA>4B[K"LĕnݦswvhXwrtH[[blA֬y@p78nbLqyLh!Rq]L\[_>97o.O&nV]&OeD ;obh!-Bµt8 ͮ|?wU)ã؁`9"$\o!(CNS/$:BYu7粹d#t\[>HÝBZ+) 5Aysp;pR >$bd*sJ@yMp {omk!RqgMp7 N4Ic}8vA% ]ɬkύ`c胴|z)Z;clŷz t6DD2_pCbAgzUm`}%3]~}l%B•c n)dW ;)xq*H&e-&>ߐP@)ts`<Ǵ@K"cfbMxN94DhkGAL8'>A݃cq=݊$~jEfe4ۛ^)=LGmzap=vp';F{<ۡBHEoCnd]=onl&@*D6pEbҶĘ!Y+Vȭptp.!}(Ϋ_ f64yae Ip \jbF `yw@~"W@[A%l| NŢXQ[EXv}[G7#g.SdA-EHH@xk0%(Pt4I;b ;hqk-2t:(.-\"sr]d[}mNF !H: ]:з Ks/V%\GGxBLD NQ.-.q RZfW;Z;8[9'KP#zJ L>rVl-Bµt8t]+osy*Ѱ³)4n`xK6.48cosEHH@xCbVg+M]3nUd)U+ezHYu!`46R"$\I!9;$j%N=N No"=8suQ(,=mŸi NV bD=Hrs$նvsm CHGxB0| O3,UWV9r/d "I}^: _uBit!%B•tsfsrpBڔŤ>nY%andK1##tcЬJf) ΍Rd=k2 oi9ܤoV{|+Ϯ7/L%O,Q//QMFYCJ@QM&8# E P\E^,ʾJ/ [V3%֣H yJ~} 8EZ65V@%X(JDM(4z[qə^e%VrBJ=LTEL#-z f rnZSu1Kxz[8%q#|# Ơ %*n -BBZcSӥ<1 *7tE[er 0p+gs6%5i  %? &ʨ1  /rT 6% r?hbvz# K{{UM VJ /Y*99*:d?e0oHe 8}y(d tG_Gΐ * uX%\_:ZIi3Z{ ڶ9+KHS ۈHaH@ X^~A;ei1'1lX+ßl7CfYjv*-˷@p}sZ;:v􏿅jT_->9EYC :#k!VkK"5Eg[XҸ !!9H@NӔuNg~5~J Ɓr;a[>o-Bµt8tY)i M?L;yp힇)JTes#0r*6>H*.[ IBxCadJ.TsYҵ7eMF:%ӗSQ9f#T8j>H iqp֯7v9F:AEv] \{#fh5?7G@J-(xs瞖.qpmgW)3@DDWzHJ+A6ƍ`e .@ʩ :]Eo,{R3pΤgM 3 rK Y'$,tgsh ̌iYKBxCLy0iob>şqT!7g|qLN52lW8.HmQJ+!qHKNIR ?^P9jP@ nFXk up{msS%?¼8K̯|AaH0De̕4gMj nrŘ詫K;KW5nMI 7$莽_86@AkwQuJ(sZ ~\3f;1E,e߄%Xh#8tg98#iZkqXR TѰ=#sV5. [6L_7WM ئw+i̞m `}Jӓ~1H/DG>yyRf2,$1zv#!:-9]B*st[h9V5 *Hf00yhx49򎰞 xB~:kiYssL]lpQ@Ze ~\[z(3ɭR/YlC6Lye3ӝt^/e!!͡g\ ؓG_[ -U~1c>8~V 6-\H;bDwAÛ;36ǜv{D $\gH>B l0?FKK!VtT~НOJFp90^b݇בQ%BK!<ǡNtkb%NfγR/\=K‚Sp2ybP19iBHHEGxB+7d&.9yHEמH"6&H0h$ *d*Ų 건M'n$b9{n ?7@=i0p7>iKpA&3cp4x={- w%z^YI!#\%<ixKp-fI1ߊ>8gߋ4&5,ѯ<`B6ӗ:g~a"xA-$BK!Ŷ''c{VTs*QucƖ.=.Bezm%\KGxIz`:#E^ lHڂTёNDU%QpltpVA[g?i$em>Sg-1{P}iU#g1 Nc.H w^z2n7bCGiۊ+>$,<DiZ}~}[v8tL햴-[[M)ZF2Ń :yX,FH}~}l-Bv80anM͍Z-bz'6#oHNLz&Qdp@4 sT,gUEl(;N.$&inˈ[dGO3p[qhA+L~9tAc(M#`,OI|yJQj@w᲻,/[ p%'?F+ XP:D9Dk|JD+ݾB" ta@XsGq3!-Bµsg׭&19^.H%~tHhNcklx:R^wc`f2pZeg,A[\vn>?B[o"6Yl'vf!8$A_^9y>ӆ}~}l-BBZ:sZڎYs:cێAVm$qJ0Fp3lm}x$BK!0}ա$BK!(Jjf>Qujndd),EԣeC p>#v .ג,OQRr|Ͽ\/>5\S-ji m//R )dʧTp)ӷvƇTpԐ3~Km!eu?~㖺>i^?u6ojÃ̧%\Q폩_c5BK*?(;4 Z/&ո3s݂Ӄ2\0NV.sI!{!C!r{>x5tB ]Hƻw@E̓?OJCoߪ;ߚ˴[?㐟Oo_.G[e>[_^wʵkCXmA^3tR!5ⵢ@@/L?_3ǚaӚ=m;{{~1k{IYLΣф SB#g,I 9[خ0']2ki"~%G>|j!ՒP}U|Xs7M&f0)]U8Vg|,roJvpn*hFz4vgbݓD8Ӎ.p.~|Kk-9~GܺGe x ԴxKu \0(6}Y\].P$!rzv侻[VFzL/"pE΍.X&E'c ""pfxwl3 #dd(aBȫ%5ުZ)v?Zrdlb~*`oVP浒Ӈs aVLxY- ù, NP+aJkEUvukd֪i~#xZFsekQ^ʩEZZn9/xX|7Bq=M4Z,m ;)g#;:S/WĴ 3Ҋ* !#v:HaK#Yh{=[A}wO-8JQ+msSicF03 `*,$~Vi5 MO!7J=&ߍ5&&7CB/$& jʮ.2e]թ |J;Y8_Z9mjJHgVN#JܰVwn. ) LQ94KV ;KqعѰj kM~piae̛7j6G2܈ye\!Ğ[S괃VW"1p\*`rmܼ-nT(~.E?rfˉ߿Sڀ8I;vDٻ,i%WgB5-UN]>&ō$ PV[}?Oowknnb gl˪߿ 3 hz(C(d`wۚ>>*x?!0Oٵ;޳-ikό"Vd4h pH7!7qN%k*R!\H@fX>1}ZE' jtٖg}i+bHoic45+e3ՎH;{|!/У`0MV]`bc 9w<̧+yzn('27$IOt.8gn {Lof_X)RsT,ܷOfZ)$TIxጙlDpf*aӖxXk Vl8S-UX#kSuԘUgJʡ޺ZVlC0ɑ yx*#v5XE@kCde4 !q["Raj ^(ջ4aL,X-٧Bpe紅r?,i#¥r:<͙&/qx$48-,<6JN FCD 3z=2kU9v8*bĩBdȱze0,AÒx* ?1[96gjJQܜ6̥ñ#FgWJ3YC2Ll[Ƨs39\[ԏ,ۂcv:'דsӢb)g_hI c cmPm[mz9,I4-r*Ό.AOWNX.8Dv} G Nc^剂њ fכiSp C*B']@>ۭV󕠉3\bPuLo7K[}2a;aB.Zfzor.h']a^طQ:K9|Jh1ø{+Seޑ\KWFR5* V gS\Qd2#a<_Z֣Sͼ7o?N`3{4vk4 Scz]0^smϣ3nNiwat7+9< [һ^4l#"O} o^i{D~G#YHV6f~~|uqn^t rhѷxZ3;))$M|qpeçiVq8{ajfN0,ƭ#b>L1}y4ҏ=Hޖ-otff8Þį|lldf0btA\n ^ܖ75l|93 da}ʠs$mӵ"̞Jk_!3[nK:86Ԥh!xh!`h,ݜ1oߙ#5#j3&n鴴S]wv֐zIQ'n;۳QTVA$MrJpv#`7Sc3ʠOeVL֮b ȸ7c3NX1X=e^󰳀_==d;L^)ק>ff&gs˷`sv Fk&8SfWڋ= h؞!]rQSnHFԲ[8_YF AY#O>Dz.^cdXXdC>)OKIpd̫{1tX ׬Pws,_p-n`;)&5bn.2#|)NB6Zjwҁ>stҳtLw`(G/g+i\lr셉pP;BAj`gL+V螽P)3c㝳V)"[O3\x;U-N _^3+ifobKL&W>iSP4KSn#ㅙ9+f .o'p7з7Q~ˏ}ff9DQ;߆[X!b5 a-P84i=0֏n䶇(k|'3^bWr;ۄk&~QFex]lYT=u D"=}m"ho!^+F6tCkY~?şs͕/#0. }uowagR 2i`t}3t,ͧ7K/AUmLKݍC{R< ZRrL*GŘo=< _gu$ݛeVa[U˭lxϟN?'lubRyr.$;n·8'(Mʧg߷ު15 jց{k {P'.Tlw4`@v%3[So86{H `Qcwa/-| cX8b^oEeuYh=M+Mr>ꖛR7,#j& ƣv4x"K?ra+CK2SV@S}>r)#?;؈ 96Y2v~ ߈W9ٌ͋XJ&l ag-?D.eK8cl6nz3vDgfGsDۖQЉomQߜ@D=f!r٢0Ys̢òp޺QDF9RpK H OrL Uv>m]G+|KEᮢQ .llY0[663]_*zDcO?0F'ymWlk3H"kf˴ho9/h+[Atm7/3R v,Iu~G|퇚 e{$uF{imV<H]&J|F$Dn6Oub-Pm YQ&>`n+{Pv\5ʘ Ϲ]W8tD+FaOg $oѪ)6 j%huӊdHPrƸjT-q ς?j10s/8!z෠m3]btT!*,vft9lH(Ξٜͺnh96|r܏2ёo]Lp8%d }sZRS' f4%t^4ws\9:OCq8m-Qo`?1k-t CW2Ff,82>;e2;̎rGo|v a0GgXy w2mp9pӓYl(کȼK^Hn1p/2W>b(D-sh LU`6L4׭X*[giMVD6͵yyT*.leIz_9Ųƹ[`鑻_9uk ;؜›MHA A%"h#1 rzu*iZ/,1su=JCS&T;4q@BaPʂ-ƬP0;"*gf^dZ.kvQ(-y{ltf+a0kq}[EO>ieؒziseF԰%60=ЇJ,t [EݎrW.h,L!Lvg^/c8D&NIf[tWqܼ@)ū)aӒ;M}pۓԣZCHdX{jt~/zʹ0d'yțD@9KY&\Dlr7\a;61QƢ]i 3( |,#_bR>s-\6XyIYjO+^h)@; pN.~"5Beo<[߁!kv;-ۦ逢sbF,W9kb ZSmF6f]XJa!Ic9jS] _|vw5"SآJŁ5%Gss2;{ :t2$pUmMo+w.Y)=}嗰EyR'$/-,}bx^D#<'#=[ɧG pDMzVmY޽Yb1xMɎ>f $dN,Jb.RFb$5#'{%FvL4 B6ÙV]\LT}[Q/D~ErO3 z |=},o*M-Za(2~nj:>18kpiY;FZRtIP%Lyx㱰Ê#wu5Qu8[(2FXvSbK|o8$-# ;PT5(xDڻQ/f $œkvKv9\n?=y5ճWP4R!slF0ϖh6֕ܦ_*jQ`1 %8liG:p E11FcNp@OSW-U&G MY~ 57P\83hQ~Ǹ9YKsS8&)\Ki!~Svo:K"3A1&KJڣ9ؙ;Og HbwP>U G1qhw/wrbKD8h WbyDt.1N°34L RaXxrS b08D@S}%֦7 M]e?-8hgf]b}4k_ 1/Af9 @0"iU(dڴ؋5u7v7=lkHЁ0T (e27B_#XF0&,;T h <h#70=e&dѩ^)iA%pEVEY;,aܭm /Eu hEA5\o 1[&hn㣲VuMٔLn骍]WIUFpS*w'qƹd"ˎ"^gYiG4H=2* (arokh%UbKգS w@- 6x R٩얰Rb5:"Sb4TS^͠O 2CmH-m^&!kmчI)rs)>4Z2Sxrj 8J C gEs*Bx:^ӶTR`\RX/Uu 癔.ѭڼO/ XqYIVv9=y?EҁTB%x@ih N$WEHG -U%=`KdB^9i;*q8 18=eN-FkYM|)>a:ӫ:'SK7Q-mudCIFKI&cVP#{[aqSsQ 3Oѡ~4C*jyFm $^ y7̮ܖ:*ՕB0Ox$4\z#s|)=מ)oϢSZJt3*?F+N:A [C`)15w(*B"dcM@IN|ȥAL4dQC9Đ6ESRap,C7ɁOa\+(?~D1#k7T$VŖ$䁈|"Y @ 8 b͆ Cj9*a5m1NS,6P2,(2 y%kdɂHvwTdO*òa?9lWl"ؔ8UҞb^Xp$ۯ:XN?:XE7q\,ekuETWd։vv "|Y8^r +h`mLQfi \q6RxBw@fuoݞklzηRTViɧy]'}7\#v XV: 1Sg?t&}!y>eY0bd"D ~biK:Э9Bv]2Xmi^c!|ͣQC#]M|yLAΒӉTG(hFiY-աd+DuJBQ c)12' 7=-CE2dqM 1#א8"VՂcF aqvS)C<@S[D]-"vLW%[\I`b10d#lɄ raXNB,d3H!1;i|nt ԚUF%)oeU6y=Ʋ3א&ͽH_$Vм{Jw99O}6ǭ1I-Dj:Ol\PN\R8~lX,G=;lgf79V>p]Xg{햀3`D(3@}zdj9Kj +v6vz$e۽9GV$ي8R]`u#TW#4v)j0Ew^\rR=_cӷD*T1_; |Kg;J# 7ӹU68J6y8<:& >x@L ]V tqy 0YˆP9:&| eѬzlKTl$اQ@OWj@3rvͬPŻؓh`Lro8]z-JcY7O&V>Kt?S&lEu.1zSp[ud! P@e#,;d 9 4 Z .')Rç}`㊃jHÁ2k;"j!{OWM7z9A1"eZUl:9pHoxZtMKRJ`x-QG?/\*Oߪ8ح9* 5vV X1If<]#5yXcE(`0 8)X3)UDr@1lM;O 'زcѼ5f>eѴ-a 8\12! N1%-d5)R9Z%pR#ȑֶVƔHnIa15Zm)5x9FBcuXDs@|pf1e*+"T!=M+x [g>WKۀ`l4$jwG5X=?~d88[<2H. WP7dM3V#4T`Z0:&6mS|;1db Q;XCX8)ST3xy0{VӦ~")GSl Ny/w)i#ᅂ@\eًƸ21[^"L%O?mKZ LBu+ź4r ?0x-oK?v~To2.酊b^ĿFKW|X뷑r8`3sHn>Zmղ4ۺ@izs%?~<A|> ;{KSꉳuH;esf+ac5ҏ&)F&3񱂔ְ㍬sx<Dz9hr$^SK 8}+HU? ݝ<4X8R7O֘+w%ԐVG HnUD em%Qu\(P|D{ }[M"7h2-R˱]u}=rDZs) QlB3:ozj`Kv5YBШJSt1yIGzN7vV\G5Z5{ބA#'-E՚p‚5BWF0`\%*B]E\90c jhxd@bjvţ8UHh +?"K@fdIZ2`/'ڼ@63;e 2+Z 9|Te[fr]>ϱ@oْ,짖) /] Sfy&;"Ȳ>!D6)dlˡהc l%CS!&^?J`+gCK>+kby,ٕ|X0GҔGs=' .M媆 !<by9UBthՒ@k[|Tvlp]5>~Į%P.Ɵh(}xM֙>>Xl:+跨S#ZsDm]`;R_g^U+_xP+lMw/}P&[ yFPK.&Zd3rL<#k:>k옫XG7(bEʰ\$ U 2?lXsZ 泌ٰ֠GQ$p +ŏ堃4!t7 l"(PәZ}[KRe-eK/3a)Sx ަ8DC Q`W\;O`MBD Mdh:G;rh*|x&y`\ZN:'n >)Z櫉QeH#Fsf*z֐ήBjt Ș&1΂ Yy td^вG/@&nu)/C [u)VZGcŶ_6*[RBsM:@>([0G[^9nQ>?ţ2Ưfm1qpZ`z\ӟAE{9&FӉNfoiX:@>hB!H>) iXz:5jCLcHJ1s48&է6\CEC4C$SLGdIvىf*9to"T+;2t2CBd잧'xcƨG,HmD:-ig#-"R'A,ԝlh}n1PA7KdFآ\q1虏c|#WۛGI1UkZvPf+<~L8GhG0 K 1'i `\".rޡ<242r\$pf4 u=mt h9LDN}>ڷKL\~M^fEV6uMFVw`w:hMg"jwhFi>][bV+ XʮX'7|@@[l>C);rq2:*ʙS-j"IxmV5Yc"-2)#t`4NRX/ׄ!L`2Wnj?Ȟ2}&4ݶd-i[g=! y$|#`}sA4G(n_cN)NiV]UL^ .}\!J  vvC)S Q;4*|FC4nS&AAhbZ|fuS:tH3*%I3)9fOrnGFUgAZa`nF $*b\ՀnQ@) X(XXo6׃%?Ѧᦗy{>&BSM] Yɺ6DǪ#sjQDы2\{znPOd^:PrцZĄPv8h3=j=`iۃ0bw!MuŚ,M%Fmy"$}a_sGp.x\UƘMt X0-p;!Ma`hL#` iazhlnVNlLB]1rn0o9G1l!Aq zƉOw)ZrgR&6-ge@--Q .DWa k a[}XT܎]r WK49m&s[eO-SVvTMvIj0 碉ҏl8;-mMpk4Նb΁US7MaN#/hNȾ0Fk"7&-PDCi5dž1az>Um4-)^@FMzv?Q,u ]]A'0GSj3N֤"*#]3Mo#Z\!ea4%N޻SWH)yJ[i׍MhH]N?_#(6-RbYC'iLEG]TJ>ȺVOMh,, jrguãhY~i!-!×.Z9j8m3H!TkߴCe-GƭeR&0#$7T9ώͣ5<3Ė16=$zzNKAE DZɰ2v8)8( !GMt4ҬtBػԤܡRFn[h4B`W3"AF2Ko&.^ΫnnOk-mh<lx:ŅZPepH4рs̶e\̢wc/A9-WImt3-UK) oB_nYܸQTg+bYX_8A͛Ɉn Sc+=ٿIҼ(`Abz)ذ"ZWIՖAW`sEhh2b(9kM殟 x% v`$\QӢ hӒu({Yؑ03O y"=Zw%48A7l7Ua5Zb$|Q|lQȆ :5Mjcwƴʊ9I D d3"Vw^qK)6mE7K}ˑBXa -WOh{NzA*,, P cI>Ml̀ђk UP`8XkxhE~&Y=lc]1Y,3L?%4dajTVToPa5`XS"*-t"heu@*c]Z$ײPAs)V zbi٦`4a,t~=qt7p1\R 3 E $SJPT-:&v+JTزY3E` Q_ՒT9P D\bf= KːW [N b0]gԜ5m*|% l՚~ćB5[刻4%cqXCTU%V@T}T1RJ$ԀdXK=7NR~c-d67(MA_odHS评0chqn1G{F<[wTƺNWu1qJOֶFJ)5 8U֢B`??Rts:Uc Z T GǮmP,:ͿX6LCB -U+e^PvzYpl#r{,xl%flYGjI3a;UͥN+?h\(?u(I}Ȯp\2~o$c8Y!(|"𼋊CƅA rn;";^WZK3f6Na<s%KRNm!,y܄KQɞ(udYQMd')Rnu!OK FMhA`5ޞT}ꨩED`W_2x#{ :c5el`i0K%Jdc14 wɨJVYszuʫ*m.YpQ_iRS !^C0i8)A];d NR7"/!-ҬV%H֤jQmv. # jFJ-)֜l U8bd@{hLZb>&Ŵ4Q!1Dt 1$ъR>Ir'&$ceKib]Mb ,7c$o"DLJ7=u2I_wʧv0 [39wg$#hl[ʡuGQ 3"`S-L- i[V'ݏC-!rUH!*<>=*1nEϲ\Hil!hrW)bKF8*{'L}N=$3B#T&fF˔l)POٝ;*"&-Ḍ:'؀lF[ǫHub]4c&⼅eN2}EYcA%G6BI[Q;;vM[nD.?),x6iGgg_2!aٍF}ұ5.ܐH03sLsSC4~jO[ lt6e:x7ryz<ݥ]Jƃyُ/$F<) fuK%n4Dz| UՄ#6AM?i0 %i DXR\!GuhQ4HHDt*<KJ-Ƭp#kS?eL@fG)OӬ!\Hkm}@\.JQc*pB`K?x~ӕ9fz ƶYh!/rD]fR׏c)wwK+%nb(CHP\5?j!ξT̵B8|!g\#VuoR?fd"j1d^uLpyxČMܩP{ĈHWF ,Lٗ~<0.ENR4V)`uIHVGK׬Wl jbﲲ!C4"fU=%45mtZbl]bG=dMt2g: ¡|XL;ֳ f=Z!L!ݫ%$Žv~\FJ(u9S;YzkJ2"щjB1sjVU8"D;?6vLxV A0&<э;$`϶: "q۵AC@)m4VƥAfiǔjb⁈{YeMs:Bzr'bF!7%I~uL6#q"вqię%N.[ƦT<C%߀cP;܋A_z9P͡a9!rk;o#ٽx#W0س8AC1})+; ]c'1~S{\撄\d?;Tì*nAF+pm5gE h !7`*'<Cوy2(7O9j*јk=%+DLzzv!o*z,/PKdNkN ^ -'S֌;dzxT4lܭ*/:j \bсKӦI晣ϗ.*Ad OE ,SJ-$# c׈>Oj,W`^҃m藄ꈙ]i5ۦ+E!58˅roVuUlRr[j]<}ϟblޯ}SӏNƖH\c&%PxnXi(yw!kDA0^TC~Q61-@J]t߯}tɕV}kLMu,;9>/ZTgC9ꘚ^qԣfH،x=*U= 9`;idu]'öDRxF9Eɗ5|Τ<0>~:%9uPrG["Fu 负eB4N/ LEIk|N@MA_ S^'!.4mCE8HwYCq-ܲS$?:K=ݢjW,&#ƺMy餔9" M8RM࿎Mf~wLQ~<;|4eA&oԀcaŒxVw-j[ ./8, \5K(wK-ֲ彎즎G)CzLiL:*it0( 5Inq"t2r/K,ߝe7 f -%0`m{/!:qvxÝXK@ m* [ԍ wmKvd.CwzT'rmV ‘nw`F]LvEWc$^D{;<$yO9[8|6T]/KޤJU[?jyr(/ݸk w |Ԩ@_1m؂ iOw'7[Թ,ta-)5lSY6!W`g^{hfr$p-%6;tHh,uى 5}=@cG}9LR@v+hA}QpG7ÜmcیFg&S "z挍:NAK1I3PTu.٢yK lV4 g^ $Ҭ9fMO{;e9 Uka#\2]co1!Yʘ-$ⴜ"LhL-̃OCL3 dԞK~t1jk ɔYܢ 'R6)H!e60\CǃR0b8!N ?Aѹ# Z;3٤0ޑDSJtɿN&!&[fMha Z-9y3@UQˬW! NQFIOuuRƪAXZ6 LT.}Y 4(Z/i[2 AWfPE !X2U@i%@?Q5m;_s<=jE˂,Unݜ$+|W70:OT,].ͤ(6>w rQFZL(JQ"AǗ_]# 3 \^i[.E I)(o*,:ᅸdH#5EId4@zN".ܤ=m9׻ܓq %DV:7(fGGtw} mdeq]007g65ҍQYsmܼ(N_n/<0 ҳ~@|€7slЁ܆>])4iL_&PTg.dÍdF2+m8Z>.Eu%h5:S_D3nK-::v/{cc0̀3P|%fhNzkKVjǰ*  2^v&7HdwƆꉬ4F_\Zƌ]RI\,bt$A '"r b< [A\GWSXD@l/]_ʩVt]!, yA!{sl#~1P*OTC߶A `bMꨪ.0aU ]BmxIDa##0rFtX ~[Z|㖩y,csɬnNS@*2RaٓPl (d#5@5@} Zq%Yw$i7y}CI-ar h9M' +)#k`)bb1P c}yԂUł~ұ{e挙yji~+z5nP= .=-VwE_^Yu(P [6n?^h*ޥo1U2SHb)1 Իв.C9‚BZ ##T"]P,ũ$g5^Lo-\N҈xPư/3KcC(!+ B &EXхOΤ!qɉZd(w5 zwp UO&G`ulm{yKF -oPqwItNѻePF{6XWK?5Ɏyw,UO( }˓p/]En&~`~dqaw`ـҝ|Co5PYh e8uI쵢sx8#T lQ++_r gA|eN aǭUIp/3]"4xQI',(Vd.dJlp2 *5 qzsVűb5U3Ds(᜜G&V cU{hwa( %]lnO,ELDIx $UWPtNtљD!JLI&@vtOx8 $Ka`NJ jʆJ1/rM}MT X Ԗɛ'I\_9Ҟa@_#Ew]i+,UAX fD)zxS CKLd#cl!lX1,qNagdE9LLo g $On퀨 c5M;Hɑi*"Z>|8]1cբ(= XmؓlVcr-45p%̔YcY#TG NP?9D]EDV+p!~8heIq*CNɌ#mw_82-4Y"F)#;гeM|<JGxfEKTJ.5p;}lLrOthW^+N8c2A-˹B(G 7]U2kN#dJl >a ץ^ Fw:U'xͣSd%7*փGR[֧2TFQ=TM*2-%,E?J93%ԊJMl ` w%rXsE@fZd khcqC)kI!1ȅ>u6-v ilegŭS7il9}aIT,x" ahcV].OV FK<1[ Wfk?-ގ%EUT~i"9 "IQe/NOL 4~Q6Uŗ4[b$tȹ +dվG-N!҉^c-hʖGݖWn8åkC>fTj1{:7ծoHHTt~d+ÖV^dB%]YhqA:?'(Π=MbڤX㠹EW82Q:]P&>,+0GN;GP+u LթoeЪZ-T[k|T_(Ղ45]wNYARsA+_Mk2`N.p_Cj mF-]~!]J!{ @FcwOCZK!YJ(bC❂cRi5 {0%HP*o4mRUT%KJ+ "m YPP/u0'\ׂ6LJf? 4v&/)z=K吥Vqƪg~l%P$X"̈UEq#Pıƪ0e()~abEW0;Ƞ{kC@M`ZUsE)+kH43|rTE oQ?,>ʜypWC`GPY5 M&:nYjnF!c٬6s%B5YXB~hT,ּfŨy촒\$>i}(7~Wڭh.̃1hQQB!l-"fO΂2AQa &9{& 3+0$*.!vW3-4IA!ƚ;޲UD?s8"hvj%-ch9nX5!nkhHlkfVs)Gnk12w=U}7Rq&,>(x#VXj ;rDƸTnIWG&U^7y5Qs\#Ra'JmւU5vLGJPL%ڱbRkS MUr~5dCm[06RZbʰZw"RQJ"FG!reGA-!\ yBZ7BAoVd/!~r`=3%֢OYʫmb$(k}'el'vJ.u^R deK ۲Ζ&"+~PL{-tz4 8Vʴ8lFqB)Z,iv-Kڎ|r  )B})F Ch0~qs'1%j^MR_(ۚoڃQ'e!%, %ޢHYj$IfڵR@G cˢM}&Kg6S^Fhm$G4.&K$B/J:|2_#)Wn~"vXwjgX(AeW36i k,.R9(w~Q>VIHX@Ñݭ;Wa\ƀ!|T-z4\ȇK`T)XO:M$hzYEpglb*CQBD}0`,O$8~֩[hs験_0 @r(kklaZl߲-z.o tْĂ6tm\itFx4Hp,g%?(T֝ŵfhZuWmXu]*2BZ?@ ip90p\2eÒx= ڧL9.A)[ ^ӝܬ8 Z~Z%O),1FA^G6.\F8ԮYj CjM9R1tYVo#)E㙣$`ORf~{Y}A ]l 蝟9_*r6j´߬5wZq W KZ6&jc/VQRzUtPA'[R ɢ S$X-3ZM-rTĀpY]$E"i, ^^q,Mڵ1{[I1> Ŏcug`l(K[=H t.+:r,o*<gL uXQ*FYGP ՛wDu͍]n9Z5xf.D2jF$_N!~JZZ2ObfX6? =Xi>A]I+Qm;n I< # u <'9svk.I4XxF*.yjre*n;-K@Bv;IhLd?Y:%$bqgiBW2@`uҧb<!Y74fv+J*I_|G;ok ߻{O~}'NퟘCZjׂ,ێdZk̲{oDy2L0\[S!SkOoo_0Hgxv-e%R~0 !|w\: sk=sx y|f-W_{eՕkPKo Ok,s|Kr~ϯsڇי>ܞ./_:~l(?~ EZn-}uMDpn>W|?y;.^3<K<>9Y+|YƋ}7C^G_E>S-UnsYeiso? > `b`6{^ķO?O9I]w}c =_ *w|\| '积u`+?33T$YG\럴<^ 'qx +OV|k{ ߻/|l!ΘǺ)8X{.lyYohG ~4oOg\==ɼCzq>ȸX0.>?w>O~rnjGa<ᅨ?Ƌ9Aɛ~qK%kI~'mo΂w@K⿯Y`,oOqkt?5a@S?'>s0 e;gZiTnW^W=ąp"^Owx~ ΅F}*݊~oeh_Ŀ\~]\216$uyQnOx俾ھ<_mUcD梙gԷ!ns1a}o!_V'vvg#×{x)?~<>rG廽p_~XϏ/44S=(L{>c̞?^Z.cP/岩P0sBoO^Y5 G Ӧ~Iendstream endobj 316 0 obj << /Filter /FlateDecode /Length 53480 >> stream x}K5RݼEv;k8䁵 X7kkϖ":red|D_?yǏH~?_;}l>gm|ݥ}-?OK>nM~?\_W+#]o۟?xF4hK) v ۿmˏ? 9rsꟹ+ߟ95>嫯XO/IO޾+L5 x-ّR5r4twNs7:I[ <$\]!<}G~զU is֣X(=w{Jn_=N~{8$J@}8s#a}>H[ "$#<ǁ1JlJ6|{}'\ZK1WUfN&Vb{~lE< zc,)_cuQ{6'gQ+ #HA>Si_sm9<ŸLݺo qv?njFT0sjrmFO_)}.׼ ɗ5j:R2 4zhNA*byilm%_moz:zS=.A0Wgit!%B•tsX^_X&L{_ޑq}5oW܃ j}6A~A p -~6w$פy}rL>W/x{5{/:۬kk' Sm <i4.: 9 fk[_+ߍ=8w, ^;ڰćǟFh!NFl}K'5emp}s۳]tgp &X\,4@ 4$]'>D[ i%\K!9ٖEcXtZԝ\Ov:} ΅?7OĽ~hTkrfd}r#v3o^4vz-sa6hTƚRܭWځO. :s8֛}}rZ46-"񥊴O:o(;=Y^;eͣh*Al)Ma_XkoX*{ C9֮|hiUR-&f;Xz`K&EO,$Wumqwy`wGSf<-kGEhRRApans1nඎ?^[Ew;79m:Y!~>FXfY_MeWi!-BBZcvn[pz5 b$vhx4@ qᤡC]&E:Qp_ȁ9p9݌)Xk֜ D<;Yx~ab jo 7o f%Bhxn̊i Eo4eغ^9kﭞ689ޢ PW?zi*s\.^]̵kXpV5/wk &;H[b־7SafA'wֹtIk*@h(8LdkmS'SXtFw,DCiX)A_ mz70PMCZ 8*^wBpTޜi6UZ?L e7N.lw73Zp!o>V?3Iǟ]YoPq;;6ǼR$ݹ*!9mk̚z=%4@ dS@pp}F BQ8;o}rMg:vc3 ؅c{H \d;^~AZ!Z 9d!)!}rvnP7ʖoڏ2-w:"۶[| 43)n,$sk(uwAӇtpQQp ʻ\u2'肓ƍd^[$8شN_tci !!aFfw:I#*MkiRy 4AwpSpq5Sz@.: 9 ~]`; Vqٵ6F wWy jZiƉ^bsh!-BBJ:9=)4Zj ۜU}}7w vw,C̓Z6'am?å_x PQAh:L}r>nMWAb1Qy8.9\&DwC44p WcHwl|7g5}Jf;nnmlπMKHTT:)v?c$GI@@N ?& ]tbFf4.H;}Bb؆@pmΛ{|>: R%\EG8F@ݰԽO C47'v%2p6A}s"Nµ Rq`kYؾC~bsD [Әo@4.KHG?ke\|1+8‹Eg,;bǠC|8}Iks:t#wqI+tpZQcm)]k]_;G|gh\[uKTzJ:BЗ_8gtүKVĝI<>9~.Oݧ:j6:=$ܒ !/x6~vNʥ#N~AڲnxmZ8 O ]|}lBut(88Au$dDhQ=%c}w76!Ql˰DNw Ơ|nw@Hp1ءm1"ݾMxnƄ 4A]qe 6<8V@cí[ pB^4"#欟ۚ}#10?12U }K6wԣh!-Bv8b3+j ;87^˺Z9U̶p!Q̵VM.mrP8"$\K!C+-\µq(@vrN0x>Cp+<~}ݨd _ v %Bo!;6qW!$\EGx BaĽcJ#53DbXWH$}B9 +#C4[µt8tWq}rpim.pUiRA⒑N!qt{u8=9r<@ SXRp}ٜ$x2$td3m$8zHEs QQ`d2D4~qjEw> y 5T Kk3MF(>H[ "$\K!<ǡ$zڕ[:8r44ꧧu74!al4@ 0@ Tf>H:IZk)8𻕌+ )vf:,;A6SKe 0CޡJb,՗ TB$P-@7c5⎷+H).zn*>Տ%$:ംD2$y7܈v .! `fcn'Dz[p W44jޅDAwj# /'rfhCeI܂vw؜{vh,p6Ir75i^o:>c`k#<}fxm&]9"I4]y3!E 8.ϛs)p. 9]A_r-OS2lgUvdq)X$bp,#nhGт:4 tT޲6fb3u- X$H㶇3rHtF9@Ys .{rQU%T>׍ZNAnB\$vB8 vk-@zugsvBXw4!Z:ct0uy=zsz~϶G3EPCK `v֠vр:D((9{%QKE4͒ |cqU7p~qlOG p_Wa0rNv WəqY)D,fhn`a胴.Z 9 %c:.-ls2m&:2u+mGxCӗ#ZA٢үK N$E'ruRV-w͝2nG`_wЯ~Tbg&$茉EWU颇9CbC&FX1rAit!%Bµvs:t[` :Q69M8tRo%=,AEu .J 1 xWk;U^8qWloT8%҅>ȡ+\V 0 \Ax A96jS.)߬mg΁T<ަ5٢? cd2KP(/Ƅ`__lM}[o9IwX!:N4e.|bR$r sBETY \>H>!Z 9VcgG<8'sE{NY‚)1,V%F}F i#i7>H>Z8R'G+#urN]$[gLWVHe;9gsθx9'p#ua|1 }s,A6ǫuX[dl~Z_xH`NH6!m^SHK+C2W{F mOu/=jin3̗̗Ӄ6|#ddэ.@B^:]Eo )!``͡%.à]aI;67|΀_њ6 w9Bf5`u_a3bB9dZ,]I>Yj^YmW#C@9Sy.Vٜ3!,_) EodJn'/?8z3I_4tY4a l;g0Q o w'_ob@E 9r. .J 9dH >8ڊ}#q$;]N @${x}lFm'\6:%BS}VjfQݛ98o qnw2|V$>M;$vh du_g=\ewWP͟CX>D ۜHt8 &#&_)p+K89tk*̜]|}lBut(TQ- ls,w:`a0nFl3)I^S,c1pWH>>9|g\GRHZv;W1x=>3gUi쎩 ~lؓKrE88HEM={A{g?%.Z 9 leCpnR rQߨ*ghQp څi΁bCZ> {PQ7=%j (8xQބ4Lҝ.`*Tt8g`#G\-!9&ތPW +lvk1+h D dsph} $p ZADseWov{?ꦡ:HAXh\V~Gp}>6s6蕹pͭEHH@xCV" +[G)TJۢv- ^!Pʲ3V upQQDQE-lMm߼hzr*hΣqpGX||Bilϡ?GQ%>99ROcȴ/I){KD{ 8?qp >GġK攷yp2r*usde%11yJ4\!.FfNH ?C[~jVy}|`[UphYuףqR,^c8G~3;-|;\A<Al?;&́*mGZ003 (B0.<1mt_FLVNfo B#(h7KkjRFBmC!GNrrFA$]F )#|H&{ Ww=n-\µs bW ;< y0̓N9Ji BB:c;L<61-ȿR,)YI, Μ_tkmPzUb.d$\C?/ W+2* +_<C\@IƎXk hT1ڟCPX|fcd'+ NNgc F]]:t (xl`mh/Z q7*TO :m8׍Q?qA-KBxC7Ψ<˪U>lUWeĵpGΠ-QqvbpqUF>vbh!Rqȷ N:`OT~47$NIX4)Vt|)a7B8o3pב?F!7K^MOyzF#ʙ9 . EDv ;@aIF_[p1 L93+d9B}F821D3^MW$G'%K?紸VO,'qrKeKIzA~ z֘>6GI}!cw@Up cKv<Ok8^On=/ gVS/{sU-;V?a%tJ}Βve< -ƒ4Ȝӱ QuihE>9 SU{:2*ğ +xö$}2?wvcv/?G9F{8s6Og 2PA;.ILvlgp} -BBZ;9e ot88e)"~% 2$ל Na @@U$%r$ c6t,[m?S#u1YZ~Y9]b"y#Xnl` Zvч iqcʡ'FfvoC:CWYd7[blI7ٽ 1wtH;$!l"td Eu\GxBӥ FEDH{}=l9!{ ~gt Xл c ZQpΟN>9$ .[AÛ+h`9O[zplyUCF>DW%\EGx_YϘ68L5laau-ھF-1d tvs3o#5kBN1N):':EOO\#_nޥR! !K>&[8g}~}l-BBZckΆ8a#[=1UζMiKf<]Xv@,Cn`%XKo#8À@PCKBx#E񻫎gә D@W!p\JB=lcNr7ޅJ+I(ނlRT92[8\MÝ Mb#8]pnsowl.u!Z.up Сc,ӿTV?B*薠a8Y<rppH{*]Ao?{pX'gt,>q3eK5RUeF(!lڽ7/F5oA>4B[K"LĕnݦswvhXwrtH[[blA֬y@p78nbLqyLh!Rq]L\[_>97o.O&nV]&OeD ;obh!-Bµt8 ͮ|?wU)ã؁`9"$\o!(CNS/$:BYu7粹d#t\[>HÝBZ+) 5Aysp;pR >$bd*sJ@yMp {omk!RqgMp7 N4Ic}8vA% ]ɬkύ`c胴|z)Z;clŷz t6DD2_pCbAgzUm`}%3]~}l%B•c n)dW ;)xq*H&e-&>ߐP@)ts`<Ǵ@K"cfbMxN94DhkGAL8'>A݃cq=݊$~jEfe4ۛ^)=LGmzap=vp';F{<ۡBHEoCnd]=onl&@*D6pEbҶĘ!Y+Vȭptp.!}(Ϋ_ f64yae Ip \jbF `yw@~"W@[A%l| NŢXQ[EXv}[G7#g.SdA-EHH@xk0%(Pt4I;b ;hqk-2t:(.-\"sr]d[}mNF !H: ]:з Ks/V%\GGxBLD NQ.-.q RZfW;Z;8[9'KP#zJ L>rVl-Bµt8t]+osy*Ѱ³)4n`xK6.48cosEHH@xCbVg+M]3nUd)U+ezHYu!`46R"$\I!9;$j%N=N No"=8suQ(,=mŸi NV bD=Hrs$նvsm CHGxB0| O3,UWV9r/d "I}^: _uBit!%B•tsfsrpBڔŤ>nY%andK1##tcЬJf) ΍Rd=k2 oi9ܤoV{|+Ϯ7/L%O,Q//QMFYCJ@QM&8# E P\E^,ʾJ/ [V3%֣H yJ~} 8EZ65V@%X(JDM(4z[qə^e%VrBJ=LTEL#-z f rnZSu1Kxz[8%q#|# Ơ %*n -BBZcSӥ<1 *7tE[er 0p+gs6%5i  %? &ʨ1  /rT 6% r?hbvz# K{{UM VJ /Y*99*:d?e0oHe 8}y(d tG_Gΐ * uX%\_:ZIi3Z{ ڶ9+KHS ۈHaH@ X^~A;ei1'1lX+ßl7CfYjv*-˷@p}sZ;:v􏿅jT_->9EYC :#k!VkK"5Eg[XҸ !!9H@NӔuNg~5~J Ɓr;a[>o-Bµt8tY)i M?L;yp힇)JTes#0r*6>H*.[ IBxCadJ.TsYҵ7eMF:%ӗSQ9f#T8j>H iqp֯7v9F:AEv] \{#fh5?7G@J-(xs瞖.qpmgW)3@DDWzHJ+A6ƍ`e .@ʩ :]Eo,{R3pΤgM 3 rK Y'$,tgsh ̌iYKBxCLy0iob>şqT!7g|qLN52lW8.HmQJ+!qHKNIR ?^P9jP@ nFXk up{msS%?¼8K̯|AaH0De̕4gMj nrŘ詫K;KW5nMI 7$莽_86@AkwQuJ(sZ ~\3f;1E,e߄%Xh#8tg98#iZkqXR TѰ=#sV5. [6L_7WM ئw+i̞m `}Jӓ~1H/DG>yyRf2,$1zv#!:-9]B*st[h9V5 *Hf00yhx49򎰞 xB~:kiYssL]lpQ@Ze ~\[z(3ɭR/YlC6Lye3ӝt^/e!!͡g\ ؓG_[ -U~1c>8~V 6-\H;bDwAÛ;36ǜv{D $\gH>B l0?FKK!VtT~НOJFp90^b݇בQ%BK!<ǡNtkb%NfγR/\=K‚Sp2ybP19iBHHEGxB+7d&.9yHEמH"6&H0h$ *d*Ų 건M'n$b9{n ?7@=i0p7>iKpA&3cp4x={- w%z^YI!#\%<ixKp-fI1ߊ>8gߋ4&5,ѯ<`B6ӗ:g~a"xA-$BK!Ŷ''c{VTs*QucƖ.=.Bezm%\KGxIz`:#E^ lHڂTёNDU%QpltpVA[g?i$em>Sg-1{P}iU#g1 Nc.H w^z2n7bCGiۊ+>$,<DiZ}~}[v8tL햴-[[M)ZF2Ń :yX,FH}~}l-Bv80anM͍Z-bz'6#oHNLz&Qdp@4 sT,gUEl(;N.$&inˈ[dGO3p[qhA+L~9tAc(M#`,OI|yJQj@w᲻,/[ p%'?F+ XP:D9Dk|JD+ݾB" ta@XsGq3!-Bµsg׭&19^.H%~tHhNcklx:R^wc`f2pZeg,A[\vn>?B[o"6Yl'vf!8$A_^9y>ӆ}~}l-BBZ:sZڎYs:cێAVm$qJ0Fp3lm}x$BK!0}ա$BK!(Jjf>Qujndd),EԣeC p>#v .ג,OQRr|Ͽ\/>5\S-ji m//R )dʧTp)ӷvƇTpԐ3~Km!eu?~㖺>i^?u6ojÃ̧%\Q폩_c5BK*?(;4 Z/&ո3s݂Ӄ2\0NV.sI!{!C!r{>x5tB ]Hƻw@E̓?OJCoߪ;ߚ˴[?㐟Oo_.G[e>[_^wʵkCXmA^3tR!5ⵢ@@/L?_3ǚaӚ=m;{{~1k{IYLΣф SB#g,I 9[خ0']2ki"~%G>|j!ՒP}U|Xs7M&f0)]U8Vg|,roJvpn*hFz4vgbݓD8Ӎ.p.~|Kk-9~GܺGe x ԴxKu \0(6}Y\].P$!rzv侻[VFzL/"pE΍.X&E'c ""pfxwl3 #dd(aBȫ%5ުZ)v?Zrdlb~*`oVP浒Ӈs aVLxY- ù, NP+aJkEUvukd֪i~#xZFsekQ^ʩEZZn9/xX|7Bq=M4Z,m ;)g#;:S/WĴ 3Ҋ* !#v:HaK#Yh{=[A}wO-8JQ+msSicF03 `*,$~Vi5 MO!7J=&ߍ5&&7CB/$& jʮ.2e]թ |J;Y8_Z9mjJHgVN#JܰVwn. ) LQ94KV ;KqعѰj kM~piae̛7j6G2܈ye\!Ğ[S괃VW"1p\*`rmܼ-nT(~.E?rfˉ߿Sڀ8I;vDٻ,i%WgB5-UN]>&ō$ PV[}?Oowknnb gl˪߿ 3 hz(C(d`wۚ>>*x?!0Oٵ;޳-ikό"Vd4h pH7!7qN%k*R!\H@fX>1}ZE' jtٖg}i+bHoic45+e3ՎH;{|!/У`0MV]`bc 9w<̧+yzn('27$IOt.8gn {Lof_X)RsT,ܷOfZ)$TIxጙlDpf*aӖxXk Vl8S-UX#kSuԘUgJʡ޺ZVlC0ɑ yx*#v5XE@kCde4 !q["Raj ^(ջ4aL,X-٧Bpe紅r?,i#¥r:<͙&/qx$48-,<6JN FCD 3z=2kU9v8*bĩBdȱze0,AÒx* ?1[96gjJQܜ6̥ñ#FgWJ3YC2Ll[Ƨs39\[ԏ,ۂcv:'דsӢb)g_hI c cmPm[mz9,I4-r*Ό.AOWNX.8Dv} G Nc^剂њ fכiSp C*B']@>ۭV󕠉3\bPuLo7K[}2a;aB.Zfzor.h']a^طQ:K9|Jh1ø{+Seޑ\KWFR5* V gS\Qd2#a<_Z֣Sͼ7o?N`3{4vk4 Scz]0^smϣ3nNiwat7+9< [һ^4l#"O} o^i{D~G#YHV6f~~|uqn^t rhѷxZ3;))$M|qpeçiVq8{ajfN0,ƭ#b>L1}y4ҏ=Hޖ-otff8Þį|lldf0btA\n ^ܖ75l|93 da}ʠs$mӵ"̞Jk_!3[nK:86Ԥh!xh!`h,ݜ1oߙ#5#j3&n鴴S]wv֐zIQ'n;۳QTVA$MrJpv#`7Sc3ʠOeVL֮b ȸ7c3NX1X=e^󰳀_==d;L^)ק>ff&gs˷`sv Fk&8SfWڋ= h؞!]rQSnHFԲ[8_YF AY#O>Dz.^cdXXdC>)OKIpd̫{1tX ׬Pws,_p-n`;)&5bn.2#|)NB6Zjwҁ>stҳtLw`(G/g+i\lr셉pP;BAj`gL+V螽P)3c㝳V)"[O3\x;U-N _^3+ifobKL&W>iSP4KSn#ㅙ9+f .o'p7з7Q~ˏ}ff9DQ;߆[X!b5 a-P84i=0֏n䶇(k|'3^bWr;ۄk&~QFex]lYT=u D"=}m"ho!^+F6tCkY~?şs͕/#0. }uowagR 2i`t}3t,ͧ7K/AUmLKݍC{R< ZRrL*GŘo=< _gu$ݛeVa[U˭lxϟN?'lubRyr.$;n·8'(Mʧg߷ު15 jց{k {P'.Tlw4`@v%3[So86{H `Qcwa/-| cX8b^oEeuYh=M+Mr>ꖛR7,#j& ƣv4x"K?ra+CK2SV@S}>r)#?;؈ 96Y2v~ ߈W9ٌ͋XJ&l ag-?D.eK8cl6nz3vDgfGsDۖQЉomQߜ@D=f!r٢0Ys̢òp޺QDF9RpK H OrL Uv>m]G+|KEᮢQ .llY0[663]_*zDcO?0F'ymWlk3H"kf˴ho9/h+[Atm7/3R v,Iu~G|퇚 e{$uF{imV<H]&J|F$Dn6Oub-Pm YQ&>`n+{Pv\5ʘ Ϲ]W8tD+FaOg $oѪ)6 j%huӊdHPrƸjT-q ς?j10s/8!z෠m3]btT!*,vft9lH(Ξٜͺnh96|r܏2ёo]Lp8%d }sZRS' f4%t^4ws\9:OCq8m-Qo`?1k-t CW2Ff,82>;e2;̎rGo|v a0GgXy w2mp9pӓYl(کȼK^Hn1p/2W>b(D-sh LU`6L4׭X*[giMVD6͵yyT*.leIz_9Ųƹ[`鑻_9uk ;؜6krpG';ήP)`,9VX(JAԬ8<CyDe۝2G7CRDgZevs1A#SqeLoE1af&>4NO7p߳4g~6hj]3[O "e fU+ڊMUDZG< =;{WHPUC:.ceg9%&n^,NA>bóm#( 2HUVٌ;2aUJUGA^L$_lLRN3>EUA {[@+[jֵ2nlѽ[MNmeUQI>'jEѰ$6/4/o}`txLmjCji#7!h\el>L xM+K5=YDВ7АS^X1UJ d8+S𚶭z?`$ERch8Ϥu n5~xJGPLE,ڌ(y`/GTJESp<$.B:jl .W ^"㉚%BTsɚBFkF!:t(OߺjQL^"R5 1Շ20BuA)<G`LjӖ aq4iP 9zI9i$2 7Cnnj8NDw|K5R E`n%`ڵȨeKrJ;RYɁr[D@0QZ+-K:Kw)t:jgZ889Ԡ W|YqgK5>1˴T+( ROh\׷Emߎ0~mȩMQ8l|)pzm1Zs^j:K Wՙ^-9 \uM%jYh#JG7ZJ2yS_ B#Gn0mM,L~35ܧRTT4remSd'jȻav嶴Qᅬ2Y|j$& nKLyx-BP[UVI5ҖXq JMزMiCQRI$xnoJ긷t:(C. `'=%!)ž cI| [z_A񛄵fŔLzeLRIX[ "Wf)5|c|c4=72 Yu.0Aִ8;M@$8/i@1B% #ڙ`SQV>!ˆikSJ-^`SWABJ{WRza P*uH9 >\Ny!A,q.ؠm1fmսj7Bl-ʭle ZpT0,h5u]of֊$>t95 c"V,2[H'Z.ݗ oNoR&߅ -$KAы{D֚0iNw@~t`0B,vZLVt9%nhGI5}z:Spwjwd :‚Xx 6XRAg7%WZu&`smNYW(EթH>yFK9LofF b1F!Q sx ~jH;ӑc*8piYmsb7 w&Cg\ [ :X3X}&!o-Ȳcvmv4~Y3`r1Ob/GTar@C /** ],A(Gf =F<D"`g+7ʯ8Pvzdˣas,?!L-&Ρ [lpuyk#&!GwѺ2_qx7́m`s{潣,zD?Ջ Y;= rM0=3C`Q{'O 2!krW2l D)L9W:fOGPTE*Uqol&lXg(U2abë|uTv#4d'r"DKat!~ݬqr!dn$.Yg) _˖x7/*ͽ" ǵN$CM9!(HXG+npd2sLcbDmXvVʦ|+Le֟|>{w5Ll'\\!m M)a%1s0%;yC_`Y;gS s.fJ,J$H?'MԽݚ+d%CHߦq5b8ݵ 'wOT,9=HulTH:R)JB\׬$U01(Cy~<r3уBZ9TQD Cd`M3p (hU-8f԰!g71<ij4UKԕ"bǙ_ʹn-!ݢHj'YG!eK&lHrb!C@j܎I㛼wSL֬2*IyS-^dSq67i@2"7KTy9nX-|FI*o& @Wyb lrϖ*c+e9jIa;5"},b>Kle!#Buav&#SY WKXs#)A ZJCj"MPciE*{@d#j{jn#.JL!p3><)4ͱА| -;KJ@Yi^hmSv>MkRcʵX#q@/SBV"UY-e98imKl8mLhIF[36Pc-4_EI=tȇ nfSrh Ya!2M2Ӵ}7us FsNl@"qFOqwTeJs#cMpx{lL4m%=WcuX-K+ʃ xG?E$ '3.Y8Dňe85:Q(E>GKq$9O cvJ+'1Ab[l*"6'"2 &s|jaعQX:aVs+ ]ӧ,n5`-̠_-<([͆E%\3 7Q# /Ð81x8[Lj$N[6g6VYc/hamLa1CjI+H P1On ;Ț?9ǎs,*]Ӎv M5Dc޷Q|00oݹ)hP}nC3Eɏs@ Ŋ~䘊kyhK@,rQ<@ IayT̀Į]EDPVnaf`QE_HN(Hз$-B?Os摉*"Yu^'/|+{y0BE(I*K&:36;&* &aWsL%O7/AgWޟdά驾Y?Gi}#i~m5|4][M8n8ByR\Ԙ](oMW(,X)48|eX(U8@AP._%3F̠VV9GaoA$~!iW<[5Qp^A,TdFE/&{ҩkh3[[к/(Š ͧOUe k -y~jb15lM\gb#,K[BTjCMVz϶j|M;9Q24e"l K! *y6~}&٘͒]ɇs<-ML89~4Wx`d^jx̣XTU-/4˳dim,0dsKh414^y( R N8BZ3hf.Qp ۰.u{}5{ægNsl߾8;w$|y M n;0bUl Stˎ֡nPppz'hQ6 ]]' X%}X談 #yL.6~VN!o'K2lryIDu4l lwK9yr -,kMD5cnxI5VW a䪛 LX C3]MN7(MMW`oG,?2x&m`i_:p|(笯z_Z@5Q{,掳\ˁL:MuyK,ԭlZUw6M^[{B(k\+OA)9_;^BzxTV'deO0rrGڞq^`a~bF eݓ񸲎 |cB֐jj<*E!:hjww -B>VM*F] kdȚMM?bW(㟁h(}xM֙>>Xl:+跨S#ZsDm]`;R_g^U+_xP+lMw/}P&[ yFPK.&Zd3rL<#k:>k옫XG7(bEʰ\$ U 2?lXsZ 泌ٰ֠GQ$p +ŏ堃4!t7 l"(PәZ}[KRe-eK/3a)Sx ަ8DC Q`W\;O`MBD Mdh:G;rh*|x&y`\ZN:'n >)Z櫉^eH#Fsf*z֐ήBjt Ș&1΂ Yy td^вG/@&nu)/C [u)VZGcŶ_6*[RBsM:@>([0G[^9nQ>?ţ2Ưfm1qpZ`z\ӟAE{9&FӉNfoiX:@>hB!H>) iXz:5jCLcHJ1s48&է6\CEC4C$SLGdIvىf*9to"T+;2t2CBd잧'xcƨG,HmD:-ig#-"_?N Xp;#xb4 A췃nQ @Ebn3&Gl;7;7mDc<<$JF) 0Vx6J5g1ᴳzjE*4,1Ĝ)cyrCj6xur}΢r(5]:Bұv+ 0IeX::k.12qE7zZ YB4e[Y݁uX`q;3 8c](JcIjoX:\@UFt+gOaIOd$Y}XdU؏Ё;H`%\2]^3kr\( {FT`}"򋛬hv>YP}PbGoS(Trj%+NI0vt}: `x8FYqw{W1y,7L4q(;2L,q 駴zN'Dp ĺiN\?F;Ei[n"J Map"ͨ|$ͤ~>=)V1w;>hÆ)D;\]rATG!0@c!X@:b-bu|T^swpGWK^z2} '#;C\M-6wd%̩EE/f[rr靺EC={BsCFr BhBۑ1M覩nlΊ Qs|6}Nk4}M9;d}ssVɂC:>,c6I](Sbi_T4_1 6!JY9G2 )wWʇB6FCC#\lưEO G=ơ{i'>qߥPj9ʝI۴|4#He1cZX>tGyBv IרπŸR_uBN@ѻHMJwGuvn4ȺHje^5-kƒmY bP>'s;jWw!/kp^k,ќh̍WnI}J?촴n"4E\~:njD~ǓW#Xk;&VL4u9࿠%;!:ܘD2B ѧ}O>bƄIj]+VcJдhH{q 5Y F 7ľRW vYt埘kR=LaP88 Zh\(tn`k|Z66hqNД8y_2B LS⧌L|nlBCr*_GYͶAoB@/?Ic*-:zܠR AֵzRmzGe{dqUP[?˨n}FK 9h u)Vi)tG ƧZM-o92n-02ޯ7(v&yv|l q!,H6䌑Q t _ (B]8NUI!Fig9msfލ&հ6pv 0ztB˿ jU0rߐ/^zc6w8zv^u e.p}XkiG`A,.B*#Cg-b`5k|x B=i5L:n#^m!J_Jh̤, xR rƍ:[j'` 2nLFtSsp] eL5E4{ K-nƆѺJr,(BC%/- GX[n2wdSo,Yпu>x#ኚnUG#cFs Ď/1y$o@ݘԺ.)qa^j &W{ (eB6d1YnRS 75UUVͱ^NO8'jP ! vDdFAOs7͊},#j A^UYN|k6uH-5g[`TX/ATh4ϩ09ς*Mk^$j(Ѿ5rP5K# =[B,Y}hf޼2QFM_VFQK(d@Vëø<5TCATU|XA3J9䓪fh_A} ljH% nY5%bѢA7-FYVW N9 0٥Az- 4mОbߠ7@*&kmF6*oMWZLw ÕJ,2 Rm`1Po1ZI9%4 EU0Ѣ:X/ѩkjXK-5CZD%jK^-IUIT%V+hݳ@ z/ڨQoo\HP-5|F;}7mV+Yŕ XdK䤠&>2-Gܵd),gBd,F ? EҵV7 kg-c)v#jisYY$t kZ깱v*k-$IDQnXԔ} z#CB%C6E'Gkvv1W?݃6ʈٺ2}p ΈyU*=Ҵe=7TJ´b\tMGS lbBU%<:vm#·bQmŲ|5a JhZ)w˒[|`W4d5؃}]ec+Q5[fp:RK_?Q\zP촲E5E#iV CQ3VޏMٝd'4!E0oQwQq(4޸0 [aGqkJkiL35Ɖ32B΢4`z)BJש1%/p#*30eNcv?"+=i?$2EѸ0ii~в -#LfӐ*O55Kd5OA]}젦 ,`^l#.U *kSPyTMeUr]: T"1+(zLZP |TQE?dE@ժۚtp^- na$4WH%#Ś-0C T qI CЧ$"j5$F@^h0!8ZQBj|ߧ8Iބd`lB2 YZ@T 8EfĔ6cMIQ&N& .5VԎCY|+bf9".lxD-bK9(* aFLݱv>ś%C! mqȴ%dX*13_çG%f߭Y) =M>>YLcHC^TGe ϩbFhh-P)sGEפH?Sy@7[BMw v2)N,f̄W5U\ICfע(9z7; 0Yb|>Rtsb8i+JwgǮ wK-^ȅg?eEo&-\K $95UTۈ\#WS:ܥV< fFwtn0޲b&"_3olև:mE<(Mb(ލ\-Ow)w~oe^f"5?a`x#( f %k=|j DBv5jhMFxS/{Z0y#)D#`IZ.,T1WQ_B]$Z ' R`16Ț8/ԏj :+ Y8QpJ4kZp 9. q{2Sop 9& 5JW1 7v;3P@En.{Vf"v1^ )v!Y{016bDS-܁&z L-ҏmk}6teGY^B@n6ZK>Q)c/w'{:basGJdq~WϿZ(U(sN_/׻pyUGn9s!ZL'Wh&S;ܡAD-8Gxާ1~wabn *1=тSO#:K;i 5=Xxbnk~0!Q5k;X(#flMYUO 7a@,]{ţx5-a[׶QY΂p'*D,C?~OuVSHdj0I#]ba&$#J]Nր嚒HtPiAU4Q),+^e)g1 Ot 讎'HH*vmAcnǐC7PJ)qibetڀ1%n8x "jVYS8`0 ܉خQ+zdm fR_H\lm:qf S)cqw7{З^KTshXyȴ"DHv/*q+G_I}!䘾C 1Γ?VUMsIZ.t*KaV YZR"_\HChadF0iA\lQ`CCܧ5hLXn Yegb=YYd<4זxY H n]Eߩ7uV,c5Zu,ݻE'HFvH7̻teGv!븂2}3֡%ₜ] %j'}6t更19,L|nJ&Zl rKG6ep+Zv+;H Z5Io? ȫґڤ y]S5<9>[5Ʉ-*kǃ.b6|{A5Mb1՘DnG†R3g[ٳ9fSN.Yvd,r,25nb`^XцWkJ.24k|)NoWB r2ݑ-oƬNi1*OUv ̨0TڑJĽDkxaPj H" r;Eg6љiF7QW2UF|-Y@Ub.HLckm25be[}דƩkFYSGq z*^tVSgzKGX^.iS|XQKt ME'fFixܢ؅I&:+hYN5zJ9BmYȁl)nݤ*1ĴRG7`ás]+}se5:j$u2U'y6/|{btKBvdZ _PBIXmJfMtJ)Jgcs' eٗʐ ֚{?dCrvvA1GՑW+xuF%fWk)]@O.I3f1]ܾ"/>hz7]C4b*(@ӶE4JqCq93 2ɘ~BwP>Ift#O%9px5pھv;K* AvP 5*fZU~YO`5[I"D0 iaN˰{X"CAk)Eّ]ıs{EkD_ǧI5+0/PKBuTN.͚mӕ"`Bvy9շt:LϪkAh)nl-.>hOYq16) \{W'cKQ_1(TV7P4jļ_s5Gd i| /bpI(Ęj .: s>Vd ʈT+5&&:i-PuL[/8\ts t lFGh힆y4l:aJ "gᅧreM^(pɣ-v^#_Ctϲ\^O!MRݢ$5VP\Ԧ/])/QpG"dkWn)R`%؞nQ]+t{@PcݦtR ҆{&_GDD~&aR?;(XrDwME> ڷl ij10bM~<;w5GOXkB%;[ yk^GvSG#!=e Mo:{޴ tcS~J-&;<yXÙ :_n:/AS|ي vw7zܤt\j' Bh:Xr0naU߻Q@mL]55FNkWOkJVwڎ1B0W4ŚSt`T J9߯}r&esبzDQdѝћ:u|u}w鴃hDg TG } ܌XT~7ZXf*2Xf;[D-{M!9J$`avԓJq|dv)h k|{WYOnCĚ$K8ahm %Hβ3qŖ Z0=G|y;<^NzBԶb-F;wrT`%QJU2v?;}Y=I{A{F 6Q\LZu;0.&}I"W+d1W\yQcpsPb'AB-j>hhʌur].ؗ^oRG-VH]`5|uj9h hڗn5;O>jTr6lI]󴧻ܓ-\x:0lr©,+3={le43Bcl9k:$4 ʺMD˾X[&) vUOQ@ >k(z}^aζmFC#yr3 mM`sFIPvԤZE|(icTl<%}qM^+G)4Ú;p#^e7BXbK#r|8lSC0Rjk *(ٷTyC!ӕ=jl1-]!6#9 / C5 4K:dHY z5Q:3)]g2uSWAC 9ɖW {W?@gxuU$85|ձ|cۣ=";2vLp i70lqJIdQa(-`*V,$KlpUX): <'3xt1"ia^)C܁VahI4bH'$? K3E`yeiq&ۧ\Ƚ2.M.pϷCu,eL~tJqZNfs&4; +-<9ZpdbXg: !H@}k`1{#Q t۴Q)թ,h:#ZM9uT` Q Vey;,!j!'aؑqTzSDgoS]GOUuoS"$J33,G/…Ūt(oH#k4@U "SQ&J0B| 1RWbjX!c@a쮝kg.l1uJZ܏^SfSbI8uUaP/s,ʯ˪KjZ@!~XG2j%^~5IdgnQ`[Г )maɐ2M}A)ur@1sHP܎Bu]-MQZۙJAjvlRtk"aF%_'wHw-3{4 gkWzDEG䜼 *Ĩe {+{e(t$'ʺ:q)cb kU-?r^8~NQx04C ;{BP@#؇DBk%R=Q$Z-1)ʏ:cn4s5^HQ+`Zۜ (Gc65l8PLµj)Qf#×$FI!hRj r&v%#xJ]uEA[37O!E kT]Bp|uY)Hca^'T5د,*u ua;QˠIԗKyp҆ lWo/:wozv >LT.}Y 4(Z/i[2 AWfPE !X2U@i%@?Q5m;_s<=jE˂,Unݜ$+|W70:OT,].ͤ(6>w rQFZL(JQ"AǗ_]# 3 \^i[.E I)(o*,:ᅸdH#5EId4@zN".ܤ=m9׻ܓq %DV:7(fGGtw} mdeq]007g65ҍQYsmܼ(N_n/<0 ҳ~@|€7slЁ܆>])4iL_&PTg.dÍdF2+m8Z>.Eu%h5:S_D3nK-::v/{cc0̀3P|%fhNzkKVjǰ*  2^v&7HdwƆꉬ4F_\Zƌ]RI\,bt$A '"r b< [A\GWSXD@l/]_ʩVt]!, yA!{sl#~1P*OTC߶A `bMꨪ.0aU ]BmxIDa##0rFtX ~[Z|㖩y,csɬnNS@*2RaٓPl (d#5@5@} Zq%Yw$i7y}CI-ar h9M' +)#k`)bb1P c}yԂUł~ұ{e挙yji~+z5nP= .=-VwE_^Yu(P [6n?^h*ޥo1U2SHb)1 Իв.C9‚BZ ##T"]P,ũ$g5^LkpзYIؖrikRZT5G [pWamP+MTcn@}n b)"]%y(sV@́U5E>^FTnp%^wc y_kb);Xz3T[4[EK )[$Fa;U ,lyKhqE}.mHr ؘ7 iQQ#z0Ov}/ȚrFu;g~ jTyHwE [W .1Tcn㛡cEuy,Z&2A+/U_ɃmWoh)|=Os;$E()̯hjW;nlw5\Pl XE m^1rr=9Tcn֬U ݗUc$R}E5.F@)@fK|7Qś Nڐ{Ǒ b_!Re!5ͻ*{ &= CP/<=H?l2?P^ӣg辞\pQQg3~$#ڱG/xXc92 ]kX]rh =a%}n;h+2IMs46(SCC[0dS*aȤdb4pXJ`3֨f1mB-%Ѐ]]>6![ÛxWia [5 >ƒdN:Œ i;p 6ELqt@wH|3z0o$e0(69*\L0:K8dS9&Rr629ߙ[6,Ve{={tNxF1C=Wt(CU梽&{ĝ /(4݊ ]3ybt1i!s N!7W7af "9ȅ0|OO^z_mJ=ީbVupx4Û<{S7*HSB41Ht&A:OsXH>Τ!qɉZd(w5 zwp UO&G`ulm{yKF -oPqwItNѻePF{6XWK?5Ɏyw,UO( }˓p/]En&~`~dqaw`ـҝ|Co5PYh e8uI쵢sx8#T lQ++_r gA|eN aǭUIp/3]"4xQI',(Vd.dJlp2 *5 qzsVűb5U3Ds(᜜G&V cU{hwa( %]lnO,ELDIx $UWPtNtљD!JLI&@vtOx8 $Ka`NJ jʆJ1/rM}MT X Ԗɛ'I\_9Ҟa@_#Ew]i+,UAX fD)zxS CKLd#cl!lX1,qNagdE9LLo g $On퀨 c5M;Hɑi*"Z>|8]1cբ(= XmؓlVcr-45p%̔YcY#TG NP?9D]EDV+p!~8heIq*CNɌ#mw_82-4Y"F)#;гeM|<JGxfEKTJ.5p;}lLrOthW^+N8c2A-˹B(G 7]U2kN#dJl >a ץ^ Fw:U'xͣSd%7*փGR[֧2TFQ=TM*2-%,E?J93%ԊJMl ` w%rXsE@fZd khcqC)kI!1ȅ>u6-v ilegŭS7il9}aIT,x" ahcV].OV FK<1[ Wfk?-ގ%EUT~i"9 "IQe/NOL 4~Q6Uŗ4[b$tȹ +dվG-N!҉^c-hʖGݖWn8åkC>fTj1{:7ծoHHTt~d+ÖV^dB%]YhqA:?'(Π=MbڤX㠹EW82Q:]P&>,+0GN;{P+u LթoeЪZ-T[k|T_y(Ղ45]wNYARsA+_Mk2`N.p_Cj mF-]~!]J!{ @Fcw֟4$IW)C;(hJ к/plib*JCz@D|0,5T g8TIaW q1tLl DTAiPݦc.B;` jNt\YTALMsCPTKr l|3k(bn-% B(%1ZoT7R)/tP4&O<mOGv)wBA4QV9I-DJUY/kCN)A2lH7hۼ9ɋ(Yx=g+*v6FyQfoq)!0]D8A|.h0Q4gi}!cue3#䃠$ ( MU逊JT测I~~,zӓRѳsTAg9)6yЎ3!I%W\"^,3RZo0JʺyWRЏ*u;҃(Cp 72) \79F.S<@B4ǎLу8ФjIZ FZxZ:m. P#_],RU0a"g X\o$_j3(RnhO% (t<,i%AQVe::%<P"2䵃yd1X($+#k!yOZ,Z HSCAEI'B?n F<+ǪEd z~";=D&FKL&;nGyJ*\?h1SD |BZ,Ì#ZTa%R2!䃯FԽkX&]"cMѿB~hYD E GFQLR=:HRo EoU3FR;8 m]2 eRH +=bG+kiͤy d8\@T@]J{ <ܛSK̀5@*ש P (dK, B2XʼnEr<1ud%]~jCʵ Qt;1@]%rHHIDb@{k4;Dϐpb҇+lՊiQ X(գhTԽ֬>ʞ ~?^@; q4޼}G?ͭ5O^?~E;ZW~_/2孏w~۱#Om7HH׻aQnODotǿQݯ^ ?t Շ=|t{ts]}8<=߻7~?Un=x<3~ ))p-=/ !Ǘ9CS:,֑'Me-֛L# [`!OB)Oz_ß4J?{r-z/mO^; f|])X#|y͟_0kՏ鏟 gy{7o~FŧҌa {ᷟAO g/Ju;/|[?|v}ljKNF󗙁ogj2m _W?wk=O_>u?'ŋ\}mk?m7_\zr?O?/ o.]r8'9Ng~5}wۍ_W9~Qȯ.G>`=~iN[oBRr__',ΫWim|OC;--/loO|c~?;-|7pYCo}gxO%/O?ǭ#uM>xǻ?׾黷~/7x1-c/-~}m_s~_ş?t(w>ׇw^dҌ<b鏰Z?((ܣpkᄎ~|m]ϋ?'u_QhbYh"jhoѿmP[e62~b}N# G$~7~z,0 tۻe?g%~FO:]Yן=[Oߏwso?sQ?b~Ѭ[ٷ8g_oF[J_먼߻eOs㧿tV½Mk]nY_] D//ӫ)|ts[?}.CϞ=jÈ:r>hǢ=X|i?~cA q|?a1tӓ3ꅴ۷./_c~ xl F9~ XC~~ai'm)k%ϭs/(?b L3 >(S_rt{Evo|$@wss퇻Hߥ_}s~.wYqok1Ϸ~} $b>o>Op0_>^ʓ3.IZI~?ݓ'ws_ύ:*!*ow>>n|O{)^Ϳk ?sWW2|endstream endobj 317 0 obj << /Filter /FlateDecode /Length 107314 >> stream xMJv9df95`a [lHvߙy] TS LX+kuϿ.o_/?w._c}|n?oz{,oWz.nr_/o?Kx=?+?Q?ׯ._?_߶}u7o/?~~}[ׯ._w3uy~_m{~w?ݻݕv[^ߝu޶zk_W_\qqzEw/Bhq.qn^/3uVF]H_vuE_}fn=nmm {n򧿺no}v}|Ჭa?l/s|<^ 1/?[X~-_T}}})/Q)kY]_R^EmyKKJٖgەE/s_/*eiї=?ߟ>Z_zrn3zY/_1?}1{,3zy?1֌ݼez^w =/;mr/%>aq>]|Tl}ߴw/~G?6Vz?N[C^veOo[g}nNJ,'}?{YgO#>>M<6g=b}y?O`/ꩵ}xct6G'Y~m>V>,&ާW^}n"|:u<ދMj0 >kpw<ߋ0LYg1>ng1>>ߋt(2^a,罱z?yo߫yRͯ3g8g7^, :gq>}!}Mvʄi18fO{Rm*}Ut(j}>y>~<\pZmk~d[>k4L/HOJgkbt?}Y{~ߵ5{g>{m=خo͗z|r>}R,~%+Dܮ|m~Vޣu~]ƟtRm\mq0h>s*q9}wga>>+;2V20{A> rgA>_Rɟ.綂Y/܄koa[?kyc!~޲nE}Ϫ{~GPߣ_|[?9_e,MvY|ϧ+/PmKfdwj_>.Ӷ}`^N&^}{ Bgn{={MVwOV ^v~~O^wQ*tMU/`i1uA14cL0DL@|I 5!̚Lgn3vL}&`g.^ h&f0 3uL,̤0sEG #n 47`I #h4@4bP :M$ 4j3v-a&!\ 3vL,kS!Ba0c/,Œ}tyfaxyhΞP0 5>Pu.T25 (DBM@,ԤP#PB9 5j 48e\r:UXg/=3)Ď>ة0SgNg~*oLNVk`HSOcVS;Pj~*v< :rVt;N)b'Nl>)6?~*N't|Fwz4?JSNH3ةf!>Sj~`7PsUS<ѝLsZN~w̏kφ6s~)Ts?;e'֮<P} eNc~*Ϟ:S9/n1aΙ3Sz)b'Ck]^~b~ /?;ݥ;٥T]~=:Ei-줖{uߤ{NhNg9mN^}vJ]ͩnNi'h +*wwJ읨RN[Fi;X[wO躛{Y'vFWU~d)XeNm'aV~OrݳSX)w/U~*uONElsf)eBN^M)KZJ)(ͿQNi'պOg^;:{.wJ'q/Tܽ~RNݩ'Otr^ܔLLŤKb\R;ՒK~BݱJ~~~$^1~^/9)ܩ&wI]PNN)(rHr^)2;դ;Ѥ;'vON伖T_!BO_7*I6{WIO{&JrTrڭ;Jl{S=Ց^)Fr4R;;}I6M䴞;J&r*jNƋ 2!H +saA`I`D`I%cNAdsCp'e,`tꤌr8ZĶ-fGKVXh|ytꤌI -> 9Z-[hyz"- -cP8ZnT:6 G-bNi"E{ZR O7ej̦ZVdj%b=WZ`v+\-6} W:pcj̮kyajټ}ljI%E Zw SWL- 6bsWmq?lmO0班E\x\j,X\&Tǭ<([EPalv-b墱іeŖbAak9[ZlrWbϴ2wK1 {6hoAloNewT/bbWKbSplv3Ň]- WTj WAj ZEZZjr1Uew\[|>ЎEl"-nr -&\& EZc,[n,;cEō.AbrFˀrNX-7`'r\?Я"26H0:Y%et`6EYdhP",c F3/f0YR'~2Z&r+˄c3Fxjl,+,C2n9Z,-;ljY`tjZ̾A-cEemy\wL.b2\槁."/"=/ ӋUezr g{_Ķ/;}2n_ܳ^:hqe = F0`Ĵl0`FP #e^nc;n-;7\aC̄ZN-+Fp #۱ AԱĈxbvL1b-[̀{ c3ƞhP#eqň[̄Z~!F :bu,1b#eqňmb|1cw1b[-o9Fp#1: 2[h4zp{&-`ɈÀzFK)#a^AXv{J.#2iip1#,3B 6#pˤ:]FeR 3.3^2@ YXWvͤ˃mfB-`4 ܱ̈myfM3YI3yFŒ fĴ0#faf$ 8&8&A,ЌVؘ@#% h ǂAwh1k,XOBoK, Z:c[`h,M ƾb#o&n% f>U?-F̙Жf=\4EcOEco!MFpwf[hh&1h23AXpLw&l32.cCXŜ ҳnfoی`91g^՞mFp6#m363]Fp.#2b.3]Fұne]FP.#p&e 8 8p/L0e6#l3̄0LcRk[1[`9Vl2jcodԲ`-Fb@3hAfc_&3./&s,evAhvTGˤ:]f%̔mP>#̄6{Dty͌'ؖmfl!m3>6#m363ullް}fqc3X>#3όg}F X6,^0h`6xɅƧOa(fheay`fJf^.5 FC4BC 4bC4WO~OUf?MPlI`?/K~aOo f4b#xF_4FT2iİƻ0H#4>PlF(2L-4MBcOBs}{7,4SYhlreC ̈́:د/wt3;3! ,\3eL6϶ +|37c7c7cwAaGWe5ska ɀ]fB7 4ʤ7/ F ˤbÌSa0K&f&FW2FT2eQf0dd&1Fc|3!2ĈAC̀ COӠp~PÈe?~PaXa쥷' ?̱dKF {|2jc\cAIs1B_ Ť/XGgQJf x ds2X.Tk&-3^,yg3~mrЈa3o-Nxl棗F ZiN6i:`F3nP좱P.zimhNgX6l>u?ZƊe޳؎FlB#tdkqbvl4mhvL4b;@9܏k9#c,[e[gXΈ!댘9$fVf욱0Xu3ŲcT٣v(v\M*2ʈ%)/}2^MɬWd\4x쑱[Xmߤ?F,c-1{11Ƭ{1GZi:c [}ϲ+fg+fZ8b$aĠ ;E3~Vfg j1 "ˆA')PaDh pcŪޗǾ7^+s(07 aWl0bM!` elۢr'Ha؂۲%8+f ebCNj>'FPVk^e0-ϋ-/6# ˞$E(]uOQet,][ĒE [Y07Q0^El2bu`}VS`!0>䒮M1hqI&`"-ބbB<5 7ډ`OFEŲz2j*A˃r|KI|.Sh(eX0([*`QtH;Jؖ2BKYLѭ(ՔT2)BEPKHJ᎔2؞"x)[j">T& # j(&eB~bZ(7N![mjZbwl%BLAMLKF: Ru,\{Zʀ[bؖ"X=AEpGQ ʱ"WB]wB^%}e~XBK[R"%>W[&ӒY\,~uZ L,b[*`YS,ׇвJKK-"%eB(J E-,b;:ؖ"fƦ"x!EPGmے[z;fO"nI/ܱ`(w, V[]"%}55F,0j/[BN@FI0! fB LTC`X@-E0/"E J.*4=EpCu"%n)/[ҋ2`_u%咾!:#)fB- f=FpK2#%F%FPKZ̀XQcĶ-=F0yr}~Uc)uL˩c:/c>6!LC0XJMS/RƎu줍ic9mlZtic^2i ic`J &)c.)cߧ)ck`20l *RV1Nrʘ1&1H0gQJ'-^"$M>)6"Qak)S#Cw)泀"łHCM1Z,  r9[zżd1/y-3即RaX@-z|b=fh--6?# 1_d10cW"b, cpĘwo1UCU18 |(jl~~cK,"QRF c⤱J1[ Ƽ8i, NGDQcqX#Fݝ1UXjG0XvأrZ^*wū e ^qtE'f%fTe6]W]l(.b.Bd= ? 4T&͆ M.b"M.S\Rr.C06b? w[ŗb?*wK*-2"a̫XDy9cL`n{E/."..֎}nn~8(6E,^c{^&~W].[~wBz.w~w\}.2!طS>2 .~o]h%< .JS0)1XTbIJ!<L.(Vd"#AȌY1j)2. jl"J1AB%fMg%0)1RmKJ̄T`C=FpKR`#n)0A 8/S`af5P`*.,/ -Ƽ`TbtB%FPGRb-%FpKRb3!`cP)0{'^:`ŗB=c*& s&j*1[J`TbBEF *2 ^:"#(2b["#RɬxɤLGp<x Tf2w)3BEF+2u 'J2#R]A& bEhVdT(25x EPd|޷i& \0'@&!lB1~L Ə 1LJ/%U !d8,T/"|ǻW*|lu!Pď1~Lŏ UC82/#qd>PG&`ـ82"̻+ \2K1\2W%9L撥S.لydgKv3%;d ,?,rR]T2 œ2AS?b^ٱ[fF2/s_&&e[L5 >wL2-s"f&n1-.OnAnA9]3C5t zn2`pLsVoe[fTen얹ZU2/p͌%-׌`tl>k5#D0f<5y'ke=(3=7g.}$.B0]mL8Lй}pFse BMn4iVoilIZi6_H&ir50K$jqF SXj634+5P8kR-Y#Κ e&5~?:G b'Pe`v8"nOco+?=}+C0j^g6/Rc=WERcWXjCLjf^.kR}^(kRɍcwzƖ]#55*5D{̈́m5VcWM~(5]ƛ\0ƙ bS x{8~XifKc?*/g/M*4KUxi䥙xhg/TC+ 4_YiJ4XhIJƟ7f .XYhf:3! 5鉶uF[g6{rg-,4Bc!+ ߢ&An&RB#-4!hYh&uYg&Ė&>1̹Q&+&4 0[`e0`| .%p`ν,E 9WA` T.` xR9a`sJ0; $GyEH0æ'$<~0@G0lb12w c0 :G0`C` x4kF0`#F0C`sE0`"R ߄K.I"F` 1pB!<{0A~0x~7C⃁&Q݃ރ}bx{`T`p/`x+q{ݮV@ [C Ot$w@#-xli?t}kk{}{[ۇR0nm&Tp@}B=MnmOӅ oqu--4yklm7N,op_m ͆nu-6?m$xcP~ry_K}-b=X:Ջ}`kݗb_~s(v/žT ]}x_Fz=I~v_7^S{##ֈH%[:Ӛ06t4 oo{)I; SW/NSS@t<+Qq_ՑVHHo/ONSlT@|HT ⣼vGyo/xL'x{yԩ)H *>۫XUHnM̦  j~v8Vn{pU@|^w|q^`>2> n55ٝgvonG*> .u3\mϊn{ Ugv߼|fw*8_ ){+?bױ\<;gyHqwtjgz!+mUG{{-mrG{UωwR/1(,(oq ;"`9TWvswų sx+JDdQ.Y@x愲 ,o+N糼\qH 0>;_h(LfPY@ov5:SZE0iBV`j  2s)LgwVXp+Lp+L0[eƂ.2Ŷ2.2>nUfQXe^ XX3J#AB-FPKZc=bĶw LE0a"EM#x0Abf /fİϐBl*"K&A-EpCmR[ڲT[".ԖBmqƃe5TT|jj"CLME0.v#6/.b[d ŦAsT_dV_[/GT8Ăs(T01PIWG-Fk1O"1*_7 1f1_c 1fucKv1\2A$ Ę 3!_g,A,W5.bPt.]Q[.s] H.bYrճ'fžUjϒ"%A-EpKrܒ\c ـzR`Z|idPH.-E0 42A( uxf L#Rfڻ'H#]!&`L!{x9"V"% H![q _R&c }lBE͒^`NVcpׂ"v,cV.1A;c|1UcvKq V$c Jc~"yzc^"& 1"{l;7D=&[D{^ c7d2l B6!T3AB^ ŋ11 &K>f*}%sX*REM"}^)}l2;6!W rQŌy9g Ƙ1*slL9gFcr%8f̛WČ^c:E̘  nj 1o4nj ˜1A+njYbnjQy66SEʘ?"1K)c729eǸHwJ1A6v< 1p] 1*cic>QmE6v,SRÊԱT2>v,S)dSU42AF6Ruvq 2t M- i9d\t  .A[tM.C,z\$ -.R= x of{i,G=%K0`m h,Z:~o26إjl2X<\ /e[7}-olkYwj0XbG}ah/Nlgwe0hfX-b$gC# dKeCf Y|t2V--6JŞ^e/ŅeVv}neVr>06lb?~*C'N6LC`$;G M,^K=UXXs+i*l,Ur8&Kar岃e/y6  U/]e0qAʡhZIge4la]W+m%U]+v{VY `ȱae0f%J0V UcV=Url[̂ʴ]yVn6L+eϊ-lY/ice:an¯JvCZ *A}AEJ0PE&}\.|*'"l0hNIFoJ6ZS0{a7`^?_5S|{^zU *W%]*W% L<*Bo%)7% W%W%XD^ȫPU.oyUxU*w*w*W%W%`^y-JKë0yUxUxUxU&J@U UK^:^ɫPǫpǫpǫpǫ2W%`nyU&J@ JJ JU U *6e[NppqNJJJ`rCN:NɩPélǩpélǩ"T vqqqqLN"*u*S% rqq\;U8US%*֛-JJ JTp,^ev_Щ"pʩ/TPǡpǡpǡ0;T+;TCP׎S%Xpz +ceL~,-+g`/L+XbJjTʱ!X"\,iaU-\+)!m+ukq2X7+v+ τ»jF+,7 cXRrn-,,>a&cb ],Xd"Gl}BKdYf+rNhZBfwNc!.,,6\YdTXYd/_,% ~ C I-[ OO/\-%5 |-lQX\63^3.T.c줱l^TW<%i|~q+GY8`qR< F1G9 /Oco,H b sL f1g(Y̹[!ddsƫؖ3Be1G(hb st P|yur$hIl!<^P#QgB,9Ŝɠ#3#% 'n8Q2jC2@ldQPOܑqĂs,A /ߒuz]YWulN*UA-UGpKRuSu/ UG,:˥#n;Aݙй33#Ԝ<0:b5bBYl~WzJ7sVYϱ t-GpKqc#W8wA G,9b'UuAEȹf{q]:*`TqlYT{7U⤒YŹ{[*BűnFG 8ݣF5G9~us&*΄8^|##߈e;'n7Qt.Le,b2 qul9Yr SxlO̪?7{#UׂUBUY:ղD%cQn+\l r;囟zx򴴑 0[t{1`0'n06)xly1>kf|hy1Zֆc5\2X%!d<<=%K)3#3O |+$[&[&CSd8t/nV:\?t?Yt=YLc ;ъ!O7$O7#O7,ƢCCjVjn 6!P\U:'ma~bP<ѹ[kh{yx?r h 9g$r,y3W_4"M#Tsg/N5WNtjOXx>|xxh2&&a <\`4ɡgxh>< oo &sʡs)^s?ŋssɝs9[*/|Jp氲FJ|1'kz><Օ}3\W<<_O9 C? 4T4T@C (Bt.v$A$ @A(4PLc&X.5c(bfu-fXsvbw5@9D=FpK̢x F .do6-F07W/T oR-Pѱ!Y+$L(8bY g~ܒs9G,fM BG8xΜԐo-FpKM*TgLԒmd/=FpKܒmd-F06(JLKpOܒk(j5[r`kB%7,fj;[B̲amBےoܒoĶ k[:Xo-f=FB򍠎|#%FS sLl+HmE%Ҥ(5A&Ԭ9H- Ajfu(bԞV^`e_Sr(E- JQbޠbځb3#c&slXL,6f..j3!ؤ[lز V @;b3&` Elj#ڌj#AV #ͱdT 6x? .7>Lc m77knd'̈́n#E0mT2n̈́nWYh/9d 6*66Ŧ l| M*l6&]l6b{n^ *5^WפQ-5lI`{M*5dפ^jȱFF/Vc(jrVV3!v}|0iR&uja14b? ?6D3LfW2,ƢJe۶ФF”`ЬfB읱;c/}蝙xf򴩼3蝱ɋޙ g&U=3~y]~w; m坱;K&L@Ig߻ zf=3ǫw&}ޙ/39[/<4S=4`Ф*5C3? F/M.K@Uozj"OM@I!OͱAI5[3<5IgOMSOM L 4>䥙yhbwKOK*n /_hM}4 }4~qt䋳&5|4FhB:>ohB{yM`3oH gF x#ƪ$T2 9^B̴TrCtSfZ@-!Gp#3-ؖ3ByXBfDipcZ 7֭pZ7Vp!xOp#%ff˳p3~ZFƇA, D0 7WB 7QæV!p#̀ ƻM*A(ˣp#f!xXIu-Unr(Q%pKF&̹hυ#X8$L}}M+K7\,"F K7wB,)n& m,ٌVYWJٱbc}Z)6v.Y8̒E%ܼ30_*Ưn썧=_ {K7(g!*pRɅCBƖJJY],^7Xr?q+'Lgp3!ln~YlB_jeזBvPY>v 4İ0Œ fJM*.,t!0i4[=F06uFlKBP#% A ^ Ɵۅ`%/%FF 6v\# L#eos!Ԥ:P3!hӎP#3 ƫB j東.E >gт!XE@K%C\sZ*мELAhǒ1M`DsK0 @4^D{xZh.V"ǢDhdDQ.R58Ѽ"ǁhZhoZ@7<m26!@ۼ6~\ &gޝ|6#4]h0M;C%>`Bo| a @z@[1h8-u:sZ1-rK""m:Sڄn}&!B0GrݺQ>%\Dywr> ԭ~v,CY0hPDө@ h hSIhʜ $4{$U%"mqqi%BZ)T|Uh˜Jt4_'0mBfTfnf/U.Z \48"-h0Mf?\T2٧*oE;h޾"-Ղ6//*'a椥ZpNZ*r/4K;̹iiΘ͹i*r|bi.M;&M˹i¹i 7mB(vxܴcɜ jқBJ 5A._dy/Pڄ0=MVir%s SDUZ: G0qRhчhFty4b#Og=#`0L[-Gpˀ#To| jwM3fN3pֿltn9vqn-8^ra Խl} ܲnYrw,9lf7|ӓ#nyr<9[-O΀{-O`jyrמ-O'Gp˓3'Gj[-o7G0xs^ytR5أcZD3dM0ztqTWg%:BGgG褂[aj9L-բ&&:;SZgG{vP5ٙFOS Z:C u9bٛoV)9vAͱS7o~L=9FPrѕ#]9~—Cȟ3!:/Gr|ʑ/pyBOŸU%αOTtOG tFOgB`L|9B?8΄3.A0o -7^cLl7bOn=UmSh mnfj̶Wl7bv37fx  v3/O ljm7`/[` g|n mwhA`mvOF_Jvn}v\2mRh%oh夰ۤj&Fұ(6jll6f#l6bZ6l6[6`k&Բf[/=c5O gb08k&|yvX/Te35^8j|s5jxjv<5bsÖ́K^C 'IF,;j\8jYT9jR|fਙ ;i}p'͔N5[ਙ;i䤙PA#4-`v<fnB̈́9Ι 䜙:fc&33a35pΙts&3nn9hIJzA#4Ao;s&HY9h|?(4ke pT8iR]IJ.40vĩ4V2;i>VN*9iUG܎cs]f ̄Pĺˮ e,meYF2XSG02c ̱dgQяx-uf<x & -X$(w`h&t.̏bQW(T0&q,Q0H5BFP'M,K4>,P$%WR j i>,٤ ld#%"!B̈́@'QH4>2E"Z*%$L4:f|8 iƗ3f4sHfZ0H3džK4ǂQIU.E!xT#A,#iOY񥗥{`j>,A,դ˳Tc( 5PoYA.T j|FB j$ F& A(դn-bϼXu-[ XkV5~XBbͻĚP"-[H#EDfB,Τ:8#ęx3(ΤF83(#E\Uer(BQƯ^2~KrY'z`g&̄@0,"tU"Ρ3!_R];X_LKDSh0X/OZh0d`V;%i0b%]Ax A^&5ou:2!Z|k,PcۭXTH,%oO'2e,de fcY..3vhv,ͬl-ͼ`5f>(,YoGfil'L0=sofaY"kQY0N7}@fn6<p1lR/!, 7p0XnCل lBj6~fC[ B3Ʒ!, 5n>5 `Y@f6!1;!3af"=fd5AP qf6! 1!f9l| C axY!/u&eZXywe(вc^vu/veC ˖`N/ŽH/2C1lݼy]61_q첡e>38, .epj",AZ(R˼EjaJ-cZ揉"EjEjY3:CjY@V6N)SJY~9lĴ QJY@Rv#y2*N+KsZW&)eR/)e`t2N*r:Yj<dThH%;,9N_Ҋ>QJل(,F:YNfc8, '3L qe叜I6!"K, ,"#2dFQdd"; aHfc Y@H#kCل0Lqǻv!dB0llKV1tE ]#]rz9eL%6o^[^}zb&4ȲGX_^o?Z]tś2e0XL"[D&M.'`z7p'`1L%sK n/N )-~=+-V_4xu _K1jb2; =.3XXJd6 K0lr12/ pX[}D>`"-7{[R[ }L;ZlhEv1f9\M-~j{eDCeGmׯhh },"=,{<,uς%vG2Gض"\+Yś^4+ˊ7+V° ח*G[ϭ"*Gů C٩_٨2j2Ă[%wg,Vb'ZW,>XNz+B6ٻb_XW\r97)*V®b#J0 fR,*lu+B;ƕa֭l[񵉣|'J0 ϊPʲrʡ\4W$vSU }CgÊ׀*bЭdwdZ96ܼr,L,)6+BJ~YX^Ƃ%E-,hgv\UvEZ&nfv*eBbIB.ؾ"+~%U ,z>? Fj4YbQByeQ h {idVi=F04j3;ؖ:3BV uƪQ3C\3^23s:s:z/ԙCgJ3:#ՙPf͈amWgmƇ MC0h4ǒQIVwuL52>BNfEFV#fB-F0j40B+4HѤ~%fBO.LhAm' i3M0Bͤ"mfB$&Ġ3BB K-fBl$Bٴ,4Z(0a0+0^\(0+SR`+06؅](0#Aؽ ̄PyɍF%ugx] By'ef%U>T^r5XyjsLn)/Qyʋ"6B) =+0XP`>/_XtZ(1~BI%sW J1A-EFpGRd\(2eEF(2|[ROLE؛+3 ef4 *"aLK2~uTd"XI2BMF5kt%x1`, |L愱T2k4PrUBTeÌc50LSŕٍQb`Y'je+2lB|Sjٱd/Ks`:u(3re(R-8DŽiyf]6%CY@EwdM;if[qf[yf1Lyaf~",f lBX3k*ͼh3K'Lp+L0^Z1gb39̾`لZg3A3333t C1+ы<g:gbgjŝ Ƽ3A3xG dm n 渳Q{n.Kt xhfXŖF0zjFPS3؞F0xj&^nsE/Kc]^ QlK3FpK#nyi .4޾",ijUF0j箚QF,k&rnjsfWv `rZf hzErwM@i%fUpxFjn~FjU@0jIsẄ́8ƉgM3!t„/`tb3fAnC{fU+.' d3{rLn%}觙h_hlT.{?\4. {2{RӦpB+U݅M7fƞM覙hlmE. v__.evx3i&.492iөp[\5]57a WnU# cw`{-wF0 BWFf2 ]4gEsMƞFpM#pثGᦹygX2j]5 W] aЙ;8LPM#0iu4b[nঙh sd=3Z0hfc4n u\4%͡=nۂNnAƺ4㇪ؖff{nঙw`pKnk5[w`{˹Xre#.!>w.bm3!v ..{ .*6lFnW6)6..Ve=.A\6Bw 5[ஙPU#\5B7 t7M@9_M#4Mw0iMnAI "7psfWĮ{rLqnifٗ\iƞ/nyivK3!A塱7CJnyhFzh^izh<4[{6fBXΤw&3>;ex ׂ3bό{f(gƟNg& CɅw3b;sC[xh~/<4dKF/x- /M*4qcO L4>K3Txgg;ޙwFl᝱W;s̱d[{h|C#<4_[v:w4ǒ,ɽM5,E|L\fvНI;SJ3m3kF0Z3)t񳃭AclB{Ư=#왂ؚYGߚxFФL, ’3AXF0204e;ec,#h2b14eObXfXF(%gL(qM95vsHgvئk9iqHR\gBk48ĸ3rm #sl۴9gϱqB|LMAF(x\1{-11[)OGO6`!dC$lǃ`N6DɆP:Yߚ_bNΑY>:|!O|Y>yLA>Y|S`> Ffψ iVe8(&ǭ ('A9 rR&͑Uӏ̪Ɇ&`΍`4mxI#؆Y5:&0klà;)'L6`v'Į$&~qCXD90*'IA T?mjD5,&Q#؆X-iS VJhRR$~wU?M`VJI;Y)#RG&)%J!VI`׆H!+$~Bg46 `uVHA ?0Bodط*$b7 ɆX!9:$ꯛ=zI")6GG|ll =Rk#~b`׆OPG}dCwGIФxs&$ YgXTHCR# HA썴aqVAbyQ/ $;2H?KH")쑂@9V*#TA i{L ɱR䒜#l.Y+-#0y%b@,)?A)S Rɏ<[%}dJڔG^X"xdf(r˦hM62&%LɱdA> O R'ǺR'ⓃRA_-lB]?i{4Q'(mAFYD+F:q/d/E)P < TEWAV׈dwdeE;+v'Fi?ɓFF}O"/4X BuOΓ +>+<&ŗMAe .K[VY|f{]Y|gBK*-~NrZΑAnjYk)}_{Zs̖*.BO@]r{/X|isHNO0אՀcX0בA:nkȎ Ȏ;ג=j4oTKv.zbo̧JdAٱR\K&k @0Ԓud:_C-YA\G6υd& |\Gv /oj _~C_,֏~龭׏7 >׏4 cUofnLԍ5c~q͘?f ~ޞP;V}<֎ H%bP?!+/sX[ ~JSXAP3VbO1b<׌ A5c2CT7N>psz{3 cNjQ5c0Ԏa k1AX;ȵcW`;^Ԩ~ y+kv-׎ 1AsX#֏ 1;"'>&|\>7c:q ٚL K1ԇ^;mlor#YcIo{G90."8.l.?.Ō,n:\Ď,E,Z.F"xb,vfM,#E0[.룆o\"-A^2^,`4#n)e')-;jcv [|ngvbZp[ -n6-mhb!V1ZjV !OZj{j"hdY.r3-~'ۥ-.>`KĂR.~Q"lrgr\O\ "-A`4[?/Oh#ld'ۥ \ژY.r \ZgENs \re lv<-><\,E,Z./Y.md\M4ŒrL5.>3|o̾%ߥm *X8& "h$FEDtcu^M#E01dEދK1 9C_` 100(0α#u f'7N tb|Pi?Sb"/6 Rb BF0PAγ vUTcF91ى닝AlĢ#ݘ&ݘ̍082S FGF,.>1gXtd##9### 92s%7 vb Nߨ؉{N>F'^rb#؍_эiƴiW81#_s,kpcMn92:2퀑#s+ܮ#'W 2fgGFg_Q54AlGf923_>23lc/h b{M|g6LE h-4mhߤUV[5_CAVMA`ӜS ich、]S [5tɪ9ZkΑѲ)eS59uf˦]#xb׈5 v]S[5 V?@GVXj Fƾ=FJ5m,BƧ{ J͏-55mdPk)aaӎ6аĆ 6}(BƿL,l`6ΆM8 6mX׈F5-]՚߿]IJZY~,؞Lja66͟+ .1,+5P1#fX,k56j66fKda .74aɤ@7#v͈%kFgifQJ:#vb,v$Έ:ɏÈ6ЉD#M nK&z_li~k4mXhİDeĿ ˿U,Ͱ7c(XfJ$i߀;? c 4(Ј?c 3b؞y];3vIw=Rg6٘2~OƖ1h2hɈ~nic`1+rϖݘN{/bPĠ :L{+́I?"M6Ͼ,v/boi~ Ʌ #ŗw/}]BF 0}/mlfbĈ{C^L~E,+/v 㥽"f,1.b]/3E,(/.b\" ~n[.bPr'Yp\;.׃~庪A6"&uz؇ .({-?6,k-6,J-m\e1䳈IZlzCb"tZ|ӨJr= 0$s - )h!GiIQ"dD$;FtD(Y,zlʡxQQV"x%'qbC/'FɉQt" FCf =O)9FY3sܐl!Ji#Cf8D".l"'egHPE'1; IA '09i l5m|Bwc|zI؆rl}P cFbr"\=7TlB؏W[_=sXsX1\9vʱzc3V0W?cc\=V TÂzlCX=V 1?@rw*ǎcmT=vd~詂  ;T-Tڎ1?qBP=ipXڜzlCP=kx)걇݉z +1Zoj̖*UEcLEcF 1[T3fzon̏^;SP7֧uc j6 5c|uc}&ucCݘOcT7Afnfn uc甹vn}ڱ C؆ņ|X7!c@ucv̵c~tvlCn̏*ԍǀj 1BݘߒBݘ_nuc>0֍m6tǺ1_P7Huc1?X7NP7ucqucºucԍmKc77ֿN1m{|\<3S-c}X8 pm Tw .kS± qᘟ%T8!l6u|jW(TNP6&嚵_bѮv kw`VMAhW&4mdit FF`i+u?ӬvŎtf fƧt34ȬZM[ j|LNs,LZPjV#1,ռ},<R+H5?6gj "FHRRM3J5X)H5~ R_Ai%2 0& 29gx$,x&5L6 U u 4G2/<-JԼ}dTj!)5IȠn;A3՚@)h҈3#fAi̔},(5FfYWRjڊqY֙iZ"5m`n6)b+6}dTlȨQYPPl|}Q VlV΃bFfŦsgզ Tla Vk@F 5~Wa=H9ɡ A3F,6(6_9tmkhX h13h613Ԣ'`Yn#ujmn#kq/tmπ)A(փxӶibY{ g!#SA) LqaR_ⴑ9Y`Nq!R80ozSMқ8Ysj㋀| M(̡C06w7L?(Jbeql'@mb0m~sl#b1ۼlCl~JFd o⛛ 7JN~(=Scأ<8!G7s`p΍G8v/കw~;4o9CS 7F`A_< ls`#s`gtl߿ش9i#s`FX p# NMunF781307~Cpo܍&{6b9iS_^8ā} l|B`se ܋&yLjqRs Q/G5gl|/D6mX&?CTFF5/u,IJ}.I/b, (I+f (E+| "#c96܎#??ĵhmǰZs-׷\ӠZ{vs`hI+~|؎|Ўc9߿. rLhbM`.Gqևs9^c9>/ rM =Ry,EyM.J^T& R4AO,Ekh'Q9`(G͇R4?\=%Rc ,EqPY*%hHJc _Z\*C3*C[0EehTv h眡 .EӕKE0=-K :۷uhXG  օhqBߓSNP&BEh~HEhmP!*@+Fg~ΊbY;N\|NP|K(>gmP|3\/ͧLh,_(Bk#cZX .Bk7],BkǂaZ1s㉊ 6U*@;NEhX֞{\GBsd,Fkh< hTNhz(FstR&kj hq} uh*:4qZ<Eh>PEh h@;Mh Mh̍hB!Z8Ehۿ uFguPfjA9aVh ^r`ҜQ.& 6i}lҬkNlԴCƎLY0 5 *Qc i 3_ Q;&Lgo؂ 5Yy41؃G0 5/CYtUiR'1Z0j5O?VBFZ&F BF4;NvzfCAͳF}hM5 ܊4}dlEWZPufFHcϖ>x> f}n]4fLLAEL?a6#6S 2[Ơ|Qit92vĂ6s gL<3>23LAʹ6c¤ʹYi#6Fƞ.ns&5A 8h2Nd1=g}de|`e bM5ABMFj2M4Yi]<2o6BُOw"͈eiAi0J3XI?U4gs ̱clдiA٠!4i; 6h!8#I2i BF4~XAw`дB٠9FF6&M;`SM> 6i|ɤ9Gf͙.gF/FM}fO͚ب[2j޾cl}d4jQcF2j|i#QF_FlѬSfnY5nd%FfM1ljΌ`42iI 4FLd٤IL߿`Ҵ) c`KL#Ic/whҜ`"?hQc_VQ#Q`IS &T0ilҴ٤SL F"5u0j h42iIJIH04XA"M1x4m؇bm=AGgFz4أiy4>4~*XiMñL,4bS#?_[!pk6n3b4bA?K!iQU$ h6qh MA,<{RnvbfY=!g6Jgh6; ~fCkfÓ0[3_dln#4яlx#42yмl-㇔l ɒ L"222f[מ|ۯ5aF̆ٚ#k љ M, ӏ vlǴͣ!cIvL;Ɵ>lic|ւ-t?ٖiV6g6ghkzF5!flɚqf/Gg4Кyڅؚ̆'،d؉?6!fδB/dѴY"ESЍ왶cl~{Se{ 9EEahX,Т[4>`~|f`LGn5k#`F(Yp53s20Ĺ,̭fNbR,SЍA8F015b8f}Lqcn/ȼ RB mg2(Á̏<2q#jȈ214 dȴ1i+92o9 ̏\1k#s@FƀfA ̟߰М#Oj6A?bBPPcv1ԴƏnjAMkXAM3כ?50 A jw`j\9}<705f;r);k lXw7K;6~3S`߯QنoX{;M1ششip`( 1Yp#x lA`S(Y,< jbP#几o 9)rP#pP#ATs!hC@S כ?!zf3bGQ0# 6āoAC 02kdȜs`G fA0S2`\mcdjaP[AM:5b!YUhblm{&pv@ٱXfG hpzX,b[l̎Ψly7yfs3]3*6Ugmt|X.:ksN r jugoBۙ(; v)Y,V gvQQY%3316fvLruaW}fva5{^Ov5 a/w~sdBf̎%՗3Klaf7Q0pedvfog1{\?K ;|/`f ڸ_f+ԗ e>_./{_o_6e X(,O4޲C5Ԗ.l\(-k뚺ˮ+U]oe2;l3\R e}W] ˄`_Y4וS[Y?꡴":|XYbc_TTX)MCMfl3PJ֗׆6}d~ udvmdv2@Y$*Pfv6c`ɘ1G7T24SڟԡhT 15]11\2fƎ11\1f cca pop/ٚSX_O;ƅpo6ýb/Ԋ:11&fS.ՉmZ^wwU FieMP샤A( FiEH+MKʱ2$#c"RHVYpj1xF]E*F"x*e]EЍtA#]EpU ʊLU*2 JA#]EHWYLW*ȟs"A|#}e3}Eg}>e5A< XX+0XsKyi,G"54KAaF}}Wv.}x@_9@Ace-FX|1.1J>&AcisFϙ5?׃3h,xA> fm0,v%u$&nIgfYRh,b'{Wb+pϘDWL=cmI[)u?-HW)5?6Ϛ̚_+&zJ:)~N^62h*ȣ~1#me3mED[ Jx {B}ED_Y,+F`WrG:`YČtşAg?Qg)hh,bYci5X"h+`Xz?&bGbAc)h>1AO8V"A#mEH[}bXWĚ"vi*YSYg{WT}Uy|6T U";+mdVjFF}ŧ Xrn0;,mdX|bC0X<ccYeL62,͜Aj1v",6X-4YвF* LJtZԲ^gKZl ^Î*-ljnwק`[4-'~X\ BE-[Vv[Vhd,8-Do62.Pqy (ri#eK<.').y\6W]*|]aCsLXqiGǥ\3E0[.?| ="E{%ŞIuGu̲ۧo]NKA,śL;qPu78ҋ ^Jϼ7_"&Rlف$l462{0>20~ل*L:0sΕ621m4 740d>2# K #]Fg_23,AFFF:4@96.M{FIo V$/h4_b7O&MYƯBj MZM~&PSd=q{2xńYmr^|8x ^|ff9x4/g ^|d^MrҶמðLL,֞ 3A3P{Vk/Α'5hՠ ՠ ՠ ՠ sdCk;XY-ڂghGhM֢ բ Z4ߟA+PlE3JюUrcQGQG`H+Dh/7F^>ԈV&bMo킡^CZA܀{7/j؀]܀&~SZA|v6Dgqә/Mh:DMgq7 gAYAh n4'07j4f(bF3?Ѭ-:7UFhOhc+4lCY34Mfd&_xd&35^QSw 3R]L4K SdvNMf>27 a]hV 44FsnlV7FbL4 f`ﱩo#`V7m$4 :7 em\\wij.;C`vMf`&cѬfѬm &v8B|h4?Ѭ l2MfIפL0J=fҰlg&hg&xg&xg&c 3ЬL0 3A33cvr_{MzĎzzs#?}kf饠ϲK1,ҦȒK$Xni#S% Z bG 2KA,EWq"leo2K\`c,8-Ҷl8.>r]|ǂҦ9 ^T> _ lo2RР`^ LK}- M  ]6s{Y@~)?bsF?F$Yy< f n IKL%P)%|'P`$ `έd2̆I9sS019S@)x l[ %ŬmdL,ɴbI ̆$sd%XsdZJLA(|q meVFy f ⶲ6Gf4ieY`N̏H)e0eeYAeALA,ǾVs L?I)>WfYiҌ_2fssdh bym䙂L,8LLA(qvf|əy|ݾ=љ)]5ELAʴ͂+S82x)7n̺f7Gf7nLAtc;pc6n  jLAj|Rc||؎I)Y)h>V| jb/F6N|r!?S01ȟ=s/S)|T0{37󰓇60{3/7S{3o*x3NJM9V&#{Fi|Ӵ9Oc>MWS4>MA>MAةH>M1N2?S-3g3Lϴ){!g  gU#34g < oq]v î$ɟyځ# f#Jf|i#7Sx3/S)/Sē)ٓ F02/τ1S,3/3 L٘i1S3`EHȘ)y0f cfC%"c 0f bcƏu0f)h` ̆Ȑ) ~ 3 LYY&-:-G.?mL\åd6.6KJ]6af8cY7BIJHV6ÁuE N(EeCbhPFBr qf0EQ*XQl)BQ`?.F)0}F) $e3^Mr~u]NPlsfJuIz9(_iD!&y]oi: Ibbd3A A1/Z^C8 C;,D!Ğ!y\Oac3cyGb9^)^Gq0h+kvz~qX`v c\1~B/D"~Dm,"v&<ĮHC9`*޽(:g#h4'$`H#v1vG蔍l#D!"SA)`~Q A6ه.G0 ?Qa$fMbraπz\yl4yu!x]=}LQoc!rBіcX@6чmpaH r>l0N> w7T &s-X-X+k|@ls;q'X[6.W ju j0AX &|?r r`6 ~P DžzLƈ`k+@`m`kK`}Q/`{M`Q\F0=^0?^ LE0P;V V/ق'aV ߐ =a?bV `W  ^0B//#z V>yk#c؂BF>o ^B//Yk;`~ۄ^blAWcz aWzMk;Ƚ`6LLL0} fwT+ 0_bo VX  y7\r .fG0v].]=`A9EWGf/C {i=`r ؏-*q ̧K]`AXA ]`q"v" .0+nSl"q?kM`M`8&0Af"0j("620'TFBs!áV.2>0gLׁc  7Ne`m\󯡩;JTOIYi㢳" OׂAW FoLJ['VW"uƂ0G6wYČ|e"vӲMZKA,*l<Fr/B[#E0.àm;Np\bmgm\#Uu Ƣ>2~Q4${1/flj ҋ ^g`,;L[)6`RL3i wu> ,"̂؄'7Ra. a~Td-QaXwS 1YW{R̷?g yXXc͂L{!a/s!i2mF`,ĆCEF0:2~.$IJr#&ӧ ̱8OP#2N6vfdiOLfASoioAgj(ʌ=҃3c/AbPSd_^m0v 13> vglis@h^ihG#D}_,4Pi;.oiѦ:M;9i'k5J^^;85XGȮz>! FƿJRgѴis tl|,ٴ5J1;PLZ6}uBϦ̢6!;6m`Tmkӷ mckmٸʍo qҳwޯ׿47H'd( 6n֭W0:7й;B΍X/$ݜ#|D07u  embF΂0[8o*y8}o 8[BYl""Ny$FGHA0 8> 8/ĂS 8ʘh,W 6gE,M[08cC08z_08~ps@-Gj9m XZN#j9mYi#g k9}@= zNA:΂X7qMN08S7#}M!oĀ~sl5up BO o BFlv[zndA Fn>2j762h7Ƞ|\oI񑃆sf O5A4#5E f !Y)}ڍn,؝>H7> TnqMM17 TnέzS*7>WPn զr;*7,Py_&IѽyGto llmA`'`MYmmmA˦hlo_ٴ?nt FƿF6}гisdϦ=y6_Sz5})}#fj  0h#&M#4ؤ]f.MAh٢i;OMAϬ獐K1y:c"6GL^Vؐ䥍cL.7_. ۶P|.y#cؙy䥠'.v f`N\^>2$.U3*`"-}J\lh<38hǤ-F `NXp¢'Q"3AE0f,F`XhHX|Bipb(֟qŴeA!m,mi ,=gHE(u00qێS_!)syN^(.b8ww] E.~ 7 N]|!uyʩԥ͂S;.~إ [Q ]|9vı .8vc1Nb7]ԥ ̱2/8|͇o\r+g}`b"`# ƾ Ff0826G`<}db|dba[Y/g1 y|ucٚX(1 ef\jFR̥fmd,5RcKJ,w`l9ksY=j93j9[ph9[!`n9!7 rFƖ3Ar1U38"6L0}U-gl\嶳w/n;Cր ̏i(7{ Q8{*ΞvpY*ꫵ`:Ugq,: \tfEg\t(֜!Ԝ 7kfAY%,lAab7ӧXo&hTo&xTo&U0֛z31Xo֖TLכRYAPkVԙ5f.:1Ƭ /oaPc  5fa}ZC}ٹy1?K5fƬ //יT_fWI/{ye~E22P}Y1P[Vו M+kueD ue̎)%e;`YYAXR/[w+XQObe~Gᒲ> .){J,) @0 \V.)%e\R&K|g<=l͡)󭇚2>2;L_2R2P 's= '9~=B?zL7sCY[*n(CC/UdA'ٱCQG2AQ[emQ+6*)}UU=򆹬fu:s<)/0)4m*)4MJ6ԙlhRVIYن?3ǪҲ CKph޶i#C221rf6 LA}Dn*̙mlxl 3c;3gfYfO:tg bgƯ0f6LAٖ(2b[#-vls5#xdlx`lvblxblxbl>gg6eebКĚ0Y3 ֌,Y3ٞRhlfbf{ N?NH)hlvl6٢6G FofCҲ OJ6{Nayن&e&afC2̖ ř 8 ^2cg|dg.ř 8[męcBٚC=͠>nW {f3 l]H^,2Cf3(ت/Ɩ$h1>.[1*Z,[1OK1>.K1o(1e#揳,z#b h0A}A7*06,0}_63]IJd63\,.w%4]VbtyR"<1,qe9X\w/Q}ap -bkXld h-bb :zQ%E ,ߨAzRO`}&,]1bdy_?,Ol泾R*zO M1!/D1䱈azr}9A\=,ەeDBłϲX6[{tWĠҶX\SͰr|rtrs%Wz U1(hl\/AV *bXUx"T1h *bS]Me3lrR2)z+)v F > QĀQ삒b##/PS|\R|\RJRm:8)Ue#e#E )ԙ(BYG 6](aŶ*6Ql~ADy^eP6.i(bBmpO1 cGfX7mL&D %}~l\&ćd3o ^Bj!slQ }O0})rd njs0çJiFA1FA_|f!( ϔ\E m^"Ëf' A_`g0F>0gnb9Ƹ֮ akݷIN{2*[v.?9q 3>E4 < 2@0u=o-za L3a90k` 4a \3DCs9™  @fǝ }: {ҨkÜjz.>`62Eʅ.b]׆ (@08Wx^}`<$sУOScI5^mX5^>琄"4 )kM5^okl($""z ^/ ^}׫^z AV>n2;:n>2vz Np wz N/6^j24{B'n?C lg^b˾j^rςqO54{M^3z ^/Zev+|Kv{ n/ߝ^rC ^7|\~q*25`lr@V2kM!SSGFS)~9 903] /CQ̱3fY f hG#=Ѭ7<F&7i|< `v`/iLYYopYyڪƏ4PM:O7(bW}jnc,ԴA9b k^vI)H9>5>25| r+5Xi;r kv`fA,蓙5/[|k\kFr 0A(մG-+I5a_D#þ;iL#e6WilI2`.աL#+ľ|di(PiL:5,:n a3H5ŰL4~I-c~,TcoCFgi,I5m,մTswLco8&+Lu}\Lu>00 %6 aSъVz{ZLybښδ-f];Y1/CQJWA% %yF5Fʰ`pc\ّ)ݘN&?AY/ r̗c$Z((2縤0gRh* *1R#A؅?A񓍕R JqZs,+6}شQ#b#?Q TlAeF+6MAJsiTf^TPJ0j5 j5NS`jCZ1EkYzMA:"M HO$iΑYi#O(  ԴYP#*4}l'`BoХi#M+2 iLӧ2M"4 2Ҵq٥. &M64X wJs~v3#!)Bl}\,ȜS)8m\q%b8rf4Q⬿sgC*73c6098ȹ۹8mQ#+9c)1N[quqֿ [pq|uC^9sF << AN @aw}v Ώ w9йiā t@ r|YC{? rs;6 r4󬍌gcyܼ 7y&hy&B`ʁ?My,A71un|9CpFNƦ}v;rF07/_ n67ρ ρM1)?9YPj<5L v `)iS` fQ fq=C0#{ fq0cP)y`S0f̏};-30%Xf1v&ecqۙ ePF 2![zen&k~ƈ0NPnf(D1qg`q 08cY_&a fb #SAބJ3C̾>F3cACY:w 9~*3,Xef$6 &3AdVG07uMfmdj2k ">.`,20W5 &3_YقCsd&q}h2;Mf뛂`l2C-  " _,TL IEf*w"z"3AXd&̾EfOȬ*̅fw;O-.4˅fm`.4Ņf /~\lf f>g.6fmǰL郔`(6;Pp7Ppwz.8g~[c\pv \tV ֩: ¢mQYAXpH*8;*gv ,6Ef osY+b3;XlVmhVd&PdVcȬ}(2+6f$ߨm ̎ 3_X`G3A\`fo \`& qE3A\`f/^X`v4lC\`?Bܧ 3{ f/+* 3A *5X,msYa 3ufB31Xh֎v(49|B35B3A\hf bKfb 3k>3AgfaYl3󏏡LcY_&3CXf&aYۛPff(v .3Κh2]feֶ]f*[0/΋@R^Đ"f"e3\G8. Ŏ21lfb21 l&+"A_2W*W; r90Vmq劆1}V.dpVl瓳rE'ƊIXU6S9PU6,uIA쑬#Qf < $o; )ܑ9Vܑsl!9N%1&;$ &=6'&f$$ U-*%WclY-i[R8%hrKY.i0%]+FzqI39ۤ L3{&6Z&mhl-,uL|fNϿWT`,|mJ6b*2AS$Y,0a#-^'[ȴDQ @FW`xmk|CCc,F1>nb aƽO!e^/;1LAĬ?|ٲ Pa`b AÖA|#C󊃘.XkeC뗱/CoXƽOsXOտ:ߪ V.s ؗ-/R0G\V w= Cc ,8="bLV X&[B ؆1>2.0_*;GV62ւ-{xb0}|ߤW*ts)_ }`m9774j<]`/[N*+[|o0"0AfwPsX+](ْ:0AV ΂O fbS1uYF`G9ԄY`O؂(5t/;L6'MQM` ;.P#CcXߪwciX[抵a}d ;b> f/\!&;JFhxH"}d)S1P2FƖ1AP3VP/q&0vj殱n;f#Nzrј?j̾ƅ1A6[1A7S cm9f6C ey+|y7c| c~m aM j[*2AEfaY4_}5doo5AsĿao ~^,.v4 O~~X;&(VFUّoo[|wޱ6߬?YEKtgG`]l?"mA0.w;WF?YaK2.mK1l}@X0^v cw;]cs" Al6 O\GsM?l'?Ya4^qWmRI&Al3"< R.b'}9O+K.xƟa0aڜل[10ӦFL1}l؅?e/?591v2;3 <(f`Ƽ#?meO1~Ny6c̘>212 e>21v2#̘9fL'7< O ?1Š #M;F?qEF'Ų#}*0؇is|~a͏OĎ1ŀsn̘fC`KH,2(̬0t$8sDzYQM14h;2h uM  `LA̱.*ݙ3Wՙ6 :Rg:U nTgĀ:SH-8d3>rf|C6;J`͙36L0f5 YuR3AF(M+f46,sFs<*9[0e6ȳF0d7aYd6M32g68 g68isFg6~1i}l Ԑ¡L56$YM+jTFg5yn3Gٌ} ML<֙ L72?LFd21=fm}L!! i|!i[W,4O[(7o6DfzBz AYAXl櫇fb q3{\l{G0m!jv\L0WtfXm֦f0Tfڬo*PY:|rO6fˆݬ h5 m[Val5[}szy0=jV>[V-Bh5#ϭfE~jZv5RflCj!l5[7LfV/APنl}0mfpY*pY 3Ab[9=-f3?BVn1;-f}n3;VSYAf֦mfmfG6Ŭ n/칓E9=s{Y6k/l^G&l1+h^al/;gh/<9^֧^π^2 c{Yڜ6De>El/k7n/#C{YAZv,Qh/6Ceo- ޲ 2"mz A_YASS;̏4;dlO s7m|P!l(ks e %eK6D%e⒲6Gn)92_*j)+ ^s?Y#5m (7 † QC emlCQ΋efC:+ł S+0msH0)0rCTQ0bf[ 2`6/ 0/lY̗/`GD/>p!ELy"l%S0K0A I0B FtYe [Ayؙ@LAbP{{`^G`^ ba#e}YwbzlCluɱzlC OX /g\|iPنPoymy h-R6OzKAXA7zZK!ZHQfXgYS0,ml*6K;\AcAgHgY0,bŞ`3eeìܾ TmxRAaZ:Um62k-vFm#es>TCݥtlèKu?$AwiKu62.>2.DeCTM!\Ys2h.md\ν'E.NK1l5v .ݜ4PoK Rh- cXs?k.mo AsYsj.Ht,.~f^lYt.2\s ͞(lߥm"#ŏy/rLdbm{k6x/y^6ދmu^|NG_{{)|`^VH0z/{9"/˗o L1#eAYHgI_A0/Xig0/mP6HJ]eäA Fk0mYe ]H)AWvOKAf.ȂQ%_Rh/Y`ڋ/ k/%?BA{)td"L|#1_GP{{K{^̴r̂@{)t@s9.}v֗{6Y{y fVc ]0ҟI{sPws%XAwǀuiⷻ"uaK[L+gtjIO|)$Xb"6Qw%Aw{c]4Pw#̺ ][Gz|^Ǝr?Yw_s20J0PD:̸s"i1בQzu4z8MXz#Yi3Hc7zXcf=^=F1yc:x̚5 //[22 %c$_(d.g2בYE̘J3Xf.gyF3~yyfl1iy 5SXP&AԜ}A ,(-32:5ḱ9e~v́Clsṉ͗-6 a\#ל`kc\s瘦U<#CLP}cp< pƏ{gn6Wga8#=p˧dcN0w=a>05 aHB]Fe+E!qWï1F6 qG;!*ta ecB6 0SA4e~PX4pbH3B8 $Ýds=ÚqهƟ78y0G5{ QOmAq'e?فC`c?4dcB`36)c`36cB`8 ln`lq`3Fe˼ lc`3f l~6 a? h  f 8!f\\n;͘bh|€fnAF&/;.|2YA͗O6Xhw|fzJ9͂[A<2P28[XF2<" ^a|C 31 aQr#080c`0awYE]&β|Lt5]e8aW;u=m_/*Yv@cuUuفCuىsuy e AeYCPUv9'Ce縪,e>p,e ecUe`,;>`,k@UY5lG*s e~ReYCXU&cU{*Ued⪲u*k+aE (*Vep eHe71UoⲪL0W|***Uev,CUYC\QsE (XQ⡢lN*j2?0V& eבlUe~)CUYCPQv9!CU_PUv/,W.2Cu\]&suY1\Y&*.%T]ЪLLL0Vʲ1PY"̟lɝeU]&mb.򑱺LWCudBs84 e&5l@(.k JEeTTsAYCPLv9.l qAłLL(&b{]/-uCw`\~l(▲1ՅsP.)%eV֋`^b TN&fexg^Y.r"xe^Y.rC)ݖ5W֋U)`^|E,z/VdWdy"ދ ^ߔ}E\yv+2-)=?`Ɣك8\V&%/ e~v>`a4/4/ ̏7ك ,+ee~6fg,)Gq:20cd,-@΃Ҳ[ղL00Ͽ z&X.`van=yxFFʅrao\Y\+;F ] #]; ؕ ff0c s`va7c,91 3@s2 N vb|wUZ&vUZ&Jci ta sraZ FF;0؁s4O1/cؕ ^ 80bفp`e^m&g ( A>>0WJ`TbaSo}gF3F1 f2ʈF#q!&L3+F0*s|{gAf@EF}>ч>e#AŜ#4>LC, #f8x0߶у `\ ̉s'{ދhl `4y&֋nzubEX/+=Cen/``v> ]Vlbh Ƨ `6 ` =Y0`a !نSl'd\7V/Y1 ІSlzd\7V X1e]1vςAh;R, Kؒy792/ّy512:2O;#c#BrdKBGƟP#c'fpd~#3fGƗ782b;GFm82bّy4n ܘ$7wjpcƌٍ#G n vc|߿ƌэܘ1 tćܘЉDNa؉NU؉NXvb081~Sc'f:1cApbw<81c# J6b3e#g101JT@Qj?TcszPd|H'2ׁiM:2XA92s|t³63|F2:aa!s."(¯"1f,1Ќf7߃y fCf8A?<;SrM122Д|e-I02_>22>penГ<<|ؓٓiAnj? b^^ b- 3^abv.œyŜ^;KW߇߇c/F!|flq~~蕉`c4Џ~LC}qr?Ư#~^c.wd.ݘ1 fdy3ɛf*?F2 wc|9ٗ*27ƒ/O8 LCh]6e~(iӚ|̞BZX5sZ3fiTsZS5I;PZsbHm|ĩ<6~ ͘: No|!;6;HovHoݤ7oқ̟qV!` q ڄ8oB7!N q T\o#B))B6NP` u ڄ:/BuP7ugcv;+sYo],5DgaY wV5DEgc *:+Y(:[`(#SYA|V6IN"Ͼ|d,>B7?+hV0=| l@;DBu܄6/5q܄7lB+ i+ة_&7Mh M ^4iB+ &4?nԄv9mma7ЈKFh~f4?،V6͹B3ZC܈KEhġf˹@ i q3<7yffb#/khDc#ZAЈvyjFkB06=*4chD/t= hOCmˍh܈ip#`nD'ЈnhD͍hq#n#b#܈6 ܈ǂ܈6hwg܌#C3udnH{ڕv}pC!͏ߪ!`hHkR3ZCЈv9܌66$fqpC3/khFfO feI ib!2Д[Ǧ)mlI(5bSژ7,BSX4pSڸsS?Ҋ妴1 JWwܕV_J$!.GX5eh 6m6jAkalΑ 3q٘"5gs`(@k^wʍ Tn~Q(7иƍVO0+77cѸrclPnlq3fwش9>l~Q X۝ps ܜ;,za ZAԂV͗,ڌGN͏ϦMC+Fʰa#z  fMAѨA+JcG0j{;l<eFaAb٨cF@FMC+F04;Fʤ2iI3FfO[6iI#Mc0i|]Wgoz !6i `FЦ`2ilzLh6=goz ^4W&I L` fPi|W>`iw٧~>_ɧ±O#|yZ ^i=+x^y5g>W#xՈݴ^q^ML-h+4>c4_ViOyh/Zϊ]y4WMYֳȟ9Ο_ڴi=+1Wg,V́?㿶;Fʟʟ=y>SYAbo'i3v"mmFPf|͌ ڌ[1f5#ߟ`Qf4S2Ж3e1`,s~﷐41L`cj7r*s3BS*iM?FS}U"-@00cdLaBq RRFlh=1k|U(#x^27aw2V4c(#>JS ם=l5w`;߁w` gA82;9}902o3ʜ?̡ e|!qPF2~ 8MP!cZ0!i>:S.A_<?K_Ar}ŗ3/?3?@\c&×L _~U"t^/BW`_l%U"xxE Z.7X]|b`[|O|[|b'f~RaE3CR,l>1S0, q.\̟ ecd[ !=BE2BeiŧfĆޅ/1| _CS3c2CkB.t ]oBE*t ]l딹7ًU"xE*{^E*{^Br9WCcǔ{ZD1BWQM#{qx޲>oBYX,Ԙ]ԙ:^cPkv|n&qnvs2 v12BAJ+9*9%gLЦLl(936tp;*|2LΛPu/CcNrPJ[R dcd('kKQR9U.%Rq_R24Ndwx*%#oJr)_c5N\Mf1l*Ɗ9Tfl eVe\vL06 Z5 3A3`&h`&D f mrs͐.fΆZ 3AX`&hU`&]Aʌ]AbW\Ђ+s3\6Meb7MebẂ#e9H2Ʋ#3FI-82N̎X td|{#EFJ̊y!\02bL*2z<̊˦=+2PYifW&Ԙ@ihUAUfXeF+0bi +0[K6֜{ȬČLc/12(2בẂwFRe*se#2s޲12Y3 u沼_&A2+uFL03I= FyQVgBKf03/3{ $44XKǒ/Fl|w`l h&jk|A#\s9nA#d#%qtQSeƧʒ͸_d5~SgfFJrUفLƪj`KF05 ?BFk5AsDO]`j|`jVgfl_՜Ͽ'j4biD6Xhbqf3lBsF3,3$ؘ̙BeΘ9Θƌς<8s_@#v%^4 4o FJͷ$4YiA+aFJ9pf$+WL3(yZ0 3 \ř3>3ͬ(Z 3An?ẃI@#~ EyiH#EqDDH#x%l f+$4" iĀHsY rPJ" iƟHHctinOW"H#x%^4W"`i:jjP#y%fŚ?>05X;bo>5v[@f+F0 6cdlƜQ$> 6c 3 6 X#Ś A Ě7Tl| R+F0 6(Z 6I9 6 X3vĚVB`jfX)D7i>L"MC+FF͏hChlA3:#xFuFJ LC+eAgeF(3 *š92s9+uF,3YQhIJB3/94u(\Хz$D2MA(Ӝ*d@i-_=h.+C6udj fQ0sfƏ5OƮ_K`kƌٮ)][5cՌE`f,j5>0k5\5^sS@Sg7KzMA>z.$J)4Ƞm &ݦh f6Oe%9F)46N\7:4>J)LSh8 m7M4ڍ(A?RA'[0j7k=TS} laƗ3h6ADͦ l bLl/h6?>2k6d4fs{̢96>gm|<}\l^>2k6<4ٌI)5;X56ߪ)x^i6>k6 ^sAiM?0I;" jyah5n[5N3:=$2x:Ailtb7:Mӌt?%Hi4Hh􍚂P'} gЃ> j3cAmqs#}!fL {3F؛͇KόYIyYX'q g|ABq g.GXsq!4f<*32e!Ve C,#s, 1} X:Eg); *=+-㙻<ı2\˜I,2> ev }ccX:8亱㮱1h|B4oಱ?޷5cH{g.{_Fj*bJYlb6&wP,vUvJ1}boP&va/A5bt\ l=mT La0?9r6/N {c {Ԉ+RQX_$%}L{'=bN`g G\ 2u=^Mޠ엀6CpX5~dL_ocr.wT?Ze_cB!-u{z7^ z=Jq%}u:twTulz;-CE%}s9f_jˏ3}Zo9B*~ 㲭B_XF_ooCn>n?rUKްS7O}E/M\!6M.zeoܽPկRcVnܷUN#Yhz3m4vmTKpy' .z;CC۹}Z ʴ775Zoߡ{e|O XYX8'S0cd3z6uiJ.1KK0 !% _)4YNY6YQr 3|veYWeY7eY]e!h%ifI% A(i2,A,g1 ror 37rX3x.,匱,gi9ç3IJr .s Y_ T,gY'fKFC+9C0c+9A+~4Ke?r! 4K K4X2 1|D1uW%xU /KJJJ/JJJa{Y%,KK$?(aZIY n~d Mz?Y_ݷ F)C|Q$).ͺ۲oяK/;XFC _|(]% ?w҅U9`.a9ϲE1o e?KS~le {ZŜ+smy{Ÿžl1*-Ć,E-|,KK1HBIP,C$ظ$KKc,YZe8eْd!% A(Y,#JX%d!% {[l%K'|w?_!?(. AcqoYӢ!,|ȳ +غ8 w?''Q0cd/|8׸ؕq`0t! fç: 42+\f̽G?N~261`6}V7eX8[g/}P{`;`e3c`P>|_`>Γ`v>vG˷Mއ P?!>w`v>|G$!V@\gd./ fݾI i}o+*!,#+_ A:2"bPȘ*~o 8Py,#/9 _A gFHi*$coI^>2$A)yN~gV|"%?6cK<Amb'1m vMγnƉ]I:;HNY5'~~2F?}XGh'K)x90)sdS#:*k?Y4V2Aab?Id#"2,M0- 4j [Z-moeo;E =12.c;^IJ?4KC,Kbތ&oA|}<}n _ ދ//~ ^fuAl<{1P?3LC}Ͽ~BD#Zp9=s֘"G5cdjz9s92Wd FG6Qlns`s~ds`ʁ͹ĮeG+6>ela`#?B`K!^-AF05O050yBqP3AcցB@ss@? c@3Nb'׷CPs15/93rE"6c` la`#k917C!c,Cp3FF7d!fonȅasF7Oa͘+7w9q lp`S ͷk_Vnqp󲓊G9'ۼ)K&6R126>em>06b6?626:A\'O mL1yf:6صBph㷧<8̡͏6ch3_!Džu m4UbM1!#Ch"7?>07s؟=)›vscQSLo|8 oax3&7 mBZ/~m~6ZY6b9F6~ 8B[BMC֌GٌsiG29D8~85D8cጹb##?]BGF8~Յgl#A᜝/Ps&E/EvZ0~L\wvugcd;)38ԝ\X;ԁFP{׷`?eoԟDS/EA)s AeCk?RK>R?R4_).B*BEh߾_TOp?5EhMlM"4 a< _[ѮM+a"4E(Bc J ,@h7[P; |Bu12+cd.B#s|mP#WWc+cPa`(Dk`ژb:/' "4_N.BEh/{v Eh?Uz Eh??.Tf/u3ƜV#}C?*4; bߧs! .D3Bo :h>.עn oLa~q7t777}~ h _\M֢ oszGB=ڏhsz4M/;[m%Moq]a.m.^W*|\~*p] .ͯݷߨ.mLbP]ZC4\f/dRM?*oҏ.^T4A\S.OP_~Fڴ1֦9smO#Ԧ4APvkOUicX&ġFM֨UjֱFMԨNn rs7wsvVFM0֨ a'纩S;NM09ב9UUUMؕsd,SfKGZ:cBt|;,_)t,l~#-'-ut~j:5=8:O)[g̶ϙm10:~k:6jy[Ǐ6:>#mAhZ:WUځw#xeF[G: s윛;ۦAvN ihU&xeZ5?_ҹuul`4#xaX:y_ե#5{`tƜӱH=^'Oܓc;y:#K?G,9ϱVv΁wvvAv`s* v윆VVs`ra9S:Z9ʱd X9cdR;PqoqYY8±:s+}=Wwj™G8sDGql 5ƮBM08 m,4hB GЪ:lZU ^U 4?\&hU& 5[|o;8Mj>WoNTfgF7~ 5:7p{7}nj!nbw ߦϞMC Fʯ)xk 5_ƫ)ƫ7^M^MC\NWSƫ)xՈ]y5>{5ב7~M`k+bn=ogcplvgS{6/;`ٌ egs]y6o<ٳg3&Ϧ l :Gmj PmϛfL}126coSƷ|?ۅOM6,xn fw)_wS{7Bw.UnwSƻ)xn x7wcG0y7us│ɻ)1Sn$Nލݒw397vs@f삁Y4pN_)xcLNA`6pg88 108ב7&Nl78S8'B2q/`⌁7&N`6qv 8 }6o)S8~w!!6o|ɼiqzqF'/ѕqSƸ))1oݘ7ơ7Mh2o)xc1p 83NCl\WMdMCl^ɸ)hc MAh0m ML q#!9  ԨݴP0fAN1ߜ'UtˮrpcӥܦnjR+UxsUvsMt6aWaWa19  Qy:,&5vXi׌9`Zs_.G)>L,)e<8OerEPRlCIJR|\ibrSgJHS좢0sBR̦LL,*1]zr' ÑcCKߪk|m2î"îînbv3nO7c|L`+Ǯ~N_+̮T@e 5c|@,g]XX<6Gⱂx~Sgxlr xMXP<_X8oǞP)(+vSPV0]:r(,{eǥP\Xelem Ⲃ*.+ Ⲇ:ىeqa 6eaa_R̷Neaa?QoT 0, k.dlؔY{ދ _E.xU\&ArĮfll_ U@ /B`+F00?v # ^v(vR#x8x1/;\`& ~|~ЪLL4YiLPegw2`aƩt90~~ly1 vb(b+f,٪27c悲W"sfGf̙%9d&#fUPv SƗuWT&]A,<l=]/9{HGfef̘sfn6cl( gY-3vF4cu=D3kAJ2(ͣA#{Igvdb٢}h!gi;3LЪAZU]U ^y3W` ʌ tfZ'i!c|+_FL03בl Ud~w2ۦL04V>P#X!!piZU-A#ZhA*4]՘`pis^U8U1A\Y#*5ة+ĕcP-x4>$ IwG & 4iŢI#MAlҜe& 0i;Fw65>p2j|d6jE.sI FF5~ بy"lɨiheA#xe44o V9#9 &F 4РC`4hy`<@AӏǂѤ@4|*ؤy"ISΠ1hĂA3irؘR0f|vƌ`0fbSLWƌ`0f#+s;sFmcFsFʜ1ghlP+;F04V04 A# =2 l#c0hI$4v!$EAc9KFp0h=Aʜ9037`go:SgEfޒG3=9x4vS@fޛv>XiF~G37ͼ'/oui74c`iO#hFF4 Gc$.=`^y4٣?`hςwsT19]E55`j4FD5 qٙ')e Qظ!F*IcԌF $5`<;Ol918$6/;kBbKlcbsUb LjqRsÍvI`Lj|aKω LlF4I NjF0v Z%4W ́w &4_CBӯsRsƤf]F0&5L $4dF0w=|:*Jj^&5W]gW]g9X%5W]gW]gẂ7Ub#AF&Jl7j>ICL,،i` Nj9_֐10&5 F0&60Jl̉͘#$6pRcOi![fתL0$5 aBcmƷ n8_5 o+lIlbbs]b#.̑9S|؈on!ǯ،9'*NlqbcRbO!g}،L'5*pR#($5CfAGIMAl&:B2S ɌPHf(Ph:/;x45 gg9CYCl6Qee:27}dn8{JqÙ n8熳 g'~|ov{ƜlL{^c=gl9=gQ瞳V羳f!7JqٗoOl=gsv?;kz~L^PegLZy99ȡ̗z~y7~12]G枳12={Ƒ =g~ =g~s =g_>2ݘ`9خk`kΓ`kfhל? F<v_CGMA`4veȲi_zA+Ȫ)?{Ο]S5lͳ]3v욂خ3.5~U]*)VݞEU3VyW0X5בm=hc`~m?l؇V[6~eؓlrl496؛_ٱsf4C 6k7`֜`vk ݚ4ر3-86vQc5c?[S5K[:5sȩ)CoMYNSة)z_05O{rk4ڵqk !pj" ti|ɥiqءs;S03L ^94>;4 ;opg^qgݸ3oܙ7L#vg m>3^L=wfLLAwWݙiؙؙ$C_R;{"duFœJfld͈!iF™9J1fn_F,2b6,ˈܸ2 UF,2ŀ SƋbn?Y9ʉ{[(1b7F؍#vÈF0MsN,JQB>Ae@F 0bˉJ4bleVBXaltl2 sؕ #L1,< F,[0>` ]cw)`a}Do(E+/6`|O//2]Đ"m;,+E,.7[#V]_КDl\\o(yA:2)cʘE*sEW1]WCЦe`HV H!R.CqB;b1 U@eyQ^ am{a NS^D#T0*dE F+c![yؕ_1NWa"0XqϘs&+ qbqT~|5C`NU>2*0WQu`V92F+ReXAD9SB12*>rUrA'TͭSeXA0ecqe AX^ +#mK=Xou\GƸş@C":'.cB2Fe.Jl_7_ ?\!67Q0d20A8[XFQˁ9Jl <46X i4:)4s`isANj|(i#{M?qH#S|i|9Ae(i1ǐCX4q<#;+S>caq2s߷&pb?lL&aOް/6ma7-L8c[عŮuac'5=a q?̗ cCROlu'&Y1{ɔzr #G̏A3[Ƹ"&[ b!&:.]bKl.gu5]bQXCWF0A{4A5f@A0h2s\"6ei#53FFk$g!peBGF!FGF{*1Abrؗo}%]Jَ)s 6Ibf=0>pa|ByeF+Fil1lÜ|c]SyP0Z1c_P*r[ laa,Ȇi-A`4bsтѫ/6:؝"X1~e3G+!aƒybƒa8mVc^6gc.l< GbtL1b؍E nOq7rؑdq6e'>2OWƆ]Ik,3s`4ffef+3U^3{Cu!#s%yIPgBef *3 Œ f즔AOdę12 ba~S/=Jb2Ndc`&#8 3LCXG&]$̿(c,(QFEM02/ i`_Œ fֹLv A+QFgQd e~3 1j"1s#2ԗ ecd6cQbc8T#wdƯ6 2sddsFQfDCQ̘)k2X@idaI@,BIƯ`C<]qٕѶE12 !sVG02АDX;2dƺ'#=Y)_02ؔgSie82w[`ٔ 6elfO-=<:/#hf_e"OFʓ̞Ӗ<؏~̏c( {1/JS`cnvُ9PcK|~AB?fΑe~1@`d4~X2cgOf̞odȱ'cwtdb;o3e?Ɵȏ<'3fOƧ<=0[2cْĖOƟ'EdĢ'('3f̞̏<'3d<'1 3ϱ AlȌFCfl GoyݖГF02~_f/#}X _dfOflٓiib?F1 Qb0l{6o`a4Ї>̘+1㡁AhČ"#:W4c\iqs81ЏBc ;:Qdt>R#J`##A4ы ^}^R2A!YpE+ }U0 Em^6GUҮN~4c490V ́KႰhnʏң9G*=R8yXTVX$H)`?G QKڣscP{GHD0e #H\{4#IWGH`ӯ,? &kc `8J5Hc\'s R3X}omc $uXK^~mB R3)1U.A%Hi4 vus X!.Az%H$?Wi9 ,C/ q,i/܁{8w G.^_\~_*?j? >wʏ`Ѹ hlʏңBTzc8\4a?c\c.P4AG?Ɣ.|d? Gc`,A3'uHs/P䷊P$ ' "$ =Hs> CCR3P H5G@ڏq G G aMZz4G֣>C-G)rј"|'n=G4֣H ێƍێ2rۑC`h;jhr$Zv#i_v#a F5|[})̽F8͑R̩SQCh4KbQCh$k#vkmt 6l;⎣qK\%΋ sAKɾ O/}A FcA t_65憣}L l8:/fl$=`௫`uL 6zns*H,wU`8/?* il::Omcy.>FF l<:c#` ƣRn<£J࿟z-!{A( TE(\h47AcX!.<}GOr8cX{t^#L&CAXw4 uG|7;z<a˟X輚,̇h=ͭcѸhEGc\u4aˎ7MG' (/5,}X!mC Y#22.2,*2e.(~s\ ȾӮX? ?尟t@ $Tl\n q0?v?B}Q} X>sp]"4|av :f'>;Õc\8f,oV8r٘^:,wm$u4v |ŸoNP7fG-=߯>.; wٳCmCX%1.kƾ2fϯ$6UC01gWc~ߑeaCr1w=l{GX;˽b7{[{?Rb`aV緩;(9bcVJbިT0)~Ob)Qċ?6MT&|]b*ܩI̞#BaG P'v6*fG;=N1)raQnB?RK_?~s^ }r^ Tb(ͳma  ]a$}^̦Xv0OՋN0'WUc(W0Xfbluc34Xv; ր[%`` U͵&0[b.ӆ{9׀`ҵ%bU`I}A\>z=JW'I_V`HgaIve|\5y%W^W" %D [%~>үo}ec@2 I$m2LĆ/8X&vI_62j&bfbŚ LwzU%xUuUUUMU`M.:Κu ^&C*0*0*0YU8&uMt 0 0 0 0 _xY&xU&8T4V`um0k'/Y;q6T&0BDF9QNn.|.aMdW&vx'bWމ f,ׂz.Ǒؽ~j'V`A;LL,'~bk |A?Q?D`!U`Mn"(~%HMt;fv'&FrY'b:NDŽ:ihu?J:U֯92~9s/Y( }2_t.[Z|B#2_x.mhBEF6ʁFQĮl`4jQQu4R f9eNWT|`TLyTU"d]lbWʁw"A`4JC<$ -]Ƭ"EFJȚʷWPUΓ`rU{v4uCVi5?vy`V&cϪJ?Њ Ί,)cY[,+ƒ"̕PYΊ VƾpV\yNPW$aw/±2f{e n_ia7y6XbX&,12i,bb,,u6Y;\?Afy+E0,W&,ӈB˷l| JO_Yj}ZlXi-N^BEljKEp[]-v"q,O*.Quɤ$b@E .!$y/A|ael>/>2/ ~r3N? 3FFF0aF0cLJAl!%.|c)@=h1tb{!Ԙ6aȈeI"KfMF{2"32V`Ve|ȕ1f+Ҥόٟ 4Z74cdThCs<4Ц:\ĚȨ;?Oȩid>~^~cR@RYVqA+F04aF~Ew6H4$4e5!$]lbẂD.|ŧA2MC1A 44#x#?"膲,#e#,Bˈy.cá,8,˼A*27U?QêӎUPe^vvWOve$Velؔ 4e.(̢O ߃)p2FFSF{*+ǦU102vQ_emHiȆ̗-B0d-YL6d|Y![gCF2~,، j{,c1Jb`c+1|(Ƽ<1cG:}ŎtPc#՘Ytcv3v?2fzO#1wo#17;cAy$XH/{c1yAscwY~ s<2cde,2w2̀ ɍ`e$؟LI#(s8#ę@qF3~Hi0s9X9Pg D6gFs?CIpg /|X94/w3#_喱C~ ?j;3F&w!vf[+3爮 te\\Ҁ3ʕ+F0! a~X,0q3i6+xlV&)1\LA99'glv٬ e/p^58DLAġye|= a(SЍB  e PfBo2`(s X!cNv#82rWscn>21l☂7qL>ȉX8q̜DHeƸeΌ%xf 3>U:S&)83vtfL_9gZ2r,g*)e \M.Spe||ْQ.1p*)8/wh,r̹E.S&9pe `M S&)ۗ@ d))8s\2n7Le%` 16&)xa 0))b61La ~ih|n+_ /sb(/-eb0l)[| [ aRǐZʊEP[ a +D-Z{Q?B&5ej1E.z#8j{NQ˗Q?q`RD- QRD, QRE+a2N1Va YAÑ~oS99CX1P;ԍ ڱ6uco ƺs]vU7V0Սuc q͘<ՌnvauU;&8ԎvlՏ]k c\C35dXCVmQCV𦆬`! 5d[!;OWb;beCM `!kn6G?/jȊԐ!+xQCV즆L𦆬5dq2.d׭c;ܡf'c('Y ޴i'+4WԒ%%+%+j Ԓ%+j:M U YTCVЦM Y75doj 5di!{ 5d 1~`26i+x>&x>V,c׭oZ ^i!+[5dvj }!UYPGЦEYC6"2_M`!+zLcm +x?&x?VMX7csci@!l.[^ #J}d dPGgt##QYCb^2{=dR#M#/B/8KdcK6dz^12^l}d QYACV =dco2򦏬MYG6KvNnZ *u4*LC9gAG^00 q/9~Qy"TgT_^Va #UAŒaR F*0nFJ'+U]t^#_1l*{=e~IihPV𦡬JL&՘A'4ƼD j LEeŀ0 t`n* 2[yڥ12;0vi3.4hŒu evH&"0~KdF0L0 &̷BC1̖51>U2b.S f0l*+?`وٵN`.+gƌi7avcE5F`Vcn>21vc 9F1 ݔӎqpdYY: "#NG$s390K2vGg|DW:0;3~ͳ3#1Wtfqe!vg,Vcwaܙ1 vg쏘؟Gɞ#=#Ð=sbh| 6MuYl)6il?VeOc/O󲣺iĮ|Ri >O#}Ois٘+{5jW9x5\Ufsdlq/6̓wsy22{8(pqُC33g9){a09 }IF 7ʲ_?#);,ה[a99Ia0⠫\5vBys6sf.^%4*E99mv/cW-e:eY5C';,F1v~J bbc+(;좟쐫zb$sLd*%;쪓찛/vWIvU#a7Zbn#_ŧbk$;mSHvXHa:8쪖찫Vn>#vdÆƦɽd|&F,aZ},F*9,0 vdca0!tm2îˑ;y._6-(f-7ZIZ AK1n s]aof!![yGWa7A7c]UvXwc+n1s+[^>J6#ZLVL*16RF7+7l%{ڲZs+ٷ7<" J̢L(`n%J&[<dw;C+ij%Z|PJfZlR) d@YCXC&j\?e+|aB  c>p)Ј"|ݸ|L/j([`({: cRL09C Y edב?]r24d>2 r2?p̏E('0Y$d+9Uj2A\Mو\Mr8T nۗN,M(V jx-Ė%̖èbNr8 fe0.β~܂(.@qiݖ,-v 1-GYr9nAsd~bGuߣ"6FFů‹4^bʋ v^n`iPAw)(x.E]!tT~RYݧ֋ * ; . P(aE.~ăm1(.~<΋;E,J/֋_A{ge`VƋ"V`󧓝"v‹`6^"ejLXsF Fh0 r `.;&8O 3FF0~F 朞7X`BE/X~KC$qX^",rnÂYzy feI\Į2#H/Or^,BEJzҋ,$4tC ^.Yv\Yvy؁BE .z̺,"٥% 4IJ]);E0.?v$X] Y.?[.s$\EE/zF+|_mLI,d؛Er$l/ɮ×>dbX,~ -IY/-ֲ^; XzX/`m8_' _<_ZzjI/-#{ `)ؒ^; XGzkI/ؔ^K%ˡ#8^z-#u: P)֑^J%{ FI/%Nb-R`鼀K} /`H/օwˁ,x]`υ0`-p0]z~\^Ƶ  ‰ H0 eυ\0҅)rajC/2 Hβ`J 5ڂ5 `H[0MZ0I_Wb~_g _L,% =d _ SuC0U7 QZ0S mnlIb6 ats7uSXY0`7KHZ0ȱ` ,XKa,‚ H~i ib]j{X[/9d9d *1M LF&`#,`#,<,X#,4,P#lW`1',rXϔ^-iBS[ ͖~=<Vz-Z iyH-ͺiMn=hY"K܃T,q:ˑ@b&2$2K*]ȔjV-B o;YhBV>%6zeI\jU,ԪXAHt\lV $N@l(-FKaBg~j)lxYX%D;-Dinj0RX&YևG,D&. VY'if 5(0c9teXb::,5+ ]Ra)0X\SX)P/r"TH, W֛Nܕ)ՕjYJ P- Kn7WhxBw])PWV"X- o;2z $MB τZ/B˥YF[,%n}2e=TZa)2X.X ]F+ ]+ԕ %,L#&z;SkґS Z$5D]0V)4`Bw5 +eaR-VQm_fpBD'tD\Y( #_ +Փh %Ia~~c'I}tW?L'enV  ľv?qQ \Xm7INJYp '%"Q)R`Ql9*-GpTnJ@I(jjk'@K;){N `t4X9)` '+'%n[n `rM9ѡX) I)K)% ) GBkI(- BHX8(^X* `GEUj,qTBEŽV+)8OI,RQ (RQ e ;J XKIl))rXwTRK%N`t ;J Xk)BM HJ),)!R -Tli)u-% GGk(BפTGᖵR(ttz!u0RG$uݐ>J@CJ@O 'TknR{a'- My랏X(Q~,mO)F)~ =ɛ `P ^`Cުe  P[PZ `ʶemM2U Pl>1UeT,LH*tuGFWg ]9/2/_OQbd &XmGƋRb8 d,騱R,!c$eـe؁3V`4V/i 5Xdm[ctXc2v\:wVc2>^`AVoMLB+U:O$K2:$lA1dIT$9dܰ"ki%Id|'Qdԋ$jXidju} %aeMȸaGCX$YdN2tv'!d4R: L!tYQ+ ! H叁 %dt $Cȸ=AkC!f`DȊ"dNȸV`+ GVP/ L$$"Yd482"uKVKVX/ ps=, IFPI'd4aTaŒdYdd`D$Y@:*F!wC$ct1i+| H`CtCL" 02iFHƑyd|@2>2 $+$'pMƳ! ',^yxe`eB'uD12M`R2 SV,s2", UƗyV髗ZXĖ$2@:oTdY_f$BHmc$UeۆuJ0x&Ԍ)H#4bI#0b& eD)2a m6`c`m6`nH}k0 Vڀ9P7<e ϛĀvP0|S?mjs ڀemoo 0ڀFJ80YK=Kܨ@kvځ r`=|=raHtaI\ Sąړa[2 `Gk0%d{2 Ƒa[2 `Gk0-a-_b [rL=9cYr `K1`t3X1zgzLǰc¥li2-Mv4&d i2&Hh2(d,T2,CYL=Ups]2Ok)3-epMeG>}3So `K,@:V3,u:V3Y `Kl)32Qf @Rd)32Rf[ `pFSd7"RdKE@#ȀL_d(d JuVoV,(H22/e>jQى(-' 2e )҂LG)qfՎHQ@(}L0Bٜщ(7SJϧL΄_ 3Q& X 3,af )ʔ)TX%$@R:X2e X2URx,QZz2|(% KRujAgB" X 2= ZFt] H 2 m>dX$LGS\ 2 Ѩ& mJ Ab$ 7,`7-b ->k/x1|r'^ O-dQ^̶ڏz T-ëaI1S ڐhBjCI2`!çAbp!H2!l^25,e#̕!V2TaҪ q Zq4-*C4ee R$D(LQмM|]-uCТ2/y2t|*eLղeQL}eNR#@RD$z76Hh3g(fjQ{3:CogGU fxN!@ʛ)fiowZ{37H{3|ofof3{"HB> >V3i}c$zm3j,gg ujG.H22$ t͎imfY `$tIm@6C#`.7@.çe˛܌wBu3.m7tM?xx3ZМM6t|ytqVo~K+m]U+Jwh<xtӄZ-U+7LhVv4K |Mg⸅O67cøÛ?/wn'iw۷}׎+q:{|?EE{iݹ?MGΟ|CaOiL˥7aaM|Y>tue}d4@Do?]nf6xp=cvw|,;%+6pD|^͎vOqVzoݟw/_OOǿ;|~|/ݹ /]0SnF`M_uܵl.#3>8}pi0bnO_?<> ]Xzjk߻pSEd5`۷<_~{x0ܩg1mu[m/X{Z>2o|ӴKml/vz=~|t^ooliCOA<ٛ^gsC|hAii6Mcmӭ>G׷,oǥlnoiz Nvl`~zW31ӚդyuvƇqִ|{VFlw갫~Yqw?NoOi9wSxፕkw;dOZ5'^/xҏq|~VbzSVζofjrrO[x,.9񣟟Wo;׸ʏ.= ¾k=|[s|~ť_(Gnz_5ʙCxz4iƱ۷B_ߟatݏKMe>;_÷? oiǻVt_vO=uof{'qOnlrVn>MKnnwh>xڿ,?QSNgi~pݰ9b!z~e.P븚eix\orq<a噴^1^.{wf3XfrT39-^&fمfX/toO\}ثvsk==_!Fׄ m۟!/c' :NapOCu8o*yY ]4ό<]pw߬숩NKGa4)aOe7=WKIY4t?xKZWC8-C4^m_?AM/ݼG'Of;!>yo*M)G~+O~[ijڮ-π0-KW 7nbOytԗ?3d$܉endstream endobj 318 0 obj << /Type /XRef /Length 265 /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 319 /ID [<698d9b9c4c1d332fd478b8affe555a3e><9558599e4be7e503adc343899bde4b4a>] >> stream xcb&F~0 $8J8?P ^ԎJgܺ/M#`* DҀ})pD5H } `5r "d$ X2V3D``5ׁEJȃHQO)"@) vzɩflgsA$w;"`{1?h"U\4XeU[A6^Y f/IcP4 endstream endobj startxref 439513 %%EOF TSP/inst/doc/TSP.R0000644000176200001440000001453514412674611013251 0ustar liggesusers### R code from vignette source 'TSP.Rnw' ################################################### ### code chunk number 1: TSP.Rnw:81-84 ################################################### options(width = 75, useFancyQuotes=FALSE, prompt="R> ") ### for sampling set.seed(1234) ################################################### ### code chunk number 2: TSP.Rnw:645-648 ################################################### library("TSP") data("USCA50") USCA50 ################################################### ### code chunk number 3: TSP.Rnw:661-662 ################################################### set.seed(1234) ################################################### ### code chunk number 4: dotchart_USCA50 ################################################### methods <- c("nearest_insertion", "farthest_insertion", "cheapest_insertion", "arbitrary_insertion", "nn", "repetitive_nn", "two_opt") tours <- sapply(methods, FUN = function(m) solve_TSP(USCA50, method = m), simplify = FALSE) ## tours$concorde <- solve_TSP(tsp, method = "concorde") tours[[1]] dotchart(sort(c(sapply(tours, tour_length), optimal = 14497)), xlab = "tour length", xlim = c(0, 20000)) ################################################### ### code chunk number 5: TSP.Rnw:703-704 ################################################### set.seed(1234) ################################################### ### code chunk number 6: TSP.Rnw:707-711 ################################################### library("TSP") data("USCA312") tsp <- insert_dummy(USCA312, label = "cut") tsp ################################################### ### code chunk number 7: TSP.Rnw:717-719 ################################################### tour <- solve_TSP(tsp, method="farthest_insertion") tour ################################################### ### code chunk number 8: TSP.Rnw:728-731 ################################################### path <- cut_tour(tour, "cut") head(labels(path)) tail(labels(path)) ################################################### ### code chunk number 9: map1 ################################################### if(require(maps)) { library("maps") data("USCA312_GPS") plot_path <- function(path) { plot((USCA312_GPS[, c("long", "lat")]), cex = .3, col = "red") map("world", col = "gray", add = TRUE) lines(USCA312_GPS[, c("long", "lat")][path,], col = "black") points(USCA312_GPS[c(head(path, 1), tail(path, 1)), c("long", "lat")], pch = 19, col = "black") } plot_path(path) } else { plot(NA, xlim= c(0,1), ylim = c(0,1)) text(.5, .5, "Suggested packages not available") } ################################################### ### code chunk number 10: TSP.Rnw:792-793 ################################################### set.seed(1234) ################################################### ### code chunk number 11: TSP.Rnw:796-807 ################################################### atsp <- as.ATSP(USCA312) ny <- which(labels(USCA312) == "New York, NY") atsp[, ny] <- 0 initial_tour <- solve_TSP(atsp, method="nn") initial_tour tour <- solve_TSP(atsp, method ="two_opt", control = list(tour = initial_tour)) tour path <- cut_tour(tour, ny, exclude_cut = FALSE) head(labels(path)) tail(labels(path)) ################################################### ### code chunk number 12: map2 ################################################### plot_path(path) ################################################### ### code chunk number 13: TSP.Rnw:831-833 ################################################### tsp <- reformulate_ATSP_as_TSP(atsp) tsp ################################################### ### code chunk number 14: TSP.Rnw:845-847 (eval = FALSE) ################################################### ## tour <- solve_TSP(tsp, method = "concorde") ## tour <- as.TOUR(tour[tour <= n_of_cities(atsp)]) ################################################### ### code chunk number 15: TSP.Rnw:869-870 ################################################### set.seed(1234) ################################################### ### code chunk number 16: TSP.Rnw:873-883 ################################################### m <- as.matrix(USCA312) ny <- which(labels(USCA312) == "New York, NY") la <- which(labels(USCA312) == "Los Angeles, CA") atsp <- ATSP(m[-c(ny,la), -c(ny,la)]) atsp <- insert_dummy(atsp, label = "LA/NY") la_ny <- which(labels(atsp) == "LA/NY") atsp[la_ny, ] <- c(m[-c(ny,la), ny], 0) atsp[, la_ny] <- c(m[la, -c(ny,la)], 0) ################################################### ### code chunk number 17: TSP.Rnw:888-897 ################################################### tour <- solve_TSP(atsp, method ="nearest_insertion") tour path_labels <- c("New York, NY", labels(cut_tour(tour, la_ny)), "Los Angeles, CA") path_ids <- match(path_labels, labels(USCA312)) head(path_labels) tail(path_labels) ################################################### ### code chunk number 18: map3 ################################################### plot_path(path_ids) ################################################### ### code chunk number 19: TSP.Rnw:941-942 ################################################### set.seed(4444) ################################################### ### code chunk number 20: TSP.Rnw:944-948 ################################################### data("iris") tsp <- TSP(dist(iris[-5]), labels = iris[, "Species"]) tsp_dummy <- insert_dummy(tsp, n = 3, label = "boundary") tour <- solve_TSP(tsp_dummy) ################################################### ### code chunk number 21: clustering ################################################### ## plot the distance matrix image(tsp_dummy, tour, xlab = "objects", ylab ="objects") ## draw lines where the dummy cities are located abline(h = which(labels(tour)=="boundary"), col = "red") abline(v = which(labels(tour)=="boundary"), col = "red") ################################################### ### code chunk number 22: TSP.Rnw:986-990 ################################################### out <- rle(labels(tour)) data.frame(Species = out$values, Lenghts = out$lengths, Pos = cumsum(out$lengths)) ################################################### ### code chunk number 23: clustering2 ################################################### prc <- prcomp(iris[1:4]) plot(prc$x, pch = as.numeric(iris[,5]), col = as.numeric(iris[,5])) paths <- cut_tour(tour, cut = "boundary") for(p in paths) lines(prc$x[p, ]) TSP/inst/CITATION0000644000176200001440000000116214402152646013036 0ustar liggesusers citation(auto = meta) bibentry(bibtype = "article", title = paste("TSP -- {I}nfrastructure for the traveling", "salesperson problem"), author = { c(person("Michael", "Hahsler", email = "michael@hahsler.net", comment = c(ORCID = "0000-0003-2716-1405")), person("Kurt", "Hornik", email = "Kurt.Hornik@R-project.org", comment = c(ORCID = "0000-0003-4198-9911"))) }, year = 2007, journal = "Journal of Statistical Software", volume = 23, number = 2, pages = "1--21", doi = "10.18637/jss.v023.i02", month = "December", issn = "1548-7660" )