Informatique TD7 : Complexité et structures de données

Documents pareils
Exercices types Algorithmique et simulation numérique Oral Mathématiques et algorithmique Banque PT

STAGE IREM 0- Premiers pas en Python

La NP-complétude. Johanne Cohen. PRISM/CNRS, Versailles, France.

Initiation à la programmation en Python

Cours 1 : Introduction Ordinateurs - Langages de haut niveau - Application

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

1 Recherche en table par balayage

Programmation linéaire

ALGORITHMIQUE II NOTION DE COMPLEXITE. SMI AlgoII

Algorithmique I. Algorithmique I p.1/??

TD3: tableaux avancées, première classe et chaînes

MIS 102 Initiation à l Informatique

Plus courts chemins, programmation dynamique

Chap III : Les tableaux

Chapitre 7. Récurrences

Découverte de Python

Cours Informatique Master STEP

Corrigé des TD 1 à 5

1 Définition et Appel d une fonction. V. Phan Luong. Cours 4 : Fonctions

Compression Compression par dictionnaires

Cours d algorithmique pour la classe de 2nde

Cours 7 : Utilisation de modules sous python

Feuille TD n 1 Exercices d algorithmique éléments de correction

SNT4U16 - Initiation à la programmation TD - Dynamique de POP III - Fichiers sources

Quelques tests de primalité

Cours d initiation à la programmation en C++ Johann Cuenin


Présentation du langage et premières fonctions

Calcul matriciel. Définition 1 Une matrice de format (m,n) est un tableau rectangulaire de mn éléments, rangés en m lignes et n colonnes.

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

V- Manipulations de nombres en binaire

TP 1. Prise en main du langage Python

Calculabilité Cours 3 : Problèmes non-calculables.

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Manuel d utilisation 26 juin Tâche à effectuer : écrire un algorithme 2

Licence Sciences et Technologies Examen janvier 2010

Représentation d un entier en base b

Python - introduction à la programmation et calcul scientifique

6 - Le système de gestion de fichiers F. Boyer, UJF-Laboratoire Lig, Fabienne.Boyer@imag.fr

Programmation linéaire

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Examen Médian - 1 heure 30

Recherche dans un tableau

1 Année LMD-STSM Algorithmique et Programmation. Série de TD 2

Algorithmique et programmation : les bases (VBA) Corrigé

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java

Représentation des Nombres

Introduction à MATLAB R

Grandes lignes ASTRÉE. Logiciels critiques. Outils de certification classiques. Inspection manuelle. Definition. Test

Organigramme / Algorigramme Dossier élève 1 SI

Cours 3 : Python, les conditions

Quelques algorithmes simples dont l analyse n est pas si simple

Les arbres binaires de recherche

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux.

Contexte. Pour cela, elles doivent être très compliquées, c est-à-dire elles doivent être très différentes des fonctions simples,

Cours 02 : Problème général de la programmation linéaire

1 de 46. Algorithmique. Trouver et Trier. Florent Hivert. Mél : Florent.Hivert@lri.fr Page personnelle : hivert

Polynômes à plusieurs variables. Résultant

Ensimag 1ère année Algorithmique 1 Examen 2ième session 24 juin Algorithmique 1

Déroulement. Evaluation. Préambule. Définition. Définition. Algorithmes et structures de données 28/09/2009

Probabilités. Rappel : trois exemples. Exemple 2 : On dispose d un dé truqué. On sait que : p(1) = p(2) =1/6 ; p(3) = 1/3 p(4) = p(5) =1/12

Initiation à l algorithmique

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Comparaison de fonctions Développements limités. Chapitre 10

Suites numériques 3. 1 Convergence et limite d une suite

Entraînement au concours ACM-ICPC

Développements limités. Notion de développement limité

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

Architecture des ordinateurs TD1 - Portes logiques et premiers circuits

L ALGORITHMIQUE. Algorithme

Conversion d un entier. Méthode par soustraction

Programmation C++ (débutant)/instructions for, while et do...while

INTRODUCTION AUX SYSTEMES D EXPLOITATION. TD2 Exclusion mutuelle / Sémaphores

Exo7. Matrice d une application linéaire. Corrections d Arnaud Bodin.


CORRIGE LES NOMBRES DECIMAUX RELATIFS. «Réfléchir avant d agir!»

UE Programmation Impérative Licence 2ème Année

Plan du cours Cours théoriques. 29 septembre 2014

