Aller au contenu

Introduction aux algorithmes gloutons⚓︎

La résolution d'un problème algorithmique peut parfois se faire à l'aide de techniques générales, ou "paradigmes", qui présentent l'avantage d'être applicables à un grand nombre de situations. Parmi ces méthodes, on peut citer le célèbre principe "diviser pour régner" ou encore la programmation dynamique. Les algorithmes gloutons, souvent utilisés pour résoudre des problèmes d'optimisation, constituent l'une de ces approches générales.

Nous allons d'abord fournir une définition intuitive de cette méthode, accompagnée de deux exemples.

Le principe glouton⚓︎

Définition⚓︎

Lors de la résolution d'un problème d'optimisation, la construction d'une solution se fait souvent de manière séquentielle, l'algorithme réalisant à chaque étape un certain nombre de choix. Le principe glouton repose sur l'idée de faire, à chaque étape, le choix qui semble le meilleur à ce moment précis (choix local), sans se soucier des conséquences futures ni revenir sur les choix précédents.

Un algorithme glouton est donc caractérisé par son approche directe et irréversible. En se dirigeant rapidement vers une solution, il peut ne pas garantir d'obtenir une solution optimale. Cependant, il fournit une réponse en un temps réduit, ce qui peut être acceptable, notamment pour des problèmes NP-difficiles où une solution optimale est hors de portée. Dans de tels cas, les algorithmes gloutons sont souvent utilisés comme algorithmes d'approximation.

Pour que cette méthode soit efficace, il est crucial que chaque choix local aboutisse à un problème similaire, mais plus petit. Cette approche partage ainsi des similitudes avec la programmation dynamique. Toutefois, la différence majeure réside dans l'ordre des opérations :

  • Avec la mĂ©thode gloutonne, on effectue d'abord un choix local, puis on rĂ©sout un problème plus restreint (progression descendante).

  • En programmation dynamique, on commence par rĂ©soudre des sous-problèmes Ă©lĂ©mentaires et on combine ensuite leurs rĂ©sultats pour rĂ©soudre le problème global (progression ascendante).

Exercice 1 : Comment rendre la monnaie⚓︎

Nous considérons des pièces de monnaie de 1, 2 et 5 centimes. Notons \( N(x) \) le nombre minimum de pièces nécessaires pour obtenir \( x \) centimes.

Question 1.1⚓︎

Quelle est la valeur de \( N(0) \), \( N(1) \), \( N(2) \), \( N(3) \), \( N(4) \), \( N(5) \) ?

Question 1.2⚓︎

Compléter l' algorithme ci-dessous qui calcule \( N(x) \).

Question 1.3⚓︎

Appliquer cet algorithme pour calculer \( N(14) \) en considérant maintenant que l'on dispose des pièces de monnaie de 1, 7 et 10 centimes. Que constatez-vous ?

Question 1.4⚓︎

