Aller au contenu

Algorithme glouton

Glouton

I. Découverte⚓︎

Glouton

Les algorithmes gloutons ou "greedy algorithms" forment une catégorie d’algorithmes permettant de donner une solution à des problèmes d’optimisation qui visent à maximiser/minimiser une quantité (GPS (plus court chemin, temps minimum, côut minimum) - plus petit temps d’exécution, meilleure organisation d’un emploi du temps, ....)

Principe d'un algorithme glouton

Un algorithme glouton est un algorithme qui suit le principe suivant :

  • résout le problème étape par étape, en faisant un choix optimum local dans l'espoir d'obtenir un résultat optimum global.
  • Ce choix d'étape n'est jamais remis en cause lors des étapes suivantes.

Un exemple⚓︎

grille

Sur la grille ci-dessus, on part de la case tout à gauche marquée de la lettre D. On souhaite atteindre les cases vides sur la partie droite en se déplaçant de case en case. Lorsqu'on est sur une case on peut se déplacer sur une des deux cases voisines situées sur la droite. On note S la somme de toutes les cases traversées.
Par exemple on peut effectuer la trajectoire suivante (on ne note pas la dernière case, qui est vide) : D - 7 – 5 – 3 – 5 – 7 – 9 – 8 – 9 – 6 qui conduit à S = 59.

🤔 On cherche à effectuer la trajectoire qui rend la somme S la plus petite possible. Pour cela, on va utiliser un algorithme glouton. * A chaque étape, nous choisissons le plus petit nombre. * Nous ne revenons jamais en arrière.

trajectoire gloutonne

Quelle trajectoire et quelle somme S obtenez-vous sur cet exemple avec votre algorithme glouton ?

Solution

D – 4 – 4 – 2 – 5 – 7 – 7 – 8 – 8 – 1

S = 46

Trajectoire optimale

Sur cette grille, en cherchant bien, la trajectoire optimale donne une somme S = 23. Déterminer le chemin correspondant

Solution

D - 4 - 4 - 3 - 2 - 3 - 1 - 3 - 1 - 2

Algorithme par force brute

Pour obtenir la solution optimale de façon certaine on souhaite trouver toutes les trajectoires possibles et calculer pour chacune d'elles la somme associée.
On doit faire 9 déplacements, et à chaque déplacement on a deux possibilités.
On a donc \(2^9=512\) trajectoires différentes. Il faudrait donc calculer la somme pour chacune de ces 512 trajectoires différentes.
🌵 Cette méthode est exacte, mais beaucoup plus coûteuse en termes de calculs.

II. Le rendu de monnaie⚓︎

Situation :
Dans le pays nommé New Land, la monnaie est constituée de pièces de 4 nl, 3 nl et 1 nl.
L’unité de monnaie est le newland, symbolisé par nl.
Alice et Bob sont deux commerçants qui disposent dans leur caisse de beaucoup de pièces de chaque type, mais ils veulent rendre la monnaie en utilisant le moins de pièces possible.

1. La méthode de Bob : algorithme glouton⚓︎

La méthode gloutonne

Bob a une idée : il se dit que plus il rendra de pièces de grandes valeurs, mieux cela sera.

Pour donner 10 nl :

  • Il donne une pièce de 4 nl, il lui reste à rendre 6 nl,
  • puis il donne une pièce de 4 nl, il lui reste à rendre 2 nl,
  • puis il donne une pièce de 1 nl, il lui reste à rendre 1 nl,
  • puis il donne une pièce de 1 nl, il lui reste à rendre 0 nl.

La fonction monnaie_Glouton prend en paramètre un entier qui est le montant en nl, et renvoie la liste des pièces correspondantes, obtenue par l'algorithme glouton.

Exemple

🐍 Console Python
>>>monnaie_Glouton(6)
[4, 1, 1]
>>>monnaie_Glouton(9)
[4, 4, 1]

Compléter ci-dessous

###(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

.128013f06S:d=4-yrE./opg2mcb1w937Cve[ l,8GP5)ti]kn;Iua(_sh050g0D0N0V0O0G0Y0F0u0G0V0Y0Y0h010N0O0q010406050Y0U0t0t0V0l0k040e0p0G0U0@0p0R050o0~1012140|0q04051k1d1n0o1k0|0g0O0C0,0.0:0=0Z0O0r0Z0G1B0Z0N0`050%0v0G0D1w0/0;011A1C1E1C0N1K1M1I0N0l1l0N0Z0,170Y0q0V0R0=0s011O1y010b0)0D0R0V0t0D1I1+1-1=1Q1^1M1{1}0`0a0F0K0l0p0q0p0Y0O1a0R0F0#1)0l0l0D0u2i1d200R1l0o1%2v1!1$1#1J0g220=1E0R1`2f1I1t1v0-1P2F0O2H0R0p2L1I0q2o1l2t2v2Z0}1,2j2N1?2S0l110G0`0F0w2s2%0{2$212)1Q2+2-2/0s2=1-2@2t2E012|0V2.040F0z302u0|332`0=36380F0i3c322%343i2/0L3m3e3o3g350p2,372/0d3t2^2(1x2{3y2}390A3D3f3G3h3I3A390I3M3v3O3x3z3j0y3U2_3W3q040w0c3m1o2X1d2L2y0g1$2D3w0u2T1~1l3:1m3.2#1e2?053_0#2Y3V2O350`0K0T0m0B0m0e3m0F3E340p0`0h4h4j3w0_040E3,3N480t0O0`3l41314p3W4r0H4o4v1?4x0`3b4B2u4D484F4H474J4y3)4u4T1Q4r0P3t3u3$480Q0`0#0b4X4(1?0x2/4.3F480R0b0`0t1b1{0O0D0X0J0G0p191b4?344r0W573w0R4{1b0%0R0N5b4E0`0M0f3t0F5p4i4I2{0`0V0X2o0R0g2o4S4/1Q4l044n4N394P2*5e5h1-5i5H065q5r4Y3h0`1E0Y0N0D5B4@1?5E5G2Z5S5C0=4r0E4#5P5R5J1Q4*040b3y5!3p0`0q4 0u5Z5H5*5#5D4;042Q5{5c4a4c4e4g5H5=5,0`5n5:5R5q6g015@0x1A1M693%5u5w1`5z615)6n5E020r0N0S5(2?635|045~2p6z425s6h046j2Z5Q6l6W6n5d045W5Y5j485E0n6%5K040V0q0q6x6+4Z0`5a6f6Q496L5 6O4C6`4r0M5o6W6l6Y6v5x6y6t6(4m7a6,5v785A626B0`0j7d5t6|6N735p6n5@2o0N0U0l1c7i6`6Z6#6~3d1d440D2v2W7H3/1u3;2y2B2w0V1L7K0o3:0|7U0$0(0*04.

2. La méthode d'Alice : La force brute⚓︎

La méthode par force brute

Alice est très méthodique. Elle va chercher toutes les possibilités dont la somme correspond, puis ensuite elle prendra celle qui correspond au plus petit nombre de pièces. Cette méthode, qui consiste à chercher toutes les possibilités s'appelle une méthode par force brute. Le nombre maximal de pièces est la somme totale (si on la donne uniquement avec des pièces de 1)

La fonction possibilites renvoie une liste de listes. Chaque liste donne une possibilité pour rendre le montant.
Par exemple [1, 0, 2] signifie qu'on rend une pièce de 4, 0 pièce de 3, et 2 pièces de 1.

Exemple

🐍 Console Python
>>> possibilites(6)
[[0, 0, 6], [0, 1, 3], [0, 2, 0], [1, 0, 2]]

La fonction monnaie_brute renvoie un tuple dont le premier élément est la liste optimale comme décrite ci-dessus, et le deuxième le nombre de pièces.

Exemple

🐍 Console Python
>>> monnaie_brute(6) 
([0, 2, 0], 2)

Compléter les fonctions :

###(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

.128013f06S:d=4yrE./èoxpg2mcb1w937Cvej[ l*8,+P5)ti]kn;Iua(_sh050g0E0Q0Y0R0I0#0H0v0I0Y0#0#0h010Q0R0r010406050#0X0u0u0Y0k0j040e0p0I0X0`0p0U050n111315170 0r04051n1g1q0n1n0 0g0R0D0/0;0?0^0$0R0s0$0I1E0$0Q0}050*0w0I0E1z0=0@011D1F1H1F0Q1N1P1L0Q0k1o0Q0$0/1a0#0r0Y0U0^0t011R1B010b0,0E0U0Y0u0E1L1.1:1^1T1{1P1~200}0a0H0N0k0p0r0p0#0R1d0U0H0(1,0k0k0E0v2l1g230U1o0n1*2y1%1)1(1M0g250^1H0U1}2i1L1w1y0:1S2I0R2K0U0p2O1L0r2r1o2w2y2$101/2m2Q1_2V0k140I0}0H0x2v2*0~2)242,1T2.2:2=0t2^1:2`2w2H012 0Y2;040H0A332x0 362}0^393b0H0i3f352*373l2=0O3p3h3r3j380p2/3a2=0d3w2{2+1A2~3B303c0B3G3i3J3k3L3D3c0K3P3y3R3A3C3m0z3X2|3Z3t040x0c3(3I2R3!3M0x2@1h2_3x3)3;3+0x323_343{3:2-3T3b0x3e413g3H3s460}0x3o4a3q3|453#4f3v4i434d4m3,3F4p4c3z3~3O4i1r2!1g2O2B0g1)2G3z0v2W211o4E1p4C2(4A4K0(2#3Y3;0T0}0(0b3p4w3Z0y2=4$3Q3}0b0}2h0?0R0w0,2k0E0#4+4W1_0|040Z4{4k2~0}0u1e0*0U0Q51441T4~0P0f3w0H5h0H4%3}0}2r0U0g2r3p5j4,1_0p0}0h5r5k4}0}0G0S5g5i5z1T4Y040b3B5y5t53040R5M4|1T0p4)5P1f4i5s5S3k0w5m1:0s0E5a374~504A5N3k54561:595Y5G0^5v040M5R520^0u0R4f5+3z5d5f5_5:010v0x0}030H0Y0X0H0r1b0.55585@6j0R0o0v4_0H0Z2o0x6j150H0E0q0E0u6k0E0P5E5i5F6a5I5K0k5 5b5;040F6Q375U0}2T6V4x5$040k5(5*5/5!015-653*5=6o586!3Z5|5~696,62646+606-0}5e6J6K755`016N5L6{700U0}0T6@3;6X5W7g2-6$6(0U5)6/3;6.6 6R386;575^2$5Z706_7k1T6}3,7q5A04734p757M766M6Y4#7b7u7d5P7H5T0}0J7W6S0N0W0l0C0l0e7!71040G7,7F3.7t5,0}5D7S6W0}6`7z777U6U7?3z5|7Z826:047$7(7*7,4~7/863;7F3^2(6a4~7_7~6a7C7`4x7e7,847,7U897)7+8f7I8e8j6|6304408D708l7D5{5w5x8q876n7x8L7-682$067N8Y7O6,7U5n5p6*8I7u5|0m8v0}0Y0r0r1}0g8c0}0Z8C2_7 6Y8^040L8T808 918P5l047f8A5c7^6I7L6L6,5I2r0Q0X0k5X8n8#5m8?5q4p4q3z5I4!7,5V5j9a3k4.046n1~0R0E0!0w0k1c8)8|8k8_8.9D5?6?9A7-7K8W6K8}044:2j1O4_8T5|8O9n7c4/2i9$4@0Q9(9U7s8*3s7w5@8 9d9X9f7c6$629m2_7A8+5w929{9T9 5h77796P962-0}1H0#9=9)5V6Zah5O9#4=1P4`9@0}8V3`8Yae7Q926$1i8 5.9_8r04akamaw7J9)0}020I0Q0VaD54apaI3Z4~ay428Za07T9p11aS0Y7ya5779*a9aK0Ral9Ma$a%a63sa2aXa/8oa8aq5#0}aFaNaH9N9oa?a^9}74aB6%0)9ka434a|669P9U8$4_0Xa,a.34774~959,7Ta~bj2xbv723G0n4T0E2y2ZbI4D1x4F2B2E2z0Y9%2y4E0 0n0(0*0,0#04.

Comparaison des méthodes⚓︎

Le moins de pièces possibles à rendre

Comparer le résultat obtenu pour la méthode par algorithme glouton, ou par force brute pour le cas d'un rendu de monnaie de 6 nl, 10 nl, 22nl . Que constatez vous ?

Solution
montant algorithme glouton (liste triée) algorithme par force brute (liste triée)
6 [1, 1, 4] [3, 3]
10 [1, 1, 4, 4] [3, 3, 4]
22 [1, 1, 4, 4, 4, 4, 4] [3, 3, 4, 4, 4, 4]

L'algorithme glouton donne un résultat très rapidement, mais il n'est pas forcément optimal.

3. Utilisation d'un algorithme glouton récursif⚓︎

On s’intéresse à un algorithme récursif qui permet de rendre la monnaie à partir d’une liste donnée de valeurs de pièces et de billets.

Le système monétaire est donné sous forme d’une liste :

VALEURS = [100, 50, 20, 10, 5, 2, 1].

On suppose que les pièces et billets sont disponibles sans limitation.

On cherche à donner la liste des valeurs à rendre pour une somme donnée en argument. L’algorithme utilisé est de type glouton.

Compléter le code Python ci-dessous. La fonction rendu_glouton prend en paramètre un entier a_rendre qui est la somme à rendre, et un entier rang, qui correspond à l'indice du tableau VALEURS à partir duquel on peut prendre les valeurs du tableau VALEURS. Cette fonction renvoie la liste des pièces à rendre par l'algorithme glouton. On garantit que la somme à rendre est supérieure ou égale à 1.

Exemple

🐍 Console Python
>>> rendu_glouton(67, 0)
[50, 10, 5, 2]
>>> rendu_glouton(291, 0)
[100, 100, 50, 20, 20, 1]
>>> rendu_glouton(291, 1)  # On ne peut utiliser que les valeurs de VALEURS[1:]
[50, 50, 50, 50, 50, 20, 20, 1]
>>> rendu_glouton(33, 3)  # On ne peut utiliser que les valeurs de VALEURS[3:]
[10, 10, 10, 2, 1]
Compléter

###(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

.128013f:6S0d=4-VyrAE/oUpg2mcb1w37Rve[ l,8+P5)ti]kn;Lua(_sh050g0E0O0W0P0H0Z0G0w0H0W0Z0Z0h010O0P0s010406050Z0V0v0v0W0m0l040e0q0H0V0^0q0S050p0 1113150}0s04051l1e1o0p1l0}0g0P0D0-0/0;0?0!0P0t0!0H1C0!0O0{050(0x0H0E1x0:0=011B1D1F1D0O1L1N1J0O0m1m0O0!0-180Z0s0W0S0?0u011P1z010b0*0E0S0W0v0E1J1,1.1?1R1_1N1|1~0{0a0G0L0m0q0s0q0Z0P1b0S0G0$1*0m0m0E0w2j1e210S1m0p1(2w1#1%1$1K0g230?1F0S1{2g1J1u1w0.1Q2G0P2I0S0q2M1J0s2p1m2u2w2!0~1-2k2O1@2T0m120H0{0y2t2(0|2%222*1R2,2.0{0u2=1.2@2u2F012|0W2/040A302v0}332`0?36380i3b322(343h0{0M3k3d3m3f350q2-370{0d3r2^2)1y2{3w2}040B3B3e3E3g3G3y040J3k1p2Y1e2M2z0g1%2E3u0w2U1 1m3W1n3U2$1f2?053$0$2Z3t3M010R0{0$0b3S3L2P010z0{0G3~3@400S0b0{2p0S0g0V0Y0t0H0q1a1c452_3^0`040X4l3D470{0W0Y4b0g2p4r344o0I3k443 2+4a1.0t4A3u4o0N0c3r0G4R4F461@3`040P3}3.314T4m4t044v4x4z4!2v4$4s1@0q0{0h0h4E3C340v0P0{0f4L4n0{4P4-0|4S564/344W2p0O0V0m1d54584M0{0F0Q4Q4S4`3u0S0{0D4_4G1R4=044^5g5o3^5q040k0n0U0o0r0C0e50404o0F5L4H040m4J5P1R4o5l5406565A404W4Y5t4U2{5r5)4%4;0{020H0O0T5y2!5h5B4u4w1{4y0E5-4:5V525m575`5$4a0%5d5f5_5#1@5N5U3g5,546e63045X6d5u0?5w0K613n694c4e4g4i0O4k6k6q014o4q6D5*6i4)5}4c4,6p6J015w0j6u5p6j2$6E4C6U5{5R5T6I5.6m0N65674V0{0E0+605z6Y645Y664R6l0?5a6a5e6!4(4x6y4h4j6c3/6@4p6h355|4+6=6X6Q6Z6?6Q5C5S0S4K7j6)6r0{6t7p620?4|2:7b4N3B0p3;0E2w2X7E3V1v3X2z2C2x0W1M7H0p3W0}7R0%0)0+04.
Astuce

Avez-vous pensé à la concaténation des tableaux ?

III. Le problème du sac à dos ("Knapsack Problem")⚓︎

sac

Le problème est celui-ci : vous disposez d'un sac d'une contenance limitée (sur le dessin ci-dessus, 15kg) et vous souhaitez maximiser la valeur totale des objets que vous mettez dans votre sac. Evidemment, la somme de leur masse ne doit pas dépasser 15 kg.

Ce problème (de la catégorie des problème dits d'analyse combinatoire) malgré sa simplicité est un problème majeur d'optimisation.

Actuellement :

  • On sait trouver LA meilleure solution, mais en explorant toutes les combinaisons une par une. Cette méthode par force brute est inapplicable si beaucoup d'objets sont en jeu.
  • On sait facilement trouver une bonne solution, mais pas forcément la meilleure, par exemple en adoptant une stratégie gloutonne.
  • On ne sait pas trouver facilement (en temps polynomial) la meilleure solution. Si vous y arrivez, 1 Million de $ sont pour vous.

1. Petite aide technique avant de commencer⚓︎

Tri par deuxième élément

Supposons qu'on dispose d'une liste mylist = [["A",3], ["B",2], ["C",8]].

Comment classer les éléments de cette liste par leur deuxième élément ???

Nous allons procéder en 2 temps :

  • création d'une fonction qui renvoie le deuxième élément d'un objet liste
  • tri de la liste grâce à cette fonction
Tester ci-dessous

###(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

Solution

Il s'affiche : [['C', 8], ['A', 3], ['B', 2]]

2. Retour sur le problème du sac à dos⚓︎

On considère un sac de 40 kg et les objets suivants :

objet A B C D E F
masse 13 12 8 10 14 18
valeur 700 500 200 300 600 800

Quels objets faut-il prendre ?

Stratégie gloutonne

  • on va classer les objets dans l'ordre décroissant de leur taux de valeur (taux de valeur = valeur / masse). Ainsi le premier élément de la liste sera celui ayant le meilleur rapport valeur/masse.
  • on prend le premier élément de la liste, puis le deuxième, etc., tant que le sac peut encore les contenir.
trier dans l'ordre décroissant de leur taux de valeur

###(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

.128013f:Sd=4yrE/oTxpg2Bmcb1wJ93vej[ l,OP5)ti]kn;ua(_shq050e0B0L0S0M0F0V0E0t0F0S0V0V0f010L0M0o010406050V0R0s0s0S0i0h040d0l0F0R0=0l0P050k0|0~10120`0o04051i1b1l0k1i0`0e0M0A0*0,0.0:0W0M0p0W0F1z0W0L0^050#0u0F0B1u0-0/011y1A1C1A0L1I1K1G0L0i1j0L0W0*150V0o0S0P0:0q011M1w010b0%0B0P0S0s0B1G1)1+1:1O1?1K1_1{0^0a0E0I0i0l0o0l0V0M180P0E0Z1%0i0i0B0t2g1b1~0P1j0k1#2t1Y1!1Z1H0e200:1C0P1^2d1G1r1t0+1N2D0M2F0P0l2J1G0o2m1j2r2t2X0{1*2h2L1;2Q0i0 0F0^0v2q2#0_2!1 2%1O2)2+0^0q2/1+2;2r2C012_0S2,040z2}2s0`302@0:33350g382 2#313e0^0J3h1m2V1b2J2w0e1!2B3c010t2R1|1j3s1k3q2Z1c2:053z0Z2W3j3x0O0^0Z0b3o3b1v1O0w0^0E3T3N3V3d0b0^0i0S183!2?3$010@040T3-2$3/0P0^0l0u0C0!3@313;0K0c3h3a3#2M013X040E4c3Z3H2~2=3^480V0e0^020X0R0l0L0Q4n4p4r4t4q0Q2m0P0A0l0M1L1K0E3*0o2c0i0L0E2U0M0n1o4C0e0)0e02030z0y0Q0R2h3|3~0L4w4v4o4x4)0Q454d3Z3U483P042m0L0R0i1a4f2s4;472(3{3}3 4~3M3.483;0D403x0s0M2{5c3/3;0N3h50581;0l0^0k5l4h3k534%5h590^5b565t5d5f042.5B4=1;5j45465n2^5v0!0V0U1Y4D0V5s5I1O5p040f5W512^0u0^0V0l4K0B0e5x5J0^3?5H5%3d0^0H0r0x0j0m0d5:1O3;0G5$5N5_040O0B0h610:5Z5#5@66323)3+0M0l6c3:0^64565m4i524^0B0A0B0i0V0B6n6e6n0O0t0^0m0i0R6B6g6t620^0K451b3K0B2t2U6U3r1s3t2w2z2u0S1J6X0k3s0`6+0!0$0(04.
Résoudre le problème par la méthode gloutonne

###(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

.128013f06S:d=4yr./oTxpg2mcb1w937vej[ l,8+P5)ti]kn;ua(_sh050g0C0N0U0O0G0X0F0u0G0U0X0X0h010N0O0q010406050X0T0t0t0U0k0j040e0n0G0T0?0n0R050m0}0 11130{0q04051j1c1m0m1j0{0g0O0B0+0-0/0;0Y0O0r0Y0G1A0Y0N0_050$0v0G0C1v0.0:011z1B1D1B0N1J1L1H0N0k1k0N0Y0+160X0q0U0R0;0s011N1x010b0(0C0R0U0t0C1H1*1,1;1P1@1L1`1|0_0a0F0K0k0n0q0n0X0O190R0F0!1(0k0k0C0u2h1c1 0R1k0m1$2u1Z1#1!1I0g210;1D0R1_2e1H1s1u0,1O2E0O2G0R0n2K1H0q2n1k2s2u2Y0|1+2i2M1=2R0k100G0_0F0w2r2$0`2#202(1P2*2,2.0s2;1,2?2s2D012{0U2-040F0z2 2t0{322_0;35370F0i3b312$333h2.0L3l3d3n3f340n2+362.0d3s2@2%1w2`3x2|380A3C3e3F3g3H3z380I3L3u3N3w3y3i0y3T2^3V3p040w0c3l1n2W1c2K2x0g1#2C3v0u2S1}1k3/1l3-2!1d2=053^0!2X3U2N010Q0_0!0b3+3M470x2.4d462)0b0_0X0U0u4i3#470^040V4q3E470R0_0n0v0D0#0X4w334t0H3l0F3D3o0_2d0O0g0X0W100p4G3v4t0M0f3s0F4$4L4e2)0_0v182P4K4M3v0n0_0h4/4)1P4t0E0P4#4%4:3$4O0n4Q4S4n4p40304(4j1P4=044@582t5a4r1=0t0O0_3*5g0`4%5i4x4*044B4D0N4S1Z0O0C4F5p5s335d5f2Y5F3v0R0v4m3x0N0C0g4W3V4t4v5p504y4A4C4E5T4s0_4J5E5Y5u0Q0C0j5%1=5H5;2`0_0k0U195@0;4I4^5b3g5_0C0B0C0k0X0C5}015?5X4_0;0Q0u0_0o0k0T696d61014Y4~4$5,1P49040b3x605j5^5v5#0N6z5t5c4g044.5+6e345!5x5z0k5B5D2!6M4t4!5p065r5r6t62044P4R0W5w0#6F5G4?6.5L6O6-6n6A5~0_0E6a5l0_2:6^6G6`044}6Y6!4 6M6v0O4c6L6o4z6(536*6,6E7d6_6b0_0J6;517g540W567q475d020G0N0S7w5u6)4S4U7D4`0_6X2Y6Z776!6$6N044,0?1b716/040l6a7f0U0q0q1_5S7W4X0_5W6U7e6?7k7/7m4{6}5m045o7?726p0_0P0M6r7O6s6M7f7F7u4o7I0;5d0J5I2=5K7r887j837Q6v2n0N0T0k7V5J7Q7f7T6K7M1c430C2u2V8B3.1t3:2x2A2v0U1K8E0m3/0{8O0#0%0)04.
Solution

Il faut donc choisir la combinaison A, F, C. Elle est bien valide (poids 39) et rapporte 1700.

Question

L'algorithme glouton nous a-t-il donné la solution optimale ?
Nous allons pour cela avoir recours à la force brute pour tester toutes les combinaisons possibles.

3. Force brute⚓︎

La méthode par force brute

Nous allons chercher toutes les possibilités pour lequel le poids total est inférieur au poids total autorisé, puis ensuite nous chercherons la possibilité qui donne la valeur totale maximale. Cette méthode, qui consiste à chercher toutes les possibilités s'appelle une méthode par force brute.

La fonction possibilites prend en paramètres la liste objets et l'entier poids qui est le poids maximal. Cette fonction renvoie une liste de listes. Chaque liste donne une possibilité de choix d'objets Par exemple [1, 1, 0, 1, 0, 1] signifie qu'on prend l'objet A, le B, pas le C, le D, pas le E et le F.

Exemple

On a :

🐍 Script Python
objets = [["A", 13, 700], ["B", 12, 500], ["C", 8, 200],\
["D", 10, 300], ["E", 14, 600], ["F", 18, 800]]
Appel de la fonction possibilites

🐍 Console Python
>>> possibilités(objets, 15)
[[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0],
[0, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 0],
[0, 1, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0]]
>>> 

La fonction butin_brut renvoie un tuple dont le premier élément est la liste optimale comme décrite ci-dessus, et le deuxième le magot obtenu.

Exemple

🐍 Console Python
>>> butin_brut(objets, 25)
([1, 0, 0, 1, 0, 0], 1000)

Compléter les fonctions :

###(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

.128013f06S:d=4yr./oxpg2mcb1w937vej[ l,8*P5)ti]kné;ua(_sh050g0B0M0U0N0F0X0E0t0F0U0X0X0h010M0N0p010406050X0T0s0s0U0k0j040e0n0F0T0?0n0Q050m0}0 11130{0p04051j1c1m0m1j0{0g0N0A0+0-0/0;0Y0N0q0Y0F1A0Y0M0_050$0u0F0B1v0.0:011z1B1D1B0M1J1L1H0M0k1k0M0Y0+160X0p0U0Q0;0r011N1x010b0(0B0Q0U0s0B1H1*1,1;1P1@1L1`1|0_0a0E0J0k0n0p0n0X0N190Q0E0!1(0k0k0B0t2h1c1 0Q1k0m1$2u1Z1#1!1I0g210;1D0Q1_2e1H1s1u0,1O2E0N2G0Q0n2K1H0p2n1k2s2u2Y0|1+2i2M1=2R0k100F0_0E0v2r2$0`2#202(1P2*2,2.0r2;1,2?2s2D012{0U2-040E0y2 2t0{322_0;35370E0i3b312$333h2.0K3l3d3n3f340n2+362.0d3s2@2%1w2`3x2|380z3C3e3F3g3H3z380H3L3u3N3w3y3i0x3T2^3V3p040v0c3!3E2N3W3I0v2:1d2=3t3#3-3%0v2~3=303@3,2)3P370v3a3}3c3D3o420_0v3k463m3^413X4b3r4e3 494i3(3B4l483v3`3K4r3M3_4a3(3S4w3U4y4o0v3Z4C4g3G4o0r3*4I404K3I0r3;2Y4m4t4z0r3|4U4s3$4X454!4x4h4R4d2!1p2W1c2K2x0g1#2C3v0t2S1}1k4=1l4:4.2!4{0!2X4D1=0P0_0!0b3l4#3-0w2.5d4*2`0b0_2d0/0N0u0(2g0R0X5i571P0^040V5v4J3g0_0n0u0C0#5u4e5e1=5y0G3l0E5L2`5m0n0N0g5J2!5j0;5y0L0f3s0E5)5Q5Z345m2n0Q0g2n5P5R0;0n0_0h5?5,5y0D0O5(5*5@0159040b3x5|5w5D040N4T2=5+6a010n5g6c1b4e6g5C340u0_0k1,0q0B5B4P5!0_5A5K5,0s0N0_4Z2=635#5%4l5*6N6o6y640_670k696p0Q0_0N6H306P336j6Y6m2Y6$4t6r046t0Q6v6x335y6B5Y6h6E6G6?3v6K616O6O63656T6V6Q6X6c4(6f636(6l773o6.6:6=6C6h6^6~3V6|046!2t6J0_5$71727y746S686n63790N4-7c5,7e2P7g6-6s6u6w7l6p7n7R6Q7q7s567S7v6L4U7y7%735,757C6+7E6Y4k7-7J6k7L7D5,0Q7i7P7o3-7T6`6p7W7}5M7!7x7(876,3V7+6U7^6h7F4q7;6h7K6*7I8e7{6;7Q806Q7 6I6D6F7r835x856M888B6N7.6/0B2d0Q0X8p8l6p5_045{8d7Z040D8x6b6d8U015N7M3$6Y7X7u045O8Q786Y7b308(8*8h6W6Y7H8/5}0_8;8L8,6c7:8t7m8{8!3_6Y8g918R608A8C8C8E2d5V0X0W2n8H8J941=8N8P8=786.1e8X6^8T7U3o6s8G1a9l9x6 0_9w8q9y6c9u0_9a9H3v8N0I8X795F5H0M5X988r9F9R6Y9K040O9G9X337q6e8_929%9m1P8b9;8V9@6i7?8k6#7E8n7k9N3V8s9.818v97a49Y040L0O0L869c7(7A6c5c8+9I9f5W9i9A8I8K9}7J0_020F0M0S9_79am9Wa86@0_7#3?afaI8995042V1_5;ar7tat040l9!040U0p0paO9$0V9)aD4t6Y9-aR9/8|as8e8$9$a.2taK2)8-a=az8@a{aka)8 a~9q9I0Na7a,99ad9ba^9=9z0M0T0k9|a@9e5/aP3s4V8a5a0Baja15f5h9D3$5l040u182P0W0u0k18a#aV9T5Ib28}al5U5W9$7wba9e2e2f1K0BaCbiaS9pbLb05nbU5r0M5tbGbvaLbI9VbKa/8?aMbNbX7Ya9b97$627_6.100o9_9o9_7q4Nb}5)8E2n0}aw0U0Mc35`9_5~9MaHb~6h9?a 8#041D0X0MaQ387d9{a|b@5obVb_8(aG3~7%8E116v0Qcfcp3-c4cN2)9s0~a#a%b78~cscu9$cVb`b49$cka(3V9PbH5GbJb-848SaV0Nc(c#6382c:8y9:cQbc667,b#cqc@c 5^cyd66q7O8ob,bs1=7qb6c$9Eaaacaec97*6Ybrd3aLcJ1_cMb39Oau0qaxazc00Uc2c|6z04cF3c8BcabW0Tcddvdr9nchd979cYcv06dKb 0_c1cg8OczdtcL7xah2nbebgci6AaVcbdN0$dPc*7~93dTdCdEdec}b|3?1c540B2uaN2u4 2v4@1c2yed0UbVe91t2?0m0!0$0(0X04.
Solution

La combinaison A-B-E est bien valide (poids total 39) et rapporte 1800

Mon info

La force brute a mis en évidence une combinaison meilleure que celle donnée par l'algorithme glouton.

En effet la combinaison A-B-E est bien valide (poids total 39) et rapporte 1800, donc 100 de mieux que la solution gloutonne.

Par contre, la force brute est inenvisageable pour si le nombre d'objets est grand, alors que la stratégie gloutonne reste très rapide.

4. Pour approfondir⚓︎

interstices

V. La chasse au trésor⚓︎

tresor

⌛ Elle arrive ...

VI. Conclusion⚓︎

Mon info

La stratégie gloutonne donne très rapidement des solutions satisfaisantes mais pas forcément optimales. Pour beaucoup de problèmes (dont le problème du sac à dos), la recherche d'une solution optimale sans passer par la force brute semble impossible (mais n'est pas démontrée).
Dans ce cas-là, la stratégie gloutonne peut être employée pour avoir vite et bien une solution convenable, même si peut-être non optimale. On dit que la stratégie gloutonne est une heuristique de résolution. On sait que ce n'est pas forcément optimal, mais faute de mieux, on s'en contente...

VII. Crédits⚓︎

Le III. La résolution gloutonne du problème du sac à dos est une mise en forme du travail de Gilles Lassus.