@@ -27,10 +27,43 @@ Séance 4
2727++++++++
2828
2929Nous garderons les dames et l'algortithme minimax pour une autre fois peut être.
30-
31- * :ref: `Distance d'édition <nbl-practice-years-2023-editdist >`,
32- * :ref: `Pivot de Gauss <nbl-practice-years-2023-pivot_gauss >`,
33- cet algorithme est la première étage pour inverser une matrice
30+ Cette séance à propos de la programmation dynamique.
31+ Le premier exercice consiste à déterminer le nombre minimal de pièces
32+ de monnaie pour écrire un montant et de retrouver la séquence minimale
33+ de pièces. On considère les pièces ``[1, 2, 4, 5] ``.
34+
35+ .. runpython ::
36+ :showcode:
37+
38+ def ecriture_minimale(n):
39+ pieces = [1, 2, 4, 5]
40+ min_pieces = [None for i in range(n+1)]
41+ predecessor = [None for i in range(n+1)]
42+ min_pieces[0] = 1
43+ for p in pieces:
44+ min_pieces[p] = 1
45+ predecessor[p] = p
46+ for i in range(n+1):
47+ if min_pieces[i] is None:
48+ # écriture impossible
49+ continue
50+ for p in pieces:
51+ if i + p > n:
52+ break
53+ m = min_pieces[i] + 1
54+ if min_pieces[i + p] is None or m < min_pieces[i + p]:
55+ min_pieces[i + p] = m
56+ predecessor[i + p] = p
57+ composition = []
58+ while n > 0:
59+ composition.append(predecessor[n])
60+ n -= predecessor[n]
61+ return min_pieces[n], composition
62+
63+ print(ecriture_minimale(99))
64+
65+ On bascule ensuite vers la
66+ :ref: `Distance d'édition <nbl-practice-years-2023-editdist >`.
3467
3568A propos de la distance d'édition, voir aussi
3669:ref: `Distance d'édition <nbl-practice-algo-base-exercice_edit_distance >` ou encore
@@ -39,21 +72,138 @@ A propos de la distance d'édition, voir aussi
3972Séance 5
4073++++++++
4174
42- * :ref: `Le voyageur de commerce <nbl-practice-algo-base-tsp_simplifie >` ou
43- `problème du sac à dos <https://fr.wikipedia.org/wiki/Probl%C3%A8me_du_sac_%C3%A0_dos >`_
44- * :ref: `Recherche à base de préfixes <nbl-practice-years-2023-prefix_search >`
45-
46- Autres variations autour du problème du voyageur de commerce,
47- ou TSP pour Travelling Salesman Problem
48- ou encore circuit hamiltonien: :ref: `l-tsp_kohonen `, :ref: `l-tsp_kruskal `.
75+ * :ref: `burrowswheelerrst `
76+ * :ref: `Code de Vigenère <nbl-practice-algo-compose-vigenere >`
4977
5078Séance 6
5179++++++++
5280
5381* :ref: `Tracer une pyramide bigarrée <nbl-practice-tds-base-pyramide_bigarree >`
5482* :ref: `Expressions régulières <nbl-practice-py-base-exercice_regex >`,
5583 :ref: `Modules, fichiers, expression régulières <nbl-practice-tds-base-module_file_regex >`
56-
84+ * :ref: `Le voyageur de commerce <nbl-practice-algo-base-tsp_simplifie >` ou
85+ `problème du sac à dos <https://fr.wikipedia.org/wiki/Probl%C3%A8me_du_sac_%C3%A0_dos >`_
86+
87+ Evocation de la :ref: `Recherche à base de préfixes <nbl-practice-years-2023-prefix_search >`
88+ en terme algorithmique.
89+
90+ Autres variations autour du problème du voyageur de commerce,
91+ ou TSP pour Travelling Salesman Problem
92+ ou encore circuit hamiltonien: :ref: `l-tsp_kohonen `, :ref: `l-tsp_kruskal `.
93+ Quelques bouts de code écrit durant la séance.
94+ Tout d'abord les expressions régulières.
95+
96+ .. runpython ::
97+ :showcode:
98+
99+ import re
100+
101+ reg = re.compile("(-?[1-9][ 0-9]{0,16}([.,][0-9]{0,4})? *(€|(euros))?)")
102+ text = "Le montant de 3000 euros auquel on a ôté 5,4 euros."
103+ print(reg.findall(text))
104+
105+ reg = re.compile("([0-9]{1,2}[-/][0-9]{1,2}[-/][0-9]{2,4})")
106+ text = "9/10/2024 09-10-24"
107+ print(reg.findall(text))
108+
109+ Ensuite la pyramide.
110+
111+ .. runpython ::
112+ :rst:
113+ :showcode:
114+
115+ import math
116+ import os
117+ import matplotlib.pyplot as plt
118+
119+ fig, ax = plt.subplots(1, 1)
120+ x, y, colors = [], [], []
121+ cs = ["r", "b", "g"]
122+ for i in range(0, 5):
123+ for j in range(0, 5):
124+ x.append(i - j * 0.5)
125+ y.append(j * math.sqrt(3) / 2)
126+ colors.append(cs[(2*i -j) % 3])
127+ size = [2000 for c in x]
128+ ax.scatter(x, y, s=size, c=colors, alpha=0.5)
129+ fig.savefig(os.path.join(__WD__, "pyramide.png"))
130+
131+ text = ".. image:: pyramide.png"
132+ print(text)
133+
134+ Ensuite le voyageur de commerce.
135+
136+ .. runpython ::
137+ :rst:
138+ :showcode:
139+
140+ import itertools
141+ import numpy as np
142+ import matplotlib.pyplot as plt
143+
144+ def show(villes):
145+ fig, ax = plt.subplots(1, 1)
146+ x = villes[:, 0].tolist() + [villes[0, 0]]
147+ y = villes[:, 1].tolist() + [villes[0, 1]]
148+ ax.plot(x, y, "o-")
149+ ax.set_title(f"longueur {distance(villes)}")
150+ return fig, ax
151+
152+ def distance(villes):
153+ # distance sans boucle
154+ dall = villes[1:, :] - villes[:-1, :]
155+ d = (dall[:, 0] ** 2 + dall[:, 1] ** 2) ** 0.5
156+ dlast = villes[0, :] - villes[-1, :]
157+ d1 = (dlast[0] ** 2 + dlast[1] ** 2) ** 0.5
158+ return d.sum() + d1
159+
160+ def solution_permutations(villes):
161+ bestp = list(range(villes.shape[0]))
162+ bestd = distance(villes)
163+ for p in itertools.permutations(list(range(villes.shape[0]))):
164+ v2 = villes[list(p), :]
165+ d2 = distance(v2)
166+ if d2 < bestd:
167+ bestd = d2
168+ bestp = list(p)
169+ return villes[bestp, :]
170+
171+ def solution_croisement(villes):
172+ bestd = distance(villes)
173+ bestv = villes
174+ for i in range(0, villes.shape[0]):
175+ for j in range(i+2, villes.shape[0]):
176+ p = list(range(villes.shape[0]))
177+ if i > 0:
178+ p[i:j] = p[j-1:i-1: -1]
179+ else:
180+ p[i:j] = p[j-1::-1]
181+ v2 = bestv[p, :]
182+ d2 = distance(v2)
183+ if d2 < bestd:
184+ bestd = d2
185+ bestv = v2
186+ return bestv
187+
188+ villes = np.random.rand(8, 2)
189+ print("distance initiale", distance(villes))
190+
191+ # solution naive
192+ print("-- optimisation gourmande...")
193+ optim = solution_permutations(villes)
194+ print("-- optimisation gourmande:", distance(optim))
195+
196+ print("-- optimisation plus rapide mais approchée...")
197+ optim = solution_croisement(villes)
198+ print("-- optimisation plus rapide mais approchée", distance(optim))
199+
200+ # graph
201+ fig, ax = show(optim)
202+ fig.savefig(os.path.join(__WD__, "tsp_simple.png"))
203+
204+ text = ".. image:: tsp_simple.png"
205+ print(text)
206+
57207Séance 7
58208++++++++
59209
@@ -68,6 +218,8 @@ Séance 8
68218++++++++
69219
70220* :ref: `Optimisation de la note moyenne <nbl-practice-years-2023-bareme_note_optimisation >`
221+ * :ref: `Pivot de Gauss <nbl-practice-years-2023-pivot_gauss >`,
222+ cet algorithme est la première étage pour inverser une matrice
71223
72224TD noté 1h30 en seconde partie.
73225Classes et un algorithme.
0 commit comments