Adapter cet algotithme avec le système de monnaie en Euro :

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 5/5
.128013it3a;dv,n2.S5wbcy14q: f-up08)_9eklohrPè=[sà6(]/mg7050g0G0c0e0b0I0Q0w0q0I0e0Q0Q0O010c0b0A010406050Q0z0W0W0e0L0r040m0J0I0z0?0J0j050V0}0 11130{0A04051j1c1m0V1j0{0g0b0h0+0-0/0;0-0j0X0z0e0X0G0y0A0r0c0K1a0w0K0b0X0K0I1O0K0c0_050$0p0I0G1v0.0:011N1P1R1P0c1X1Z1V0c0L1k1J0+160Q0A0e0j0;0k011#1x010x0(0G0j0e0W0G1V1`1|211%241Z27290_0a0w0M0L0J0A0J0Q0b190j0w0!1^0L0L0G0q2u1c2c0j1k0V1J2H1;1?1=1W0g2e1y0b0j262r1V1s1u0,1$2R2T0j0J2X1V0A2A1k2F2H2.0|1{2v2Z222%0L100I1V0e1M2A0x0;030E0E0q2(0G1R2$0J0y0B0y0s0_0w0s1c0e2/2=0`2;2d2@1%2_2{2}2 0G3101333537392U3c0y1 040w0k3j3l1|3n2F2Q013s0e2|1k2~0K303234360!3C2%3E0d3g0d3K2E3m0{3O3q0;3R3T053V3X3y3Z3B2S3D3d0t3g0t3,1d3.3o2?1w3r0J2`3S3u3W3w3Y3A3#3~3%3d0n3g0n442.3/2=3P3?4e3`3z3!384k3b3d0S3g0S4q463:493=4b3t3U3v3x4y3}3a3E0Y3g0Y4H3M4s3p4K3Q4M4d4O4f4Q3|4j4T3d0C3g0C4Y2G4!482!4%4c3@3_4g3{4i4A4/0y0F3g0F4@3N4t3;4|4N3^4P4h4z3$4C3e0B0_0s0B594_4u4(4~5g515i4B3E0s3f045A5q475s4}4w504R4.3 3e3G0s3J0V3k3-4Z5F5c4v4*4x4-535M0s3)5C3+5R3L4^5V4$5X5f4+5h4S5$415C435+5T5-4J4{5:4 4,525j5z4n5C4p5|455U5 2^5t5I635x540s4E5C4G6a4r5.606f5Y5J5!653d0s4V5C4X6o4I5b5/6s5;5Z645y6x4;5C4?6C6c6E6r5H6t6h5@4l3e565C586P5~6R6e6T6H6u6J540k5m046/5E6d4a6*625?5L6X0k5B6~6?6(6^5e6`5w6W5k0k3G79591n2,1c2X2K0g1?2P5c4z2W1t1k2+0G2-3m5}1k4z7s2d0b0g0;342F5z3u7z7B6-5$202i0G7H6i7J2H5S6@0;0q5B030w0h3S0G0z0L0*0!0*0A0b0N0q0G0Q7u0{6b2G5F7G017C2=3E3G5f7^6v6K3F7K287M7_7I6}1V5|7S3Q0_0Q0r0Q0c0G290E0W1a270b0G7u0w6q220J0_0O8q8s1%0^040P7u8y0;0W0b5n8D8b8A0i8x8b8G0_5Q2:8K0_8M7=3H8E018P04698S720;8A0U7:8J4t7 0E7D3d5(7~7A867O6X3)0w7L7N773(893k7;8%7y8^7`1|3E5_8@8 6|5k418}849d5#6X9b8a8(017U0_7W1R8g1!7(0w7*7,7.0w0R0w2A0j0g2A8,8W7@978:7{4m7F9L8`5k4n9h299j6w0y673,8b0j0_0)0c0E7*2B7.8N9o8u048w8W8r8T8B8+8W947t3O8/8;0y6l9c8_904D839Va49e3Ea25+9|3M9K7Ha06za380544V9U85al5Maj9n4#4{9q047W0Q0J0 1!9C9E9G8p9{8-96ah9N0y6Mak875k4;ao9W81aNat4`2^8daA8j0e0EaE9H9?8Y9:9=2.9@9o8!0s5{6p9J9~9La06ZaO9R3E56aSa99k5ka|adaI2v9 aL5o9PaT6j5mb1aq6Xbb7Q7xaX1%aw7W2S1s7-9x0J7#9x11367#0b0L0w1Z7)7+7-7/aHa^8.a`ba5Ba}a53e3fbgaP5zbNaW4u0_0b9.au8t8vb!bm3=0p9%26b73P8A0Tb.5W8d8f8h8j8l0j8naG95b)018A0Db(3P9:0yc45ca;9Ib 0wb9996x7}2~8/a~cga7apbTclbkae7?a_aKcf3e8?ci9QbP5%cmbd5$8?bW7l7V0w0pbu0,9v1!360j8g0L0z2C0b1L2x0-bC0b9u2w9A9ybGcb9}bKcu0j5z9bcycDbi9g8~b29Xa=92bl3P0H0_0o1N1Zc85/aZaB0Ea$a(b~3ma/b#1%9:020X0c0fd44{8!5pbJde8)0_0vc*afct86a00s9Zc;c_81dzcCdC6j9Z5+0wdKddc09$047Y1Z7#dlb$9;dT3rb@9ub`8m0%dbdv9o8A8CdpdNbYb=4$8*ducsc,dxbaa2dBbh5k6kdFd|5zac3kdLdMc~bY0xdW3=d6a#a%26aFe901dg0IdjegdOdQ7!0Ld/4{8AdtbIcccec.6xajd{co3eanc^e0eyc|e4e48YdObZa*8bc6a-dc8Ycaeuc+aJd^cv0saNeAck3eaReEeBeZeHdL8Yc 04380Qd%d?dqc1dsd=c}ew5za|e#cAb0e)e$0sb5e3eIdKeK9%8g9*8oc)d,c50_0leqaY040e0A0Aeefk8z0_b;fgb?dP7ZdSfvd:0_c3eUd(eW98ex3F6:bOaa3d6/d eBfObkf8f99#eb0Gd8ed9Fa)a.a+0_0yeQ3Me5fwenfza@evbLcv6~bcdG5Mf@bSe$f@cqb.e}fNchcdczfM3F1 f|bP79c|eKb+042+2S0cfrdr04fucc5c0Q3G020u0z0Jdj0MbF9AaDee2A0w0vgrgtekfAer8Uelfb9)9+ffgnfB04fDf:7t0V7w7d7r7f7o1c0c7ig#2N2I0e1YgY0V7g7;0!0$0(0Q04.

Exercice 2 : Les conférenciers⚓︎

Planification des conférenciers⚓︎

Des conférenciers sont invités à présenter leurs exposés dans une salle. Cependant, leurs disponibilités ne leur permettent d’intervenir qu’à des horaires bien définis. Le problème consiste à construire un planning d’occupation de la salle incluant le plus grand nombre possible de conférenciers.

Désignons par \( n \), entier naturel non nul, le nombre de conférenciers. Chacun d’eux, identifié par une lettre \( C_i \), où \( i \) est un entier compris entre 0 et \( n - 1 \), est associé à un intervalle temporel \([d_i, f_i[\), où \( d_i \) et \( f_i \) désignent respectivement l’heure de début et l’heure de fin de l’intervention.

Afin de dégager une stratégie de résolution du problème, commençons par analyser cette situation :

Nous allons utiliser une liste des conférences :

tab_intervalles = [[0,7,'C1'],[2,5,'C2'],[6,8,'C3'],[1,2,'C4'],[5,6,'C5'], [0,2,'C6'],[4,7,'C7'],[0,1,'C8'],[3,6,'C9'],[1,3,'C10'], [4,5,'C11'],[6,8,'C12'],[0,2,'C13'],[5,7,'C14'],[1,4,'C15']]

Question 2.1⚓︎

Compléter la version adaptée du tri à bulles pour classer ces intervalles heure de fin croissante.

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 5/5
.128013it3a;dv,FnT2S5éwbcy+14qL: f-up08)_j9eklohrP=[sà6(]/mg7050g0L0c0e0b0N0U0A0s0N0e0U0U0S010c0b0E010406050U0D0!0!0e0Q0t040n0O0N0D0`0O0k050Z111315170 0E04051n1g1q0Z1n0 0g0b0h0/0;0?0^0;0k0#0D0e0#0L0C0E0t0c0P1e0A0P0b0#0P0N1S0P0c0}050*0r0N0L1z0=0@011R1T1V1T0c1#1%1Z0c0Q1o1N0/1a0U0E0e0k0^0m011)1B010B0,0L0k0e0!0L1Z1~20251+281%2b2d0}0a0A0R0Q0O0E0O0U0b1d0k0A0(1|0Q0Q0L0s2y1g2g0k1o0Z1N2L1^1`1_1!0g2i1C0b0k2a2v1Z1w1y0:1*2V2X0k0O2#1Z0E2E1o2J2L2=101 2z2%262+0Q140N1Z0e1Q2E0B0^030I0I0s2,0L1V2*0O0C0v3g0}0A0v1g0e2?2_0~2^2h2{1+2}2 31330L350137393b3d2Y3g0C23040A0m3m3o203q2J2U013v0e301o320P3436383a0(3F2+3H0d3j0d3N2I3p0 3R3t0^3U3W053Y3!3B3$3E2W3G3h0w3j0w3/1h3;3r2`1A3u0O2~3V3x3Z3z3#3D3(413*3h0o3j0o472=3=2_3S3_4h3}3C3%3c4n3f3h0W3j0W4t493?4c3^4e3w3X3y3A4B403e3H0$3j0$4K3P4v3s4N3T4P4g4R4i4T3 4m4W3h0G3j0G4#2K4%4b2(4*4f3`3|4j3~4l4D4=0C0K3j0K4`3Q4w3@4 4Q3{4S4k4C3)4F3g0F0}0v0F5c4|4x4+515j545l4E3H0v0v5q3l0Z3n3:4$4a5v504z534U4;423g3J0v3M5H3O4{5L5f4y4-4A4:565S0v3,045,5t5!4)5$5i4.5k4V5+445.465X5J5Z4M4~5?524/555m5C4q5.4s5 485K622|5w5O665A570v4H5.4J6d4u5;636i5%5P5)683h0v4Y5.4!6r4L5e5=6v5@5(675B6A4@5.4_6F6f6H6u5N6w6k5`4o3g595.5b6S616U6h6W6K6x6M570m5p046=5c1r2:1g2#2O0g1`2T5f4C2!1x1o2/0L2;3p601o4C792h0b0g0^382J5C3x7g7i6:5+242m0L7o6l7q2L5I6g1+0M0}0(0B7b6t260q3j7F7z3^0B0}1^0b7K6+1+0|040X7R4(637O0e0r0I2W0c0L0Q0h3V1%0U7X4}267U0H0z7b0 6e2K5L7n017j2_3H3J5i7~6y6N3I7r2c7t7 7p6!835X0A8h0A7G3u0}1f7{3K8k0^0O0}0S7:4x0r0}2l8v5f7U7W8o8q3T7!7$7(7*7,0N7.8A4)7?7_8v850I7k3h5-847h8c7v6!3,0A7s7u6Z5n8X8g8i8F0k7O0Q0b0L7b8j7L018s048u8o8`7S0^0M0s0}0j3V0U8^8o7`2@3R8T8V0C5|8Y8*5R6!448(8a9k5*9m1Z5X9c7a9e8Z80203H6a9j8!8+9B892d9q6z0C9C8.8h8F0s5E04030A0y1(7P0A0V0A0r0D8M0L0.1 0Q3a0D2E0A0;9/0b0U7)0A0J0D0U0x0D02030d0K0f9Z0s1(9|9W0O9`9/9(0A0p0N0p2d0k0c0.0U0O8@ah2A200.1%9!1P4e0g2E8R8E9x7o9g6o9D86574H9o9I9E9l5naC9N917Y267B040q1R1%8_8:8=8@aW8{8}0S8 2=aO7;7A9504970-9a9d92017U7^9b8S9y8U813h6CaD8d5n4YaH8baE5Sb09ua{aAa~0C6Pb18#5n4@b59J87bfaN8ia*4xaYa;3pbq5fa$a!a?940}0l0Q0Dbt3Pbv4)9Q0}9T0e0D2A0p9#0c2A9~a00f0D2z9*9,0Q0U0i0A1P110E2u99aa0.adaf2aai0A7P0p7/a`ay4w9fbd6$bg9F3h59bkaJ9r5nb bo8/8{aR0B4ebyaP8l047Q908F0O7Ici8na)8:8x040Q201I8O4~8Ccx2|8mcfa+8r0}0CcD3S0!0b5qcA7T0}7@cI729R9TbYa8b!9^9`9|bTa19Z0Nc#0f0e7,an0(0Q0k8@0Qaxa=7fa|9g5r7ma|bh5C5pc4b76!c{7x3Kbpd79O8{8;040P280k5Gcqa#8tcR5=8H7%ah8K7-9(cN0^7U0Tds8Gcidw7U0Ydvb{cg0^cKcMdDcEa@0}0Y8_d89PcT9/c)0P0L9-1(2Bde0A9(bRar0m0L2dacaeagbR2B0s0P0ea69;9?bF5ZdI0Ab}9A6A9Rc0aK5C5Ed1b2e29t3nd8dOda0}dd2W5Wdha?bxckeb041#dn7)7+dqb_c@dJdudwdbcjegdE8|0}0udk4~dG5.dzdLdCescJcLeGd`8BdLc?9wb|c_bd5Vc|bl6m23e4c~6A8f3n9v3P7}eUd}3g8X328Te$e/9Hb6e56A8-e8e9bp8FaR0b7Eeja?dbeddfeD268}020#0c0ff9chf7efeSeza^eRe+az8cc`9ie;c}c13g9n8)c59K0v9ibad`d|0k69eXfz870v4qe#fvfLe7d6e~eaa?bJ9S0A0E7*0!1c0e2y2Aab0md*b:aher49fEe-fG6AaCfteY5+aGfyd25n6nfQfSe9aXel7#endp9%f.foa?eueOdldygdcydL0ifg3^dm8Jepg8eH04eJfkdJewgkeA04eCf4ezeFdggt3SdAgweieygugmdogo8Ngg7=0}gsgaezgvgAdJ8}gzgJeLdHeKeP040YgjgWbrg48IgM8LgOg%8PgRev0}exgEg(dMb`eKfF5Cb0f^fJ6mb4f|e`3gb9e)bbfqeVbfh4f}5Cbjh8e?0vbne}g1e ek7Pd^8pdi8~gwbAa.98hubH4~fV9T2+a9c+1e0.2E0k3aah0Qb^f(b.d+b;0.2+2zau1e0kb^fn7|fp9zf=6#fIhi6Ac3hlfOc8hcf:bce.6=h-h9h{fNe13hh{d5hrbz0}2E0c9-cpbug3emgng;drg 7a0Z7d6`786|751g0c6 ip2R2M7#1%2L6}7`0(0*0,0U04.

Question 2.2⚓︎

Avec

tab_classe = [[0,1,'C8'],[1,2,'C4'],[0,2,'C6'],[0,2,'C13'],[1,3,'C10'], [1,4,'C15'],[2,5,'C2'],[4,5,'C11'],[5,6,'C5'],[3,6,'C9'], [0,7,'C1'],[4,7,'C7'],[5,7,'C14'],[6,8,'C3'],[6,8,'C12']]

Compléter le code suivant pour obtenir le planning optimal.

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 5/5
.128013Cit3a;dv,n2.S5éwbcy14: f-up08)_j9eklohrP=[sà6(]/mg7050h0I0d0f0c0K0R0x0s0K0f0R0R0P010d0c0B010406050R0A0X0X0f0N0t040n0L0K0A0@0L0k050W0~1012140|0B04051k1d1n0W1k0|0h0c0i0,0.0:0=0.0k0Y0A0f0Y0I0z0B0t0d0M1b0x0M0c0Y0M0K1P0M0d0`050%0r0K0I1w0/0;011O1Q1S1Q0d1Y1!1W0d0N1l1K0,170R0B0f0k0=0l011$1y010y0)0I0k0f0X0I1W1{1}221(251!282a0`0a0x0O0N0L0B0L0R0c1a0k0x0#1_0N0N0I0s2v1d2d0k1l0W1K2I1=1@1?1X0h2f1z0c0k272s1W1t1v0-1%2S2U0k0L2Y1W0B2B1l2G2I2/0}1|2w2!232(0N110K1W0f1N2B0y0=030F0F0s2)0I1S2%0L0z0l0z0u0`0x0u1d0f2:2?0{2=2e2^1(2`2|2~300I32013436383a2V3d3d3h0l3k3m1}3o2G2R013t0f2}1l2 0M313335370#3D2(3F0e3h0e3J2F3n0|3N3r0=3Q3S053U3W3z3Y3C2T3E3e0v3h0v3+1e3-3p2@1x3s0L2{3R3v3V3x3X3B3!3}3$3e0o3h0o432/3.2?3O3=4d3_3A3Z394j3c3e0T3h0T4p453/483;4a3u3T3w3y4x3|3b3F0Z3h0Z4G3L4r3q4J3P4L4c4N4e4P3{4i4S3e0D3h0D4X2H4Z472#4$4b3?3^4f3`4h4z4.0z0H3h0H4?3M4s3:4{4M3@4O4g4y3#4B3f0C0`0u0C584^4t4%4}5f505h4A3F0u3g045z5p465r4|4v4 4Q4-3~3f205B3I0W3l3,4Y5E5b4u4)4w4,525L0u3(5B3*5Q3K4@5U4#5W5e4*5g4R5#405B425*5S5,4I4`5/4~4+515i5y4m5B4o5{445T5~2_5s5H625w530u4D5B4F694q5-5 6e5X5I5Z643e0u4U5B4W6n4H5a5.6r5:5Y635x6w4:5B4=6B3L1o2-1d2Y2L0h1@2Q5b4y2X1u1l2,0I2.3n5|1l4y6)2e0c0h0=352G5y3v6:6=6I6i212j0I6{6h5#1W5{6c3s0`1Y0F2T0d0I0N0i3R1!0R6+0x6p230L0`0P7j7l1(0_040Q0Q6+7r0=0X0c0`5o6a2H7y017t0j7x767z7B046A2;7L7H0`7J7E6.4_230R5A02030e0H0g0b0u7#7%0g7K6D4`7t0V0j7w7V7G7A0`5P7Q7:237I7/4!4`7{04687~83807T827X1(7Z0`7,7(0b0l8h7.7_7R7=7@8c3O856m888d0=818n7 1(856N8v3O8y8E5b8f048l0b0e8l8r5b8p7^8H4#853j8z897s8b8X8w01857}6*8o8!8T4`8J8L0v8O8#8F0`7?8S8*8A7M0`878{8Y8x8,908$8t8P4#8G943O8/7$8i0o8=8-8a047?7q8+7u97847N7D9h8Z047U9s8}048)6P9m9v9a8I7!9d7)0T9g9D988^8q8?5b855`9w7S9u9o23857P9K7;939A8|019c7-0b0Z9J9$919T8_9V8B9q9=929U9O8U7N8W9S999.8$9)8i0D9-7F9m9;9{9p0`5)9 9#a79%96aa9i9Ca19b9F9*0Ha67W8@9j9N9S8V9^9Talag9/85ad9Zakaya37)5nar7G8p9l9%7t8`am9P7N9RaF9taAasaT8~aya0aBa2ao8i5zaLa8avaW9x8ua:azay8Ca$afaZ4#aI7*8k9Ga`auaRa(8s9@ajaXa^7N9zb58Qa{7Ga~5$a-aP9Mb4a|ab86b2aY7`7N9YaS9L9`9Sbh8;b1b89_a9aw9}bqba0`aVbv9!bxa?bh9fbBae9j0V6+0|8?6`016?2?3F5N5ebY6u6J3G0x6 715?4k3G2I3lbW8Eb)0F6@3e5%b(6;bZ6|5L3(b-2970c172b;b~759%0J0`0#0yay0q3hay0k0y0`0B1A0k2T0Yb20Ucl780f0r36480Ib20E0wbV8rb`b|0z5^b b/5Kb;40c52acN5!cP74b@cHc0b!1}3F66cMc8b:5j4mcRc7b*53c%5*0xc?7k7R0s5A030x1/0I0f0A2xd1cp1}cr1BcGbXcZb{b#4C6_dac95j4Dc-cT6v0z6k3Jc@c^9%0kcxczd40kd6ct7Vdq9/7n047pdzaM0`bm7Gds04793rcCbC9TdI7R859ra?7=bUdFc_c{0x0f0G0L19d20x6%7A7d0,0N0p2Ud0d8b_dacJ6yc(c/5L4Udjc)cO5jd{5*b^9acIdc0z6Ld|c2b;4:e0d}eecW3od96{cJ554Nb`dg3F55eged5jeodoc@dJ0`0kcz7b7d7f0K7haOdB7oeJ8$eC0`2icucwdLcycA1%dObS0Ed@e7d_e95ndedkb+e(euer6w5lb?ekd^eme%5Aece.3f3ge-c*5ye_c=ez7RdK0GeM3OdCdE2/dA95b7fb7Gc`0`c|0G1_0k0@270d0x1!2x7dcrd.eE7e7g1#d$d(0d0p0x0Sc}eUdvdxe!ame8c#6wb%2 eqe fO6~c6e*6ib%e5cYe@fN3fb~fQdffSf%fUcSe1cU5j5$ejdp7Gce040y4af75V0`0cf}4#0Lcj042Tg15 0r0`0N1}1FeRdPaxdPa%04fc4teBeDfmeFfy7igh0`cEfKb5fM0k5ycLf)fW5@f-c.evgzf?dpf3cdf chdYdrdteV0:eXdVdHeSg0gs9jdRahfegU9jg77m8g0Y0d0gfa3ngkf~eTczdNb2g!9/f5b20Vg`fd5mg}cFgO9/fh04c|0b0L0X1|gb0c0R1M2y0K8l0M0I0A2Bfs2x0p0rd)0hd10sd:d=d10cd#0i2Cfqhjhlhn2y252whtd/d;c d1f67Ve6fLe$f$0uc%gBf/dlhVgEgCb;h!e;gJh*g;5.gQfIcsaydC0meS0f0B0B270hge9SdKdMcBg_gWg}eZhQf!c1cJ6je)hYe+dib.ic6idnf2h+gKg{0`hPff7Rf9g)77g5gvasgx5yd{hXehf;d ifiBiyejhRgwhTgy6KibiFiMe~e25yebijh,4`f_2B0dhm1ch4eNh.cqh:i67_0W6-6Q6(6S6#1d0d6Vi?2O2Jcy1!2I6TbW0#0%0)0R04.