Amphi de rattrapage Algo / Prog Jérémy Marin htime@via.ecp.fr Arthur Patora aki@via.ecp.fr Tom Brendlé sylentheal@via.ecp.fr
Plan du rattrapage Introduction et conseils Commandes et notions de base Les listes Les piles et les files Les tris Les dictionnaires Les arbres Les graphes
Objectif : valider le CF Epreuve de 3h à exercices indépendants Pas de documents et ordinateur (sauf formulaire types abstraits fourni pendant le CF) Retrouvez sur : Claroline Cours Slides Mais aussi sur people.via.ecp.fr/~modulo/algo/ Cours (2010) Exemples et bouts de codes Annales Documentation
Préparation et organisation Pas de secret : faire des exos L’épreuve est courte (3h) et tardive Lire le CF en entier Faire proprement les premières questions Réfléchir avant d’écrire Indentation Commentaire au besoin Tester sur les cas simples (n=0, n=1) Gratter les points Se relire contre les étourderies
À ne pas faire À faire Choisir des noms de variable explicites : def _check_call_py24(cmd): if not res == 0: print(“The world is big”) else: raise Error(msg) def _check_call_py24(cmd): if not res == 0: print(“The world is big”) else: raise Error(msg) Choisir des noms de variable explicites : resFonctRec = résultat de la fonction récursive res_Fonct_Rec Code aéré : sauter des lignes Commenter les endroits que vous jugez compliqués écrire d’une autre couleur et # commentaire # Calcul le terme de la suite
Algorithmique vs Programmation Différence entre algorithme (concept) et programmation (langage) Notre langage : le Python Simple et haut niveau Répandu et utilisé Ca peut toujours resservir… (projet enjeu) Préférer le Python au Pseudo code : Si a > 0 alors afficher(« positif ») Sinon afficher(« negatif »)
Plan du rattrapage Introduction et conseils Commandes et notions de base Les listes Les piles et les files Les tris Les dictionnaires Les arbres Les graphes
Notions de base On va voir : Dans Python : Les nombres Expression logique L’instruction if Fonctions Boucles Exceptions Dans Python : Pas de déclaration => affectation directe a = 12 L’indentation définit les blocs Sauter une ligne change d’instruction
L’indentation définit les blocs
Les nombres A = 2 B = A # B vaut 2 C = A + B + 1 # C vaut 5 D = 5*C # D vaut 25 10/3 # 3.333333333334 2**3 # 8 print(A) # affiche 2 print(D – 20) # affiche 5
Les commandes de base Sur les nombres : +, -, * : addition, soustraction, multiplication ** : exposant (puissance) / : division mais qui arrive dans les réels // : division entière % : reste de la division euclidienne
Les expressions logiques (1/2) Expression qui retourne un booléen (True/False) Attention : Majuscules !! Egalité 1==2 # False Différence 3 != 4 # True Inégalité 5 < 5 # False 5 <= 5 # True
Les expressions logiques (2/2) Et True and False # False Ou True or False # True Négation not(True) # False En cas de doute, ajouter des parenthèses : 1==2 and 5 <= 5 or not(True) ((1==2) and (5 <= 5)) or not(True)
L’instruction if Pseudo-code (P-C) : Si… Alors… {Sinon Si… Alors…} Sinon… if condition1: instruction1 # Exécuté si condition1est vrai instruction2 elif condition2: instruction3 # Exécuté si condition1 est faux instruction4 # et condition2 est vrai else: instruction5 # Exécuté dans les autres cas #Sortie du if Indentation et deux points (:) très importants
Les boucles (1/2) : la boucle for P-C : Pour i allant de x à y Faire instruction(avec la valeur de i) Python : for i in range (x,y): instructions (avec la valeur de i) Pas besoin de gérer i (il augmente tout seul !)
Explication fonction range() range(x,y) => [x,y[ range(x) => [0,x[ Exemple : for i in range (n+1): print(i) => Affiche : 0 1 2 3 … (n-1) n
Les boucles (2/2) : la boucle while P-C : Tant que condition Faire instruction Python : while condition: instructions Attention aux boucles infinies : vérifier que la condition doit devenir fausse Exemple (avec un compteur) n = 0 # Initialisation while n <= 10: n = n+1 Préférez la boucle for à while quand vous pouvez !
Instruction break A éviter ! Permet de sortir de la plus petite structure de boucle Exemple : for j in range(n): # Boucle for i = 0 while True: # Boucle infinie ? i = i + 1 if i > 10: break # On sort de la boucle while mais pas de for
Les fonctions def nom_fonction (param1, param2, …): instruction1 instruction2 {return solution} (optionnel) Nombre de paramètres quelconque return solution : - stop la fonction immédiatement - la fonction s’utilise comme une variable print(nom_fonction(param1,…)) => affiche le résultat de la fonction
Les exceptions (1/2) : raise Définition en haut du code (ne pas oublier !): class monException(Exception): pass Exemple d’utilisation (fonction top de pile.py) : def top(Pile) : if isEmpty(Pile): raise EmptyException else: return P[0]
Les exceptions (2/2) : try, except Gérer des erreurs qui existent dejà dans python Peut servir Exemple : def division(a, b) : try: # Code qui risque de produire une erreur return (a/b) # Si b = 0 => erreur except ZeroDivisionError: # Code qui gére l’erreur (ici, on affiche un message) print(“Erreur : argument nul fourni”)
Plan du rattrapage Introduction et conseils Commandes et notions de base Les listes Les piles et les files Les tris Les dictionnaires Les arbres Les graphes
Les listes A B C D 2 1 3 Définition : variable contenant un nombre fini d’éléments numérotés Déclaration : liste = [a, b, c] Accès à un élément : liste[i] Attention ! Numérotation à partir de 0 ! len(liste) : nombre d’éléments La taille d’une liste est fixée au moment de la création mais …
Concaténation de deux listes B C D 2 1 3 E F G H I 2 1 3 4 + A B C D 2 1 3 E F G H I 6 4 5 7 8 = Syntaxe : liste3 = liste1 + liste2 Utile pour rajouter un élément en fin de liste : liste = liste + [élément] En début de liste: liste = [élément] + liste
Extraction d’une tranche B C D 2 1 3 E F 4 5 2 3 4 C D E liste liste[2:5] Syntaxe : liste[i:j] pour récupérer les éléments de i à j-1 Exemple : pour enlever le dernier élément : liste = liste[0:len(liste)-1] Pour supprimer le i-ème élément : del liste[i]
Test de sous-liste (CF 2009) Est-ce que liste2 est une sous-liste de liste1 ? Eléments contigus Dans le même ordre A B C D 2 1 3 E F 4 5 liste1 G 6 C D E 2 1 liste2 A D G 2 1 liste2 D C 1 liste2 non oui non
Test de sous-liste (CF 2009) Idée : regarder toutes les sous-listes de liste1 qui ont la bonne longueur Exemple : la sous-liste cherchée est de longueur 4 A B C D 2 1 3 B C D E 2 1 3 A B C D 2 1 3 E F 4 5 G 6 à comparer avec la sous-liste cherchée C D E F 2 1 3 D E F G 2 1 3 Complexité : O(n)
Récursivité Fonction qui s'appelle elle-même, et pour laquelle une certaine quantité décroît (strictement). Pour une valeur minimale, la fonction renvoie une valeur, c'est le cas de base. Exemple 1: def fact( n ) : if n == 1 : return 1 else: return ( n * fact( n - 1 ) ) Quantité décroissante : n Cas de base : n=1 Exemple 2: def pgcd (a,b) : if b > a : return pgcd(b,a) else: if a%b == 0 : return b return pgcd(b, a%b) Quantité décroissante : a%b Cas de base : a%b == 0
Plan du rattrapage Introduction et conseils Commandes et notions de base Les listes Les piles et les files Les tris Les dictionnaires Les arbres Les graphes
Les files Liste FIFO (First In First Out, i.e. file d’attente) Caisses de supermarché
Plan du rattrapage Introduction et conseils Commandes et notions de base Les listes Les piles et les files Les tris Les dictionnaires Les arbres Les graphes
Algorithmes de tri Entrée : liste de nombres Sortie : les mêmes en ordre croissant Pourquoi plusieurs algorithmes de tri ? Complexités Variantes itératives ou récursives + ou – adaptés aux listes déjà triées, ou triées à l’envers (pire ou meilleur cas)
Algorithmes classiques Tri bulle Tri par insertion Tri rapide
Tri bulle Idée : examiner des couples (« bulles »). Solution itérative : On parcourt la liste du début à la fin (ça fait n-1 bulles) On échange les bulles qui sont à l’envers Condition d’arrêt : si en un passage on n’a rien changé.
Tri bulle 12 11 11 12 17 23 10 23 10 Complexité O(n²) Exemple : Puis on recommence, jusqu’à ce que la liste soit triée. Complexité O(n²)
Tri par insertion Idée : on fait reculer chaque élément jusqu’à ce qu’il trouve sa place. Exemple : 4 3 7 9 5 2 8 6 1 4 3 7 9 5 2 8 6 1 4 3 7 9 5 2 8 6 1 4 3 7 9 5 2 8 6 1 4 3 7 9 5 2 8 6 1 4 3 7 9 5 2 8 6 1 9 7 5 3 4 9 7 3 4 3 4 4 7 3 4
Tri rapide Algorithme récursif : s’appelle lui- même sur de plus petites listes Idées : Initialisation à 2 éléments Choix du pivot : par exemple le premier élément Classement des éléments restants par rapport au pivot Tri des deux listes formées et concaténation
Tri rapide Exemple : 4 3 7 9 5 2 8 6 1 > 4 < 4 3 2 1 4 7 9 5 8 6 < 3 > 3 < 7 > 7 1 2 2 1 3 4 5 6 7 8 9 9 8 Y’a plus qu’à recoller les morceaux. C’est trié !
Plan du rattrapage Introduction et conseils Commandes et notions de base Les listes Les piles et les files Les tris Les dictionnaires Les arbres Les graphes
C’est quoi un dictionnaire ? Définition : comme une liste sauf que les éléments ne sont pas forcément repérés par des numéros Exemple : dico "France" 60 "Espagne" 46 "Belgique" 10 dico = {"France": 60, "Espagne": 46, "Belgique": 10}
Dictionnaires Eléments pas ordonnés Un seul élément par clé (l’élément peut être une liste) Appel d’un élément : dico[clé] (si la clé est une chaîne de caractères on n’oublie pas les guillemets …) list(dico.keys()) : liste des clés list(dico.values()) : liste des éléments
Pour les plus courageux Table de hachage : But : stocker des données variées et y accéder efficacement Fonction de hachage : prend une clé et renvoie l’indice dans la table Le dictionnaire fonctionne sur ce principe !
Plan du rattrapage Introduction et conseils Commandes et notions de base Les listes Les piles et les files Les tris Les dictionnaires Les arbres Les graphes
Les arbres Définitions Racine Arête Hauteur Nœud Feuille
Arbres binaires Définition : arbre dont chaque nœud est de degré au plus deux. Se construit récursivement : chaque arbre est constitué d’une clé, d’un sous-arbre gauche (« fils gauche ») et d’un sous-arbre droit (« fils droit »).
Arbres binaires : implémentation On les implémente avec un dictionnaire ayant trois champs : ‘rac’, ‘g’ et ‘d’. Ex: {‘rac’ = 8, ‘g’ = {‘rac’ = 2, ‘g’ = {}, ‘d’ = {} }, ‘d’ = {‘rac’ = 6, ‘g’ = {‘rac’ = 1, ‘g’ = {}, ‘d’ = {} }, ‘d’ = {} } } {‘rac’ = 2, ‘g’ = {}, ‘d’ = {} } 8 {‘rac’ = 6, ‘g’ = {‘rac’ = 1, ‘g’ = {}, ‘d’ = {} }, ‘d’ = {} } 2 6 1 {‘rac’ = 1, ‘g’ = {}, ‘d’ = {} }
Arbres binaires : seconde implémentation On les implémente avec un tuple : (racine, liste de fils) Ex: (8,[(2,[ ]), (6,[(1,[ ])])]) (2,[ ]) 8 (6,[(1,[ ])]) 2 6 1 (1,[ ])
Quelques fonctions Il est clairement plus simple de faire des fonctions récursives pour traiter un arbre. Ex : nombre de nœuds = 1 + nombre de nœuds du fils gauche + nombre de nœuds du fils droit. En python: def nombre_noeud(arbre) : if arbre == {} : return 0 else : return 1 + nombre_noeud (arbre[’g’]) + nombre_noeud (arbre[‘d’])
Quelques fonctions 8 Parcours infixe : 2 6 3 1 def p_infixe(arbre) : if arbre == {} : return [] else : return (p_infixe(arbre[’g’]) + [ arbre[‘rac’] ] + p_infixe(arbre[‘d’]) ) 2 6 3 1 Résultat : [2, 8, 1, 6, 3]
Arbre binaire de recherche Arbre ordonné Facilite la recherche ! Conditions : Tout nœud du fils gauche ≤ racine ≤ Tout nœud du fils droit Tout fils est un arbre binaire de recherche 5 2 6 1 4 8 3 7 9
Ex : recherche dans un arbre binaire de recherche def recherche(elem, arbre) : if arbre == {} : return False else: if arbre[‘rac’] == elem : return True else: if arbre[‘rac’] < elem : return recherche(elem, arbre[‘d’]) else : return recherche(elem, arbre[‘g’]) 5 5 5<7 2 6 6 6<7 1 4 8 8 8>7 3 7 7 9 True Recherche(7,arbre)
Pour les courageux : le parcours en largeur Manipule à la fois les arbres et les files !
Principe du parcours en largeur Problème : on ne peut pas le faire récursivement, car il faut traiter les deux sous-arbres simultanément ! Astuce : à chaque nœud, on affiche la racine et on mémorise sous-arbres pour les traiter plus tard. Il faut traiter d’abord les premiers sous- arbres enregistrés : on utilise une file.
toVisit : [arbre_c, arbre_d, arbre_e] parcours: [a,b] def largeurFile2(arbre): toVisit= [arbre] parcours = [] while len(toVisit)>0: #je prends le premier élément, je l'affiche parcours+=(racine(toVisit [0])) #j'ajoute ses fils s'il y en a, à la fin de la file if not est_vide(gauche(toVisit[0])): toVisit+= (gauche(toVisit [0])) if not est_vide(droit(toVisit [0])): toVisit+=(droit(toVisit [0])) #je défile toVisit = toVisit[1:] return parcours toVisit : [arbre_c, arbre_d, arbre_e] parcours: [a,b] toVisit : [arbre_a] parcours : [ ] toVisit : [arbre_b, arbre_c] parcours : [a]
Plan du rattrapage Introduction et conseils Commandes et notions de base Les listes Les piles et les files Les tris Les dictionnaires Les arbres Les graphes
Graphes Définition : Un graphe G est un couple (E,A) : E est un ensemble de sommets (ou états). A est un ensemble d’arêtes. 1 2 4 3 5 6 8 7 9
Graphes Vocabulaire : Chemin : séquence d’arêtes telles que l’extrémité de l’une correspond à l’origine de la suivante Cycle : chemin dont l’origine est égale à l’extrémité Boucle : cycle de longueur 1 2 5 4 9 2 4 9 3 5
Graphes Sous forme de dictionnaire: Implémentations possibles : 1 2 4 3 8 7 9 Implémentations possibles : Sous forme de dictionnaire: Les clés sont les étiquettes des sommets Les valeurs sont des listes de successeurs Sous forme d’un dictionnaire de deux listes : Une liste de sommets Une liste de couples qui représentent les arêtes G = { 1 : [ 3 ], 2 : [1, 4], 3 : [ 7 ], 4 : [ 2 ], 7 : [ ], 8 : [ ], 9 : [ 3, 4 ] } l_sommets = [ 8, 2, 4, 9, 3, 7, 1 ] l_aretes = [ (2, 1), (2, 4), (1, 3), (3, 7), (9, 3), (9, 4), (4, 2) ] G = { ‘vertices’ : l_sommets, ‘edges’ : l_aretes } Matrice d’adjacence : Matrice dont le coefficient (i,j) vaut 1 si l’arête i → j existe et 0 sinon
Exemple de fonctions sur les graphes Parcours en largeur : On visite tous les fils d’un sommet puis on visite les fils de ces fils. Implémentation : On utilise une file pour stocker les sommets en cours de traitement et une liste pour les sommets déjà visités. (cf arbres)
Exemple de fonctions sur les graphes 5 Parcours en largeur en partant de 5. 6 2 4 9 3 1 8 7
Exemple de fonctions sur les graphes 5 Visited = [] toVisit = [5] 6 2 4 9 3 1 8 7
Exemple de fonctions sur les graphes 5 Visited = [5] toVisit = [4] 6 2 4 9 3 1 8 7
Exemple de fonctions sur les graphes 5 Visited = [5, 4] toVisit = [2, 9] 6 2 4 9 3 1 8 7
Exemple de fonctions sur les graphes 5 Visited = [5, 4, 2] toVisit = [9, 1] 6 2 4 9 3 1 8 7
Exemple de fonctions sur les graphes 5 Visited = [5, 4, 2, 9] toVisit = [1, 3] 6 2 4 9 3 1 8 7
Exemple de fonctions sur les graphes 5 Visited = [5, 4, 2, 9, 1] toVisit = [3] 6 2 4 9 3 1 8 7
Exemple de fonctions sur les graphes 5 Visited = [5, 4, 2, 9, 1, 3] toVisit = [7] 6 2 4 9 3 1 8 7
Exemple de fonctions sur les graphes 5 Visited = [5, 4, 2, 9, 1, 3, 7] toVisit = [] On doit recommencer avec les sommets qui n’ont pas été visités. 6 2 4 9 3 1 8 7
Exemple de fonctions sur les graphes Visited = [5, 4, 2, 9, 1, 3, 7] toVisit = [] notVisited = [6,8] 5 6 Ajouter l.remove(n) 2 4 9 3 1 8 7
C’est fini ! Récupérez sur votre PC tous les documents Faites quelques exos Retrouvez des documents sur : people.via.ecp.fr/~modulo/algo Les slides sont sur : people.via.ecp.fr/~htime/ Retrouvez les cours sur : cours.etudes.ecp.fr/claroline/ Bonnes révisions !