méthodes de tri rapide en python

This commit is contained in:
gwen 2017-10-16 17:16:19 +02:00 committed by Benjamin Bohard
parent bf45ad7859
commit b5b00ce4d3
2 changed files with 189 additions and 27 deletions

View File

@ -1,20 +0,0 @@
les types structurés
- le produit cartésien
- le n-uplet
- types produits nommés (enregistrements)
type complexe = { re : float; im : float} ;;
type complexe = { re : float; im : float; }
# let a = {re=1.4; im = 0.5} ;;
val a : complexe = {re = 1.4; im = 0.5}
# a.re ;;
- : float = 1.4
# a.im ;;
- : float = 0.5
les types sommes : modélisation de domaines finis
# type couleur = Pique | Coeur | Carreau | Trefle;;
type couleur = Pique | Coeur | Carreau | Trefle
# let a = Trefle ;;
val a : couleur = Trefle

View File

@ -197,6 +197,8 @@ Description de l'algorithme
- la fonction inserer permet dinsérer un élément x dans une liste l - la fonction inserer permet dinsérer un élément x dans une liste l
- si la liste l est triée alors x est inséré au bon endroit - si la liste l est triée alors x est inséré au bon endroit
.. important:: la manière naturelle d'implémenter cet algorithme est ici la récursivité
.. code-block:: ocaml .. code-block:: ocaml
# let rec inserer x l = # let rec inserer x l =
@ -219,15 +221,21 @@ soit une liste l à trier :
qui sont plus petits (resp. plus grands) que la valeur du pivot p qui sont plus petits (resp. plus grands) que la valeur du pivot p
- trier récursivement g et d, on obtient deux listes g et d triées - trier récursivement g et d, on obtient deux listes g et d triées
la fonction suivante permet de partager une liste l en deux sous-listes g et
d contenant les éléments de l plus petits (resp. plus grands) quune valeur
donnée p
.. code-block:: ocaml .. code-block:: ocaml
:caption: fonction de partage d'une liste :caption: fonction de partage d'une liste
#let rec partage p l = #let rec partage p l =
match l with match l with
[] -> ([] , []) [] -> ([] , [])
|x::s -> let g,d = partage p s in |x::s -> let g,d = partage p s in
if x<=p then (x::g , d) else (g , x::d) ;; if x<=p then (x::g , d) else (g , x::d) ;;
val partage : a -> a list -> a list * a list = <fun> val partage : a -> a list -> a list * a list = <fun>
# partage 5 [1 ;9 ;7 ;3 ;2 ;4];; # partage 5 [1 ;9 ;7 ;3 ;2 ;4];;
- : int list * int list = ([1 ; 3 ; 2 ; 4], [9 ; 7]) - : int list * int list = ([1 ; 3 ; 2 ; 4], [9 ; 7])
@ -236,14 +244,184 @@ soit une liste l à trier :
# let rec tri rapide l = # let rec tri rapide l =
match l with match l with
[] -> [] [] -> []
| p::s -> let g , d = partage p s in | p::s -> let g , d = partage p s in
(tri rapide g)@[p]@(tri rapide d) ;; (tri rapide g)@[p]@(tri rapide d) ;;
val tri rapide : a list -> a list = <fun> val tri rapide : a list -> a list = <fun>
# tri rapide [5 ; 1 ; 9 ; 7 ; 3 ; 2 ; 4];; # tri rapide [5 ; 1 ; 9 ; 7 ; 3 ; 2 ; 4];;
- : int list = [1 ; 2 ; 3 ; 4 ; 5 ; 7 ; 9] - : int list = [1 ; 2 ; 3 ; 4 ; 5 ; 7 ; 9]
autre exemple de tri : le tri fusion. Il y en a d'autres.
Le tri en python
----------------
Pour comprendre comment marche le tri en Python, il faut comprendre que presque tout en Python est ordonnable car comparable
.. code-block:: python
>>> 1 > 0 # les nombres sont comparables
True
>>> 1 < 0
False
>>> "a" < "b" # les lettres, par ordre alphabetique
True
>>> True > False # les booléan (!)
True
>>> (1, 2) > (2, 1) # les iterables comparés, élément par élément dans l'ordre
False
>>> (1, 2) > [2, 1] # mais ils doivent être du même type
True
>>> {1:1} < {1:1, 0:0} # les dictionnaires, par nombre d'éléments
True
>>> "a" > 2 # si on mélange des types ça peut vide devenir bizarre
True
>>> 1j > 1 # PRESQUE tout est ordonnable
Traceback (most recent call last):
File "<ipython-input-11-ed3c013d3df8>", line 1, in <module>
1j > 1
TypeError: no ordering relation is defined for complex numbers
Cest ce quon appelle lordre naturel des éléments. Quand il ny a pas dordre naturel évident (et que ce nest pas une opération explicitement interdite comme avec les complexes),
Python va comparer lid (imaginez ladresse en mémoire)
.. code-block:: python
>>> class PersonnageDeLost(object):
... pass
...
>>> mort1 = PersonnageDeLost()
>>> mort2 = PersonnageDeLost()
>>> mort1 < mort2
True
>>> id(mort1) # son id est plus petit, donc il est inférieur
39611408
>>> id(mort2)
41720976
.. code-block:: python
class PersonnageDeCityHunter(object):
def __init__(self, nom, erectopouvoir):
self.nom = nom
self.erectopouvoir = erectopouvoir
def __lt__(self, other):
# on doit retourner un booléan qui confirme ou infirme
# l'opération "lt" ("lower than", c'est à dire "plus petit que")
return self.erectopouvoir < other.erectopouvoir
def __gt__(self, other):
# on doit retourner un booléan qui confirme ou infirme
# l'opération "gt" ("greater than", c'est à dire "plus grand que")
return self.erectopouvoir > other.erectopouvoir
# on peut faire la même chose pour les autres méthodes qui
# concernent les opérateurs <=, >=, == et !=
>>> PersonnageDeCityHunter('Ryo Saeba', 99999) > PersonnageDeCityHunter('Mamouth', 1)
True
>>> PersonnageDeCityHunter('Ryo Saeba', 99999) < PersonnageDeCityHunter('Mamouth', 1)
False
Ordonner une liste
-------------------
Avec `sort()` Les éléments sont triés dans leur ordre naturel automatiquement, du plus petit au plus grand:
.. code-block:: python
>>> l = ['b', 'a', 'c']
>>> l.sort()
>>> l
['a', 'b', 'c']
>>> l = [(2, 1), (1, 2), (7, 8), (2, 2), (2, 0), (2, 3)]
>>> l.sort()
>>> l # ordonne sur le premier élément, puis le second si il y a égalité
[(1, 2), (2, 0), (2, 1), (2, 2), (2, 3), (7, 8)]
>>> persos = [PersonnageDeCityHunter('Ryo Saeba', 99999), PersonnageDeCityHunter('Mamouth', 1), PersonnageDeCityHunter('Kaori', 0)]
>>> persos.sort()
>>> for perso in persos:
... print perso.nom
...
Kaori
Mamouth
Ryo Saeba
et inversement:
.. code-block:: python
>>> l = [1, 7, 3, 8]
>>> l.sort(reverse=True)
>>> l
[8, 7, 3, 1]
`sort()` et `sorted()` acceptent toutes les deux les mêmes arguments. Ce que vous apprenez pour lun vaut pour lautre. La seul différence est que sort() retourne None et modifie sur place, tandis que sorted() retourne une nouvelle liste. sorted() est un peu moins performant.
.. code-block:: python
>>> sorted((1, 7, 3, 8), reverse=True)
[8, 7, 3, 1]
Utilisations de tri personnalisés
----------------------------------
Parfois on a besoin de trier sur quelque chose de plus complexe quune lettre ou un chiffre. Par exemple, vous avez des scores dans un dictionnaires. Un dictionnaire nest pas ordonné. Si vous imprimez un classement, il faut en faire une liste de tuples :
::
>>> sorted(scores.items())
[('Cunegonde', 3), ('Gertrude', 4), ('Robert', 2), ('Roger', 1)]
Cest là quintervient le paramètre key. key est très particulier, cest un paramètre qui attend quon lui passe un callback, donc key attend quon lui passe une fonction.
::
>>> def get_score(nom_et_score):
... return nom_et_score[1] # retourne le 2nd element du tuple
...
>>> sorted(scores.items(), key=get_score) # on passe la fonction a key
[('Roger', 1), ('Robert', 2), ('Cunegonde', 3), ('Gertrude', 4)]
.. ifconfig:: exercice
classer des objets voiture en fonction de la puissance du moteur
autre exemple: ordonner des objets voitures selon leur coût dentretien dabord, et ensuite par coût dachat.
::
class Voiture(object):
def __init__(self, cout_entretien, cout_achat):
self.cout_entretien = cout_entretien
self.cout_achat = cout_achat
def __repr__(self):
return "<Voiture E-{} / A-{}>".format(self.cout_entretien, self.cout_achat)
>>> voitures = [Voiture(10000, 10000), Voiture(50000, 10000), Voiture(10000, 60000)]
>>> voitures
[<Voiture E-10000 / A-10000>, <Voiture E-50000 / A-10000>, <Voiture E-10000 / A-60000>]
>>> def get_entretien_achat(voiture):
... return (voiture.cout_entretien, voiture.cout_achat)
...
>>> sorted(voitures, key=get_entretien_achat)
[<Voiture E-10000 / A-10000>, <Voiture E-10000 / A-60000>, <Voiture E-50000 / A-10000>]
Définition d'un itérateur Définition d'un itérateur
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -552,13 +730,17 @@ On les appelle enregistrements, dictionnaires ou tables de hachage.
- les sommes (constructeurs) - les types sommes (constructeurs) : modélisation de domaines finis
.. code-block:: ocaml .. code-block:: ocaml
# type couleur = Pique | Coeur | Carreau | Trefle;; # type couleur = Pique | Coeur | Carreau | Trefle;;
# let v = (Pique , Coeur);; # let v = (Pique , Coeur);;
val v : couleur * couleur = (Pique , Coeur) val v : couleur * couleur = (Pique , Coeur)
# let a = Trefle ;;
val a : couleur = Trefle
.. code-block:: ocaml .. code-block:: ocaml