Skip to content

Commit 190ab8c

Browse files
authored
Update session 4 (#74)
* menu * latexé * add session 5 * fix style * sess6 * remove tix
1 parent 9ee66a6 commit 190ab8c

File tree

15 files changed

+413
-140
lines changed

15 files changed

+413
-140
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ _doc/sg_execution_times.rst
3939
_doc/CHANGELOGS.rst
4040
_doc/LICENSE.txt
4141
_doc/auto_examples/*
42+
_doc/articles/2024/pyramide.png
43+
_doc/articles/2024/tsp_simple.png
4244
_doc/examples/**/plot_*.png
4345
_doc/examples/**/plot_*.xlsx
4446
_doc/examples/prog/*.proto

_doc/algorithm_culture.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ Catalogue d'algorithmes
178178
* `n-grammes <http://fr.wikipedia.org/wiki/N-gramme>`_ **déf**
179179
* `Algorithme d'Aho-Corasick <http://fr.wikipedia.org/wiki/Algorithme_d%27Aho-Corasick>`_ **algo**,
180180
voir aussi `Commentz-Walter <https://en.wikipedia.org/wiki/Commentz-Walter_algorithm>`_
181-
* `Transformée de Burrows-Wheeler <http://fr.wikipedia.org/wiki/Transform%C3%A9e_de_Burrows-Wheeler>`_ **algo**
181+
* `Transformée de Burrows-Wheeler <http://fr.wikipedia.org/wiki/Transform%C3%A9e_de_Burrows-Wheeler>`_ **algo**,
182+
voir :ref:`burrowswheelerrst`
182183
* `algorithme Apriori <https://en.wikipedia.org/wiki/Apriori_algorithm>`_ : apprentissage de règles d'associations **algo**
183184
* `Boyer–Moore string-search algorithm <https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string-search_algorithm>`_
184185
* Optimisation

_doc/articles/2024/2024-11-31-route2024.rst

Lines changed: 164 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,43 @@ Séance 4
2727
++++++++
2828

2929
Nous 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

3568
A 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
3972
Sé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

5078
Sé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+
57207
Sé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

72224
TD noté 1h30 en seconde partie.
73225
Classes et un algorithme.

_doc/c_expose/finance/finance_autostrat.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1202,7 +1202,7 @@ Le slippage est ici modélisé comme une constante mais il serait sans
12021202
doute plus judicieux de l'ajuster en fonction d'une variabilité locale
12031203
(par rapport à la différence High - Low) qui pourrait pénaliser davantage
12041204
la stratégie en temps de crise. Par exemple, lors de la vente d'une action
1205-
au prix :math:`p`, on considèrera le prix :math:`p - \alpha \abs{p} - \beta`.
1205+
au prix :math:`p`, on considèrera le prix :math:`p - \alpha \\left| p \\right| - \beta`.
12061206
:math:`\alpha` est le coût de transaction est proportionnelle au prix,
12071207
:math:`\beta` est le slippage qui s'exprime en un multiple
12081208
entier du tick (donc différent pour chaque action).

_doc/c_ml/rappel.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ On exprime cette propriété comme suit en terme mathématique.
4242

4343
.. math::
4444
45-
\forall \epsilon >0, \exists \eta, \forall x,y \in I, \; \abs{x-y} < \eta \Rightarrow \abs{f(x) -f(y)} < \epsilon
45+
\forall \epsilon >0, \exists \eta, \forall x,y \in I, \;
46+
\left| x - y \right| < \eta \Rightarrow \left| f(x) -f(y) \right| < \epsilon
4647
4748
On résume visuellement cette propriété comme suit.
4849
La fonction de gauche est continue, celle de droite ne l'est pas.
@@ -110,7 +111,7 @@ l'angle qui les sépare.
110111

111112
.. math::
112113
113-
<X,Y> = \sum_{i=1}^n x_i y_i = \norm{X}\norm{Y} \cos(X,Y)
114+
<X,Y> = \sum_{i=1}^n x_i y_i = \left\Vert X \right\Vert \left\Vert Y \right\Vert \cos(X,Y)
114115
115116
.. index:: norme, distance
116117

@@ -122,13 +123,13 @@ vecteurs. La distance euclidienne est nommé *norme L2* :
122123

123124
.. math::
124125
125-
\norm{X}_2 = \sqrt{<X,X>}
126+
\\left\\Vert X \\right\\Vert_2 = \sqrt{<X,X>}
126127
127128
La norme L1 utilise les valeurs absolues :
128129

129130
.. math::
130131
131-
\norm{X}_1 = \sum_{i=1}^n \abs{x_i}
132+
\left\Vert X \right\Vert_1 = \sum_{i=1}^n \left | x_i \right |
132133
133134
Ce sont les deux principales normes utilisées en
134135
:epkg:`machine learning`.

_doc/conf.py

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -126,30 +126,29 @@
126126
# next
127127

128128
preamble = """
129-
\\usepackage{etex}
130-
\\usepackage{fixltx2e} % LaTeX patches, \\textsubscript
131-
\\usepackage{cmap} % fix search and cut-and-paste in Acrobat
132-
\\usepackage[raccourcis]{fast-diagram}
133-
\\usepackage{titlesec}
134-
\\usepackage{amsmath}
135-
\\usepackage{amssymb}
136-
\\usepackage{amsfonts}
137-
\\usepackage{graphics}
138-
\\usepackage{epic}
139-
\\usepackage{eepic}
140-
%\\usepackage{pict2e}
129+
%%% \\usepackage{etex}
130+
%%% \\usepackage{fixltx2e} % LaTeX patches, \\textsubscript
131+
%%% \\usepackage{cmap} % fix search and cut-and-paste in Acrobat
132+
%%% \\usepackage[raccourcis]{fast-diagram}
133+
%%% \\usepackage{titlesec}
134+
%%% \\usepackage{amsmath}
135+
%%% \\usepackage{amssymb}
136+
%%% \\usepackage{amsfonts}
137+
%%% \\usepackage{graphics}
138+
%%% \\usepackage{epic}
139+
%%% \\usepackage{eepic}
140+
%%% \\usepackage{pict2e}
141141
%%% Redefined titleformat
142-
\\setlength{\\parindent}{0cm}
143-
\\setlength{\\parskip}{1ex plus 0.5ex minus 0.2ex}
142+
%%% \\setlength{\\parindent}{0cm}
143+
%%% \\setlength{\\parskip}{1ex plus 0.5ex minus 0.2ex}
144144
\\newcommand{\\hsp}{\\hspace{20pt}}
145145
\\newcommand{\\acc}[1]{\\left\\{#1\\right\\}}
146146
\\newcommand{\\cro}[1]{\\left[#1\\right]}
147147
\\newcommand{\\pa}[1]{\\left(#1\\right)}
148148
\\newcommand{\\R}{\\mathbb{R}}
149149
\\newcommand{\\HRule}{\\rule{\\linewidth}{0.5mm}}
150-
%\\titleformat{\\chapter}[hang]{\\Huge\\bfseries\\sffamily}{\\thechapter\\hsp}{0pt}{\\Huge\\bfseries\\sffamily}
151-
152-
\\usepackage[all]{xy}
150+
%%% \\titleformat{\\chapter}[hang]{\\Huge\\bfseries\\sffamily}{\\thechapter\\hsp}{0pt}{\\Huge\\bfseries\\sffamily}
151+
%%% \\usepackage[all]{xy}
153152
\\newcommand{\\vecteur}[2]{\\pa{#1,\\dots,#2}}
154153
\\newcommand{\\N}[0]{\\mathbb{N}}
155154
\\newcommand{\\indicatrice}[1]{ {1\\!\\!1}_{\\acc{#1}} }
@@ -322,6 +321,7 @@
322321
"tkinter.Entry.insert": "https://tkdocs.com/pyref/entry.html",
323322
"tkinter.Event": "https://tkdocs.com/tutorial/eventloop.html",
324323
"tkinter.Frame": "https://tkdocs.com/tutorial/widgets.html#frame",
324+
"tkinter.filedialog": "https://docs.python.org/3/library/dialog.html#module-tkinter.filedialog",
325325
"tkinter.IntVar": "https://tkdocs.com/pyref/intvar.html",
326326
"tkinter.Label": "https://tkdocs.com/tutorial/widgets.html#label",
327327
"tkinter.Label.after_cancel": "https://tkdocs.com/tutorial/widgets.html#label",
@@ -354,8 +354,6 @@
354354
"tkinter.Toplevel.resizable": "https://tkdocs.com/pyref/toplevel.html",
355355
"tkinter.Toplevel.title": "https://tkdocs.com/pyref/toplevel.html",
356356
"tkinter.Toplevel.withdraw": "https://tkdocs.com/pyref/toplevel.html",
357-
"tkinter.tix.DirTree": "https://pythonbasics.org/tkinter-filedialog/",
358-
"tkinter.tix.FileSelectBox": "https://pythonbasics.org/tkinter-filedialog/",
359357
"tkinter.ttk.Combobox": "https://tkdocs.com/pyref/ttk_combobox.html",
360358
"tkinter.ttk.Notebook": "https://tkdocs.com/pyref/ttk_notebook.html",
361359
"tkinter.ttk.Progressbar": "https://tkdocs.com/pyref/ttk_progressbar.html",
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# coding: utf-8
2+
"""
3+
4+
.. _burrowswheelerrst:
5+
6+
==============================
7+
Transformée de Burrows Wheeler
8+
==============================
9+
10+
La transformée de `Burrows-Wheeler
11+
<https://fr.wikipedia.org/wiki/Transform%C3%A9e_de_Burrows-Wheeler>`_
12+
transforme un mot en un autre mot composée des mêmes lettres
13+
mais aux propriétés statistiques différentes.
14+
Les deux fonctions qui suivent implémentent les algorithmes
15+
décrits sur la page Wikipedia.
16+
17+
Codage
18+
======
19+
"""
20+
21+
22+
def code_burrows(text: str) -> str:
23+
# étape 1: matrice décalée
24+
decalages = ["".join(text[i:] + text[:i]) for i in range(len(text))]
25+
# étape 2: tri
26+
decalages.sort()
27+
# on cherche la position du mot initial
28+
pos = decalages.index(text)
29+
# fin
30+
return pos, "".join(decalages[i][-1] for i in range(len(text)))
31+
32+
33+
print(code_burrows("ENSAE"))
34+
35+
############################################
36+
# Décodage
37+
# ========
38+
39+
40+
def decode_burrows(pos, last_col):
41+
first_col = sorted(last_col)
42+
two_cols = list(zip(last_col, first_col))
43+
for _i in range(2, len(last_col)):
44+
two_cols.sort()
45+
two_cols = [(c, *t) for c, t in zip(last_col, two_cols)]
46+
two_cols.sort()
47+
return "".join(two_cols[pos])
48+
49+
50+
print(decode_burrows(2, "SAEEN"))
51+
52+
##############################
53+
# On vérifie que le code vérifie des tests unitaires simples.
54+
55+
56+
def test_burrows():
57+
for mot in ["AA", "AB", "BA", "ABC", "ACB", "BCA", "BAC", "ENSAE"]:
58+
pos, code = code_burrows(mot)
59+
decode = decode_burrows(pos, code)
60+
assert (
61+
decode == mot
62+
), f"problème avec {mot}, decode={decode}, pos={pos}, code={code}"
63+
64+
65+
test_burrows()

0 commit comments

Comments
 (0)