Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ _doc/sg_execution_times.rst
_doc/CHANGELOGS.rst
_doc/LICENSE.txt
_doc/auto_examples/*
_doc/articles/2024/pyramide.png
_doc/articles/2024/tsp_simple.png
_doc/examples/**/plot_*.png
_doc/examples/**/plot_*.xlsx
_doc/examples/prog/*.proto
Expand Down
3 changes: 2 additions & 1 deletion _doc/algorithm_culture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ Catalogue d'algorithmes
* `n-grammes <http://fr.wikipedia.org/wiki/N-gramme>`_ **déf**
* `Algorithme d'Aho-Corasick <http://fr.wikipedia.org/wiki/Algorithme_d%27Aho-Corasick>`_ **algo**,
voir aussi `Commentz-Walter <https://en.wikipedia.org/wiki/Commentz-Walter_algorithm>`_
* `Transformée de Burrows-Wheeler <http://fr.wikipedia.org/wiki/Transform%C3%A9e_de_Burrows-Wheeler>`_ **algo**
* `Transformée de Burrows-Wheeler <http://fr.wikipedia.org/wiki/Transform%C3%A9e_de_Burrows-Wheeler>`_ **algo**,
voir :ref:`burrowswheelerrst`
* `algorithme Apriori <https://en.wikipedia.org/wiki/Apriori_algorithm>`_ : apprentissage de règles d'associations **algo**
* `Boyer–Moore string-search algorithm <https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string-search_algorithm>`_
* Optimisation
Expand Down
176 changes: 164 additions & 12 deletions _doc/articles/2024/2024-11-31-route2024.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,43 @@ Séance 4
++++++++

Nous garderons les dames et l'algortithme minimax pour une autre fois peut être.

* :ref:`Distance d'édition <nbl-practice-years-2023-editdist>`,
* :ref:`Pivot de Gauss <nbl-practice-years-2023-pivot_gauss>`,
cet algorithme est la première étage pour inverser une matrice
Cette séance à propos de la programmation dynamique.
Le premier exercice consiste à déterminer le nombre minimal de pièces
de monnaie pour écrire un montant et de retrouver la séquence minimale
de pièces. On considère les pièces ``[1, 2, 4, 5]``.

.. runpython::
:showcode:

def ecriture_minimale(n):
pieces = [1, 2, 4, 5]
min_pieces = [None for i in range(n+1)]
predecessor = [None for i in range(n+1)]
min_pieces[0] = 1
for p in pieces:
min_pieces[p] = 1
predecessor[p] = p
for i in range(n+1):
if min_pieces[i] is None:
# écriture impossible
continue
for p in pieces:
if i + p > n:
break
m = min_pieces[i] + 1
if min_pieces[i + p] is None or m < min_pieces[i + p]:
min_pieces[i + p] = m
predecessor[i + p] = p
composition = []
while n > 0:
composition.append(predecessor[n])
n -= predecessor[n]
return min_pieces[n], composition

print(ecriture_minimale(99))

On bascule ensuite vers la
:ref:`Distance d'édition <nbl-practice-years-2023-editdist>`.

A propos de la distance d'édition, voir aussi
:ref:`Distance d'édition <nbl-practice-algo-base-exercice_edit_distance>` ou encore
Expand All @@ -39,21 +72,138 @@ A propos de la distance d'édition, voir aussi
Séance 5
++++++++

* :ref:`Le voyageur de commerce <nbl-practice-algo-base-tsp_simplifie>` ou
`problème du sac à dos <https://fr.wikipedia.org/wiki/Probl%C3%A8me_du_sac_%C3%A0_dos>`_
* :ref:`Recherche à base de préfixes <nbl-practice-years-2023-prefix_search>`

Autres variations autour du problème du voyageur de commerce,
ou TSP pour Travelling Salesman Problem
ou encore circuit hamiltonien: :ref:`l-tsp_kohonen`, :ref:`l-tsp_kruskal`.
* :ref:`burrowswheelerrst`
* :ref:`Code de Vigenère <nbl-practice-algo-compose-vigenere>`

Séance 6
++++++++

* :ref:`Tracer une pyramide bigarrée <nbl-practice-tds-base-pyramide_bigarree>`
* :ref:`Expressions régulières <nbl-practice-py-base-exercice_regex>`,
:ref:`Modules, fichiers, expression régulières <nbl-practice-tds-base-module_file_regex>`

* :ref:`Le voyageur de commerce <nbl-practice-algo-base-tsp_simplifie>` ou
`problème du sac à dos <https://fr.wikipedia.org/wiki/Probl%C3%A8me_du_sac_%C3%A0_dos>`_

Evocation de la :ref:`Recherche à base de préfixes <nbl-practice-years-2023-prefix_search>`
en terme algorithmique.

Autres variations autour du problème du voyageur de commerce,
ou TSP pour Travelling Salesman Problem
ou encore circuit hamiltonien: :ref:`l-tsp_kohonen`, :ref:`l-tsp_kruskal`.
Quelques bouts de code écrit durant la séance.
Tout d'abord les expressions régulières.

.. runpython::
:showcode:

import re

reg = re.compile("(-?[1-9][ 0-9]{0,16}([.,][0-9]{0,4})? *(€|(euros))?)")
text = "Le montant de 3000 euros auquel on a ôté 5,4 euros."
print(reg.findall(text))

reg = re.compile("([0-9]{1,2}[-/][0-9]{1,2}[-/][0-9]{2,4})")
text = "9/10/2024 09-10-24"
print(reg.findall(text))

Ensuite la pyramide.

.. runpython::
:rst:
:showcode:

import math
import os
import matplotlib.pyplot as plt

fig, ax = plt.subplots(1, 1)
x, y, colors = [], [], []
cs = ["r", "b", "g"]
for i in range(0, 5):
for j in range(0, 5):
x.append(i - j * 0.5)
y.append(j * math.sqrt(3) / 2)
colors.append(cs[(2*i -j) % 3])
size = [2000 for c in x]
ax.scatter(x, y, s=size, c=colors, alpha=0.5)
fig.savefig(os.path.join(__WD__, "pyramide.png"))

text = ".. image:: pyramide.png"
print(text)

Ensuite le voyageur de commerce.

.. runpython::
:rst:
:showcode:

import itertools
import numpy as np
import matplotlib.pyplot as plt

def show(villes):
fig, ax = plt.subplots(1, 1)
x = villes[:, 0].tolist() + [villes[0, 0]]
y = villes[:, 1].tolist() + [villes[0, 1]]
ax.plot(x, y, "o-")
ax.set_title(f"longueur {distance(villes)}")
return fig, ax

def distance(villes):
# distance sans boucle
dall = villes[1:, :] - villes[:-1, :]
d = (dall[:, 0] ** 2 + dall[:, 1] ** 2) ** 0.5
dlast = villes[0, :] - villes[-1, :]
d1 = (dlast[0] ** 2 + dlast[1] ** 2) ** 0.5
return d.sum() + d1

def solution_permutations(villes):
bestp = list(range(villes.shape[0]))
bestd = distance(villes)
for p in itertools.permutations(list(range(villes.shape[0]))):
v2 = villes[list(p), :]
d2 = distance(v2)
if d2 < bestd:
bestd = d2
bestp = list(p)
return villes[bestp, :]

def solution_croisement(villes):
bestd = distance(villes)
bestv = villes
for i in range(0, villes.shape[0]):
for j in range(i+2, villes.shape[0]):
p = list(range(villes.shape[0]))
if i > 0:
p[i:j] = p[j-1:i-1:-1]
else:
p[i:j] = p[j-1::-1]
v2 = bestv[p, :]
d2 = distance(v2)
if d2 < bestd:
bestd = d2
bestv = v2
return bestv

villes = np.random.rand(8, 2)
print("distance initiale", distance(villes))

# solution naive
print("-- optimisation gourmande...")
optim = solution_permutations(villes)
print("-- optimisation gourmande:", distance(optim))

print("-- optimisation plus rapide mais approchée...")
optim = solution_croisement(villes)
print("-- optimisation plus rapide mais approchée", distance(optim))

# graph
fig, ax = show(optim)
fig.savefig(os.path.join(__WD__, "tsp_simple.png"))

text = ".. image:: tsp_simple.png"
print(text)

Séance 7
++++++++

Expand All @@ -68,6 +218,8 @@ Séance 8
++++++++

* :ref:`Optimisation de la note moyenne <nbl-practice-years-2023-bareme_note_optimisation>`
* :ref:`Pivot de Gauss <nbl-practice-years-2023-pivot_gauss>`,
cet algorithme est la première étage pour inverser une matrice

TD noté 1h30 en seconde partie.
Classes et un algorithme.
Expand Down
2 changes: 1 addition & 1 deletion _doc/c_expose/finance/finance_autostrat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,7 @@ Le slippage est ici modélisé comme une constante mais il serait sans
doute plus judicieux de l'ajuster en fonction d'une variabilité locale
(par rapport à la différence High - Low) qui pourrait pénaliser davantage
la stratégie en temps de crise. Par exemple, lors de la vente d'une action
au prix :math:`p`, on considèrera le prix :math:`p - \alpha \abs{p} - \beta`.
au prix :math:`p`, on considèrera le prix :math:`p - \alpha \\left| p \\right| - \beta`.
:math:`\alpha` est le coût de transaction est proportionnelle au prix,
:math:`\beta` est le slippage qui s'exprime en un multiple
entier du tick (donc différent pour chaque action).
Expand Down
9 changes: 5 additions & 4 deletions _doc/c_ml/rappel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ On exprime cette propriété comme suit en terme mathématique.

.. math::

\forall \epsilon >0, \exists \eta, \forall x,y \in I, \; \abs{x-y} < \eta \Rightarrow \abs{f(x) -f(y)} < \epsilon
\forall \epsilon >0, \exists \eta, \forall x,y \in I, \;
\left| x - y \right| < \eta \Rightarrow \left| f(x) -f(y) \right| < \epsilon

On résume visuellement cette propriété comme suit.
La fonction de gauche est continue, celle de droite ne l'est pas.
Expand Down Expand Up @@ -110,7 +111,7 @@ l'angle qui les sépare.

.. math::

<X,Y> = \sum_{i=1}^n x_i y_i = \norm{X}\norm{Y} \cos(X,Y)
<X,Y> = \sum_{i=1}^n x_i y_i = \left\Vert X \right\Vert \left\Vert Y \right\Vert \cos(X,Y)

.. index:: norme, distance

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

.. math::

\norm{X}_2 = \sqrt{<X,X>}
\\left\\Vert X \\right\\Vert_2 = \sqrt{<X,X>}

La norme L1 utilise les valeurs absolues :

.. math::

\norm{X}_1 = \sum_{i=1}^n \abs{x_i}
\left\Vert X \right\Vert_1 = \sum_{i=1}^n \left | x_i \right |

Ce sont les deux principales normes utilisées en
:epkg:`machine learning`.
Expand Down
36 changes: 17 additions & 19 deletions _doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,30 +126,29 @@
# next

preamble = """
\\usepackage{etex}
\\usepackage{fixltx2e} % LaTeX patches, \\textsubscript
\\usepackage{cmap} % fix search and cut-and-paste in Acrobat
\\usepackage[raccourcis]{fast-diagram}
\\usepackage{titlesec}
\\usepackage{amsmath}
\\usepackage{amssymb}
\\usepackage{amsfonts}
\\usepackage{graphics}
\\usepackage{epic}
\\usepackage{eepic}
%\\usepackage{pict2e}
%%% \\usepackage{etex}
%%% \\usepackage{fixltx2e} % LaTeX patches, \\textsubscript
%%% \\usepackage{cmap} % fix search and cut-and-paste in Acrobat
%%% \\usepackage[raccourcis]{fast-diagram}
%%% \\usepackage{titlesec}
%%% \\usepackage{amsmath}
%%% \\usepackage{amssymb}
%%% \\usepackage{amsfonts}
%%% \\usepackage{graphics}
%%% \\usepackage{epic}
%%% \\usepackage{eepic}
%%% \\usepackage{pict2e}
%%% Redefined titleformat
\\setlength{\\parindent}{0cm}
\\setlength{\\parskip}{1ex plus 0.5ex minus 0.2ex}
%%% \\setlength{\\parindent}{0cm}
%%% \\setlength{\\parskip}{1ex plus 0.5ex minus 0.2ex}
\\newcommand{\\hsp}{\\hspace{20pt}}
\\newcommand{\\acc}[1]{\\left\\{#1\\right\\}}
\\newcommand{\\cro}[1]{\\left[#1\\right]}
\\newcommand{\\pa}[1]{\\left(#1\\right)}
\\newcommand{\\R}{\\mathbb{R}}
\\newcommand{\\HRule}{\\rule{\\linewidth}{0.5mm}}
%\\titleformat{\\chapter}[hang]{\\Huge\\bfseries\\sffamily}{\\thechapter\\hsp}{0pt}{\\Huge\\bfseries\\sffamily}

\\usepackage[all]{xy}
%%% \\titleformat{\\chapter}[hang]{\\Huge\\bfseries\\sffamily}{\\thechapter\\hsp}{0pt}{\\Huge\\bfseries\\sffamily}
%%% \\usepackage[all]{xy}
\\newcommand{\\vecteur}[2]{\\pa{#1,\\dots,#2}}
\\newcommand{\\N}[0]{\\mathbb{N}}
\\newcommand{\\indicatrice}[1]{ {1\\!\\!1}_{\\acc{#1}} }
Expand Down Expand Up @@ -322,6 +321,7 @@
"tkinter.Entry.insert": "https://tkdocs.com/pyref/entry.html",
"tkinter.Event": "https://tkdocs.com/tutorial/eventloop.html",
"tkinter.Frame": "https://tkdocs.com/tutorial/widgets.html#frame",
"tkinter.filedialog": "https://docs.python.org/3/library/dialog.html#module-tkinter.filedialog",
"tkinter.IntVar": "https://tkdocs.com/pyref/intvar.html",
"tkinter.Label": "https://tkdocs.com/tutorial/widgets.html#label",
"tkinter.Label.after_cancel": "https://tkdocs.com/tutorial/widgets.html#label",
Expand Down Expand Up @@ -354,8 +354,6 @@
"tkinter.Toplevel.resizable": "https://tkdocs.com/pyref/toplevel.html",
"tkinter.Toplevel.title": "https://tkdocs.com/pyref/toplevel.html",
"tkinter.Toplevel.withdraw": "https://tkdocs.com/pyref/toplevel.html",
"tkinter.tix.DirTree": "https://pythonbasics.org/tkinter-filedialog/",
"tkinter.tix.FileSelectBox": "https://pythonbasics.org/tkinter-filedialog/",
"tkinter.ttk.Combobox": "https://tkdocs.com/pyref/ttk_combobox.html",
"tkinter.ttk.Notebook": "https://tkdocs.com/pyref/ttk_notebook.html",
"tkinter.ttk.Progressbar": "https://tkdocs.com/pyref/ttk_progressbar.html",
Expand Down
65 changes: 65 additions & 0 deletions _doc/examples/prog/plot_burrows_wheeler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# coding: utf-8
"""

.. _burrowswheelerrst:

==============================
Transformée de Burrows Wheeler
==============================

La transformée de `Burrows-Wheeler
<https://fr.wikipedia.org/wiki/Transform%C3%A9e_de_Burrows-Wheeler>`_
transforme un mot en un autre mot composée des mêmes lettres
mais aux propriétés statistiques différentes.
Les deux fonctions qui suivent implémentent les algorithmes
décrits sur la page Wikipedia.

Codage
======
"""


def code_burrows(text: str) -> str:
# étape 1: matrice décalée
decalages = ["".join(text[i:] + text[:i]) for i in range(len(text))]
# étape 2: tri
decalages.sort()
# on cherche la position du mot initial
pos = decalages.index(text)
# fin
return pos, "".join(decalages[i][-1] for i in range(len(text)))


print(code_burrows("ENSAE"))

############################################
# Décodage
# ========


def decode_burrows(pos, last_col):
first_col = sorted(last_col)
two_cols = list(zip(last_col, first_col))
for _i in range(2, len(last_col)):
two_cols.sort()
two_cols = [(c, *t) for c, t in zip(last_col, two_cols)]
two_cols.sort()
return "".join(two_cols[pos])


print(decode_burrows(2, "SAEEN"))

##############################
# On vérifie que le code vérifie des tests unitaires simples.


def test_burrows():
for mot in ["AA", "AB", "BA", "ABC", "ACB", "BCA", "BAC", "ENSAE"]:
pos, code = code_burrows(mot)
decode = decode_burrows(pos, code)
assert (
decode == mot
), f"problème avec {mot}, decode={decode}, pos={pos}, code={code}"


test_burrows()
Loading
Loading