Premiers Pas en Programmation Objet : les Classes et les Objets

Baccalauréat ES Polynésie (spécialité) 10 septembre 2014 Corrigé

Bases de programmation. Cours 5. Structurer les données

1. Structure d'un programme FORTRAN 95

Problèmes arithmétiques issus de la cryptographie reposant sur les réseaux

MISE A NIVEAU INFORMATIQUE LANGAGE C - EXEMPLES DE PROGRAMMES. Université Paris Dauphine IUP Génie Mathématique et Informatique 2 ème année

AWS avancé. Surveiller votre utilisation d EC2

Projet Active Object

Cette application développée en C# va récupérer un certain nombre d informations en ligne fournies par la ville de Paris :

Exercices du Cours de la programmation linéaire donné par le Dr. Ali DERBALA

Chapitre VI- La validation de la composition.

Logiciel Libre Cours 3 Fondements: Génie Logiciel

Algorithmique, Structures de données et langage C

ARBRES BINAIRES DE RECHERCHE

Théorie et codage de l information

ASR1 TD7 : Un microprocesseur RISC 16 bits

Objectifs du cours d aujourd hui. Informatique II : Cours d introduction à l informatique et à la programmation objet. Complexité d un problème (2)

Algorithmes pour la planification de mouvements en robotique non-holonome

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme

La programmation linéaire : une introduction. Qu est-ce qu un programme linéaire? Terminologie. Écriture mathématique

Transcription:

Informatique TD7 : Complexité et structures de données CPP septembre - novembre 2016 1 Complexité 1.1 Introduction (5mn) Un algorithme est dit de complexité polynomiale si sa complexité est une fonction polynomiale de la taille du problème n, par exemple f(n) = 3n 3 n 2 + 10. Dans le cas d une complexité polynomiale, les coefficients des monômes n importent pas puisqu on s intéresse à la complexité asymptotique (quand la taille des données devient grande), et seul le degré du polynôme compte (n 3 dans l exemple ci-dessus). Donc, en général, quand on «compte» les opération pour évaluer la complexité, on compte 1 pour chaque opération (affectation, comparaison, arithmétique sur des entiers ou des flottants), même si la réalité (le temps mis par chaque opération à s exécuter) est différente. Attention quand même attention aux «opérations» qui coûtent O(n) (comme les comparaisons ou copies de liste). L amalgame «1 ligne de code = O(1)» est délicat avec un langage de haut niveau comme Python. Cette observation s applique à tous les calculs de complexité asymptotique, et même au cas des complexités non-polynomiales : on s intéresse uniquement au terme dominant. 1.2 Multiplication de deux matrices (10mn) Soient A = (a ij ) une matrice n m et B = (b ij ) une matrice m p. Le produit de A et B est une matrice n p, C = (c ij ), avec c ij = m k=1 a ikb kj Quelle est la complexité du calcul d un élément de la matrice C? O(m) Combien y a-t-il d éléments dans la matrice C? O(n p) Écrire la fonction python matmult(a,b), qui renvoie le produit de deux tableaux numpy A et B, sans utiliser numpy.dot (rappel : A.shape[0] est le nombre de lignes et A.shape[1] le nombre de colonnes de A) attention aux indices! def matmult (A, B): n = A. shape [0] m = A. shape [1] p = B. shape [1] C = np. zeros ([ n, p]) for i in range (n): for j in range (p): for k in range (m): C[i, j] += A[i, k] * B[k, j] return C Calculer la complexité dans le cas meilleur, le cas pire, en moyenne, en fonction de la taille des données, ici les dimensions (n, m, p) des matrices A et B. 1

Meilleur cas = pire cas = O(m n p). Note : En théorie, on peut faire plus efficace. Trouver un algorithme optimal de multiplication de matrices est un problème de recherche ouvert à l heure actuelle. A PASSER DANS LE CM? 1.3 Recherche dans un tableau (5mn) On vous demande de concevoir une fonction qui recherche par dichotomie un élément dans un tableau de n entiers triés, et qui renvoie soit son index, soit -1 si l élément n est pas présent. Quelle est la complexité asymptotique dans le pire cas en temps d exécution de cette fonction? (On peut montrer qu elle correspond aussi à la complexité moyenne) def Codage en Python : recherche (T, e): i = 0 j = len (T) while j > i: # Invariant : si l' élé ment est dans T, son indice est # dans [i, j [. pivot = (i + j) // 2 if T[ pivot ] == e: return pivot elif T[ pivot ] > e: j = pivot else : i = pivot + 1 return None # Test : tableau = [0, 1, 5, 10, 42] print ( recherche ( tableau, 0)) print ( recherche ( tableau, 2)) print ( recherche ( tableau, 42)) print ( recherche ( tableau, 43)) Complexité : on l a vu en cours, il suffit d appliquer le "Master Theorem" avec k = 1, b = 2, d = 0 : O(log n) (d = log b k = 0). Rappel : Si f(n) = kf( n/b ) + O(n d ), avec k > 0, b > 1, d 0 alors si d > log b k, f(n) = O(n d ) si d = log b k, f(n) = O(n d log n) si d < log b k, f(n) = O(n log b k ) 2 Structures de données Une structure de données est un assemblage de types simples (dans notre cas listes, booléens, entiers, flottants, chaînes) permettant de représenter un objet plus complexe (exemples : un tuple d une relation, un arbre généalogique, un graphe de villes avec leurs distances) Nous allons créer une structure de données pour représenter un vecteur creux, c est-à-dire un vecteur contenant beaucoup de fois la valeur 0. Un vecteur creux se comporte de la même manière qu un vecteur classique (np.array à 1 dimension), mais est optimisé pour le cas où le vecteur contient une majorité de valeurs nulles 1. 2.1 Préliminaire : opérations sur les listes et complexité Dans la suite, nous allons utiliser des listes Python pour représenter une structure de données. Voici un rappel des opérations et de leur complexité. 1. Par exemple, l instruction np.zeros(10**10) (créer un vecteur de taille 10 10 ) provoque une MemoryError sur la machine de l auteur de ce document, alors que créer un vecteur creux (en utilisant coo_matrix de la bibliothèque scipy ou la version faite maison) de taille 10 1000 ne pose aucun problème. 2

Soient x une liste de longueur n et i un entier. e est une valeur quelconque. x[i] : accès à l élément i, Θ(1) x.append(e) : insertion en fin de liste, Θ(1) x = x + [e] : construction d une nouvelle liste contenant les éléments de x suivis de e, θ(n) x.insert(i, e) : insertion de e en position i, Θ(nombre d éléménts déplacés) = Θ(n i), ou Θ(1) si aucun élément n est déplacé. e = x.pop(i) : suppression de l élément à la position i, Θ(nombre d éléments déplacés) = Θ(n i), ou Θ(1) si aucun élément n est déplacé. Hypothèse simplificatrice : on suppose que l espace mémoire alloué par Python pour stocker les éléments de la liste est suffisant pour ajouter un élément en fin. L insertion en fin est donc en Θ(1) et l insertion en milieu de liste en Θ(nombre d éléments déplacés) 2. 2.2 Structure de données = implantation + constructeurs + testeurs + sélecteurs + modifieurs (10mn) L utilisateur de notre structure de données ne devrait pas avoir à se soucier de la représentation interne de notre vecteur creux (on parle de structure de données "opaque" ou "abstraite"). Lorsqu on doit choisir une structure de données, avant de se poser la question «Comment représenter un vecteur creux en Python?» (c est-à-dire «Quelle structure de données utiliser?»), il faut se poser la question «Pourquoi représenter un vecteur creux?», c est à dire «Quel jeu de fonctions proposer à l utilisateur?». Nous allons fournir à l utilisateur des fonctions permettant de modifier ou de lire cette structure de données. Pour notre vecteur creux, ces opérations sont les mêmes que pour np.array, mais leur implémentation et leur complexité sera différente. Ces fonctions sont de plusieurs types : les constructeurs permettent de créer une structure de données vide ou de créer une structure de données à partir d un fichier ou d une autre structure de données (exemple : np.array(...)) ; les testeurs et sélecteurs permettent d interroger la structure de données sans la modifier (est-ce qu un élément est présent dans l ensemble? combien d éléments contient l ensemble?) (exemples : x.shape(), x[...]) ; les modifieurs permettent de modifier la structure de données (ajouter un élément, en supprimer un, extraire un élément quelconque) (exemple : x[...] =...) ; des opérateurs qui prennent en entrée plusieurs instance de la structure et renvoient une valeur fonction de ces entrées ; éventuellement, les destructeurs permettent de détruire la structure de données (en Python, dans beaucoup de cas ils ne sont pas nécessaires). Elles constituent l interface de la structure de données. 2.3 Spécification de l interface (10mn) Spécifier l interface, c est donner la réponse à la question «Pourquoi?» ci-dessus, sous la forme de liste de fonctions avec leurs paramètres et leurs valeurs de retour, sans en donner le contenu. Note : la bibliothèque NumPy utilise les opérateurs (+, [],...) pour l interface de programmation des vecteurs, mais vous n avez pas les notions de Python nécessaires pour le faire : toute l interface utilisera donc des fonctions (def...). Donner une liste des fonctions de l interface d une structure de données «ensemble», par catégorie, avec pour chaque fonction ce qu elle fait et la liste des paramètres. Par exemple : creer_vecteur(n) renvoie un vecteur vide de taille n creuser(v_dense) construit un vecteur creux représentant la même valeur mathématique que la liste Python v_dense. remplir(v_creux) construit une liste Python représentant la même valeur mathématique que le vecteur creux v_creux taille_vecteur(v) renvoie la taille du vecteur 2. En réalité, la complexité de ces opérations fait appel à la notion de complexité amortie qui n est pas au programme, cf. https://wiki.python.org/moin/timecomplexity 3

changer_valeur(vect, i, val) Modifie la valeur à l emplacement i du vecteur vect. Équivalent de vect[i] = val avec les vecteurs. somme_vecteurs(v1, v2) ajoute deux vecteurs (renvoie un vecteur). comparer_vecteur(v1, v2) compare les deux vecteurs v1 et v2. Renvoie True s ils sont égaux, et False sinon. somme_elements_vecteur(v) renvoie la somme des éléments du vecteur v. 2.4 Représentation et implantation (30mn) Implanter une fonction ou un algorithme, c est la réponse à la question «Comment?» ci-dessus. Il faut choisir quel(s) type(s) Python utiliser, mais aussi comment les valeurs y sont stockées. Nous proposons d étudier la représentation d un vecteur creux par une liste de doublets [indice, valeur] (valeur est une valeur numérique quelconque. Pour simplifier on travaille avec des entiers, mais le code marchera aussi avec des flottants par exemple). Pour mémoriser la taille du vecteur, on force la dernière valeur à être représentée par un doublet même si elle est nulle. Les autres valeurs nulles ne sont pas représentées (on interdit la présence d un doublet [indice, 0] si indice n est pas le dernier élément du vecteur). Par exemple, le vecteur [1, 0, 0, 0, 12, 5, 0, 42, 0, 0] est représenté par : [[0, 1], [4, 12], [5, 5], [7, 42], [9, 0]], qui se lit «la valeur 1 à l indice 0 puis la valeur 12 à l indice 4, puis..., et toutes les autres valeurs sont nulles». On donne la fonction afficher_vecteur(v) qui affiche le vecteur v mathématique (c est à dire, valeurs nulles comprises) : def afficher_vecteur ( v): print (' [ ', end =' ' ) first_zero = 0 for pair in v: pos = pair [0] val = pair [1] # Note : on peut aussi é crire # pos, val = pair # On affiche les é ventuels zé ros depuis la derni è re valeur : for i in range ( pos - first_zero ): print (0, end =' ' ) # Puis la valeur non - nulle elle - mê me : print (val, end =' ' ) first_zero = pos + 1 print (' ]' ) Expliquer le code et le faire tourner au tableau sur un exemple. On note S la taille du vecteur et N le nombre d éléments non-nuls. Quelle est la complexité pire cas et meilleur cas de afficher_vecteur(v) en fonction de S et N? Donner l implantation en Python des fonctions suivantes : creer_vecteur(n) (indice : 1 ligne suffit) taille_vecteur(v) (indice : 1 ligne suffit) Voir fichier vecteur_creux_sentinelle.py séparé. Évaluer la complexité de ces deux fonctions.... Quelle serait la complexité de ces deux fonctions avec des vecteurs classiques (non creux)?... Donnez l implémentation de la fonction changer_valeur(vect, i, val) (indice : c est un peu plus compliqué qu on aurait pu le croire, cette fois-ci il faudra une dizaine de ligne). Quelle est la complexité (pire et meilleur cas) de cette fonction? 4

Donnez l implémentation de la fonction comparer_vecteur(v1, v2). Quelle est sa complexité? Quelle serait la complexité de cette fonction si on n avait pas interdit les doublets [indice, 0]? 2.4.1 Note sur l examen Un des exercices de l examen portera sur les vecteurs creux. Les opérations rappelées section 2.1 seront rappelées dans le sujet d examen. 5