Corrigé du TP n o 5 2013/2014. Lycée Louis-Le-Grand, Paris MPSI 4 Informatique pour tous A. Troesch, J.-P. Becirspahic



Documents pareils
Présentation du langage et premières fonctions

TP 1. Prise en main du langage Python

1 Recherche en table par balayage

Chapitre 2 Devine mon nombre!

Découverte de Python

Probabilités. I Petits rappels sur le vocabulaire des ensembles 2 I.1 Définitions... 2 I.2 Propriétés... 2

Utilisation d objets : String et ArrayList

NOTIONS DE PROBABILITÉS

Initiation à la programmation en Python

STAGE IREM 0- Premiers pas en Python

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

Recherche dans un tableau

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

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

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Cours 7 : Utilisation de modules sous python

Corrigé des exercices sur les références

Algorithmique et Programmation, IMA

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

Les bases du langage Python

I. Introduction aux fonctions : les fonctions standards

Initiation à l algorithmique

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

Probabilités sur un univers fini

NOTE SUR LA MODELISATION DU RISQUE D INFLATION

Probabilités Loi binomiale Exercices corrigés

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

Calcul Formel et Numérique, Partie I

Introduction à MATLAB R

INF 321 : mémento de la syntaxe de Java


Programmation Web. Madalina Croitoru IUT Montpellier

Simulation de variables aléatoires

Cours 1 : Qu est-ce que la programmation?

LES DECIMALES DE π BERNARD EGGER

Module Administration BD Chapitre 1 : Surcouche procédurale dans les SGBDS

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


Licence Sciences et Technologies Examen janvier 2010

Perl Orienté Objet BioPerl There is more than one way to do it

Définitions. Numéro à préciser. (Durée : )

Atelier C TIA Portal CTIA04 : Programmation des automates S7-300 Opérations numériques

Programmer en JAVA. par Tama

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)

* très facile ** facile *** difficulté moyenne **** difficile ***** très difficile I : Incontournable T : pour travailler et mémoriser le cours

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

# let rec concat l1 l2 = match l1 with [] -> l2 x::l 1 -> x::(concat l 1 l2);; val concat : a list -> a list -> a list = <fun>

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

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

Programme Compte bancaire (code)

Les classes en Python

Compléments de documentation Scilab : affichage de texte et formatage de nombres

L informatique en BCPST

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

Définition 0,752 = 0,7 + 0,05 + 0,002 SYSTÈMES DE NUMÉRATION POSITIONNELS =

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

PHP et mysql. Code: php_mysql. Olivier Clavel - Daniel K. Schneider - Patrick Jermann - Vivian Synteta Version: 0.9 (modifié le 13/3/01 par VS)

Introduction à l algorithmique et à la programmation (Info 2)

Editer un script de configuration automatique du proxy

Surveillance et maintenance prédictive : évaluation de la latence de fautes. Zineb SIMEU-ABAZI Univ. Joseph Fourier, LAG)

Sujet proposé par Yves M. LEROY. Cet examen se compose d un exercice et de deux problèmes. Ces trois parties sont indépendantes.

DM 1 : Montre Autoquartz ETA

Algorithme des fourmis appliqué à la détection et au suivi de contours dans une image

Solutions du chapitre 4

DU BINAIRE AU MICROPROCESSEUR - D ANGELIS CIRCUITS CONFIGURABLES NOTION DE PROGRAMMATION

Encryptions, compression et partitionnement des données

POKER ET PROBABILITÉ

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Paginer les données côté serveur, mettre en cache côté client

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

4. Groupement d objets

Représentation des Nombres

Algorithmique, Structures de données et langage C

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

1 Lecture de fichiers

V- Manipulations de nombres en binaire

Le langage SQL Rappels

Tp 1 correction. Structures de données (IF2)

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

Impact des robots d indexation sur le cache de second niveau de SPIP IMBERTI Christophe - SG/SPSSI/CP2I/DO Ouest 06/06/2012 mis à jour le 05/07/2012

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

Algorithmique I. Algorithmique I p.1/??

2. Comprendre les définitions de classes

Probabilités et Statistiques. Feuille 2 : variables aléatoires discrètes

Image d un intervalle par une fonction continue

Corrigé des TD 1 à 5

Bac Blanc Terminale ES - Février 2011 Épreuve de Mathématiques (durée 3 heures)

Projet de programmation (IK3) : TP n 1 Correction

AWS avancé. Surveiller votre utilisation d EC2

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

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

Programmation Python pour Arcgis

Probabilités sur un univers fini

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Chapitre 1. L intérêt. 2. Concept d intérêt. 1. Mise en situation. Au terme de ce chapitre, vous serez en mesure de :

Représentation d un entier en base b

2 Comment fonctionne un ordinateur, dans les grandes lignes

Analyse de sécurité de logiciels système par typage statique

Architecture des Systèmes d Information Architecture des Systèmes d Information

Transcription:

Lycée Louis-Le-Grand, Paris MPSI 4 Informatique pour tous A. Troesch, J.-P. Becirspahic 2013/2014 Corrigé du TP n o 5 Exercice 1. recherche d un élément dans un tableau non trié 1. Le principe de la recherche d un élément dans un tableau non trié est simple : un parcours séquentiel jusqu à trouver cet élément ou aboutir à la fin de la liste. def est_present(a, lst): Notons toutefois que cette fonction n est guère utile en pratique car si x est un objet python et seq une séquence (c est à dire un objet de type list, tuple, range, str et quelques autres), l expression «x in seq» répond à la question posée. Par exemple : >>> 3 in [1, 2, 3, 4, 5] True >>> 5 in range(2, 10, 2) False >>> 'y' in 'asymptote' True 2. Si on souhaite retourner l indice minimum de la liste correspondant à l élément recherché, se pose la question de savoir quoi faire en cas d absence de cet élément. Une solution simple consiste à afficher à l écran un message signalant le problème ou à retourner la valeur None : def indice(a, lst): print("l'élément recherché n'est pas dans la liste") mais il existe une solution plus élégante consistant à déclencher une exception. Une exception se déclenche et interrompt le script en cours dès lors qu un évènement inattendu se produit : erreur arithmétique, variable non définie, erreur de typage, etc. Par exemple : >>> 1 + 2 / 0 ZeroDivisionError: division by zero >>> 1 + a NameError: name 'a' is not defined >>> 2 + '3' TypeError: unsupported operand type(s) for +: 'int' and 'str' Il est possible de déclencher une exception à l aide de l instruction raise ; c est ce que nous allons faire dans le cas où x ne se trouve pas dans lst : def indice(a, lst): raise ValueError('élément non trouvé') Par Exemple : >>> indice(5, [1,2,3,4,6,7,8,9]) ValueError: élément non trouvé L intérêt de cette démarche est qu il est possible de rattraper une exception à l aide de la syntaxe try... except. Illustrons ceci en revenant un instant sur la première question de cet exercice, et utilisons cette fois une boucle conditionnelle pour parcourir les éléments de la liste : page 1

def est_present(a, lst): while lst[k]!= a: Cette version n est pas satisfaisante : elle renvoie bien True lorsque a est dans la liste, mais déclenche l exception IndexError dans le cas contraire (dès lors que k >= len(lst)). Nous allons la corriger en rattrapant cette exception pour renvoyer False à la place : def est_present(a, lst): try: while lst[k]!= a: except IndexError: Notez enfin qu il est possible de créer ses propres exceptions si celles qui sont prédéfinies ne suffisent pas (consulter l aide en ligne pour plus d information sur les exceptions). L exercice 2 nous donnera une autre occasion d illustrer l intérêt de ce mécanisme de rattrapage d une exception. 3. Calculer le nombre d occurrences d un élément dans une liste ne présente aucune difficulté : def occurrences(a, lst): 4. Nous allons maintenant simuler la recherche d un élément de l intervalle 0, N 1 dans une liste de 10000 éléments du même intervalle, en réalisant 1000 fois l expérience. Pour ce faire, nous allons modifier la fonction de la première question de manière à dénombrer le nombre d éléments testés : def est_present(a, lst): Nous allons utiliser la fonction randint du module numpy.random qui permet de créer un tableau pseudo-aléatoire d une taille donnée : from numpy.random import randint La fonction permettant de réaliser l expérience se définit alors de la façon suivante : def moyenne(n): for k in range(1000): s += est_present(randint(n), randint(n, size = 10000)) print("moyenne des comparaisons effectuées :", s/1000) Quelques essais avec différentes valeurs de N : >>> moyenne(10) moyenne des comparaisons effectuées : 9.861 >>> moyenne(20) moyenne des comparaisons effectuées : 19.788 >>> moyenne(50) moyenne des comparaisons effectuées : 50.183 >>> moyenne(100) moyenne des comparaisons effectuées : 98.527 On constate un coût en moyenne proche de N, ce qui n est pas étonnant. En effet, la probabilité que l élément recherché soit trouvé au bout de k comparaisons est égal à 1 N ( 1 1 N ) k 1 et la probabilité qu il ne se trouve pas page 2

( dans la liste égal à 1 1 ) n donc le coût en moyenne est egal à : N n k=1 ( k 1 1 ) k 1 ( + n 1 1 ) n ( = N 1 ( 1 1 ) n ). N N N N Lorsque n est grand devant N, ( 1 1 N ) n est petit devant 1, et le coût en moyenne proche de N. En revanche, lorsque n et N sont voisins, ( 1 1 N ) n est proche 1 de 1 e donc la complexité en moyenne voisine de N ( 1 1 e ), ce que l on peut constater expérimentalement : >>> moyenne(10000) moyenne des comparaisons effectuées : 6338.666 >>> from math import exp >>> 10000*(1-1/exp(1)) 6321.205588285577 5. Rappelons que l écart-type d un ensemble de valeurs (x 1,...,x n ) se calcule à l aide de la formule : σ = où x désigne la moyenne des valeurs. On calcule moyenne et écart-type en parallèle : from math import sqrt def ecarttype(n): s = s for k in range(1000): x = est_present(randint(n), randint(n, size = 10000)) s += x ss += x*x print("écart-type des comparaisons effectuées :", sqrt(ss/1000-(s/1000)**2)) L expérience montre que lorsque n est grand devant N l écart-type est proche de N : >>> ecarttype(10) écart-type des comparaisons effectuées : 9.011146375461891 >>> ecarttype(20) écart-type des comparaisons effectuées : 19.986668656882266 >>> ecarttype(50) écart-type des comparaisons effectuées : 49.610211841918186 1 n n xi 2 x2 Exercice 2. recherche dans un tableau trié 1. Pour chercher x dans la liste triée par ordre croissant [a 0,...,a n 1 ], nous allons appliquer le principe dichotomique : comparer x et a p avec p = n. 2 si x < a p alors x, s il se trouve dans la liste, ne peut qu être dans la liste [a 0,...,a p 1 ] ; si x = a p, la recherche est terminée ; si x > a p alors x, s il se trouve dans la liste, ne peut qu être dans la liste [a p+1,...,a n 1 ]. Pour mettre ce principe en pratique, nous allons le généraliser à la recherche de l élément x dans la liste extraite [a i,...,a j 1 ] : si i j la liste en question est vide et x ne s y trouve pas ; si i < j l élément médian a pour indice k = i + j et la comparaison entre x et ak ramène la recherche à l un des deux tableaux [a 2 i,...,a k 1 ] ou [a k+1,...,a j 1 ]. i=1 a k a k a k 1. car ( 1 + 1 n def recherche_dicho(a, lst): return None ) n ( ( 1 )) 1 = exp nln 1 = exp( 1 + o(1)) = n e + o(1). i k j 1 page 3

2. Pour pouvoir évaluer expérimentalement le coût de cette fonction, nous allons la modifier en ajoutant un compteur dénombrant le nombre de comparaisons à l élément médian effectués : def recherche_dicho(a, lst): Réalisons alors 1000 expériences à partir d un tableau de longueur n contenant des entiers pris au hasard dans 0,2n : def experience(n): for k in range(1000): s += recherche_dicho(randint(2*n+1), sorted(randint(2*n+1, size = n))) print("moyenne des comparaisons effectuées : ", s/1000) L expérience montre que le nombre de comparaisons est en moyenne de l ordre de log 2 (n) : >>> from math import log >>> experience(10) moyenne des comparaisons effectuées : 3.233 >>> log(10, 2) 3.3219280948873626 >>> experience(100) moyenne des comparaisons effectuées : 6.231 >>> log(100, 2) 6.643856189774725 >>> experience(1000) moyenne des comparaisons effectuées : 9.505 >>> log(1000, 2) 9.965784284662087 3. Si on cherche la première occurrence de a dans le tableau, il faut poursuivre la recherche dans la partie gauche même si on a trouvé a. C est l occasion d utiliser le mécanisme de rattrapage d une exception évoquée dans l exercice précédent, plus particulièrement de l exception NameError qui se déclenche lorsqu on fait appel à un nom de variable non défini : def premiereoccurrence(a, lst): sol = k try: ol except NameError: return None À l issue de la recherche dichotomique, deux situations peuvent se rencontrer : si a est présent dans le tableau, la variable sol contient l indice de la première occurrence et c est ce résultat qui est retourné par la fonction ; si a n est pas présent dans le tableau, la variable sol n a pas été définie et la tentative de retourner son contenu déclenche l exception NameError qui est rattrapée pour renvoyer la valeur None à la place. La recherche de la dernière occurrence se traite de la même façon : page 4

def derniereoccurrence(a, lst): sol = k try: ol except NameError: return None Exercice 3. recherche d un mot dans un texte par la méthode naïve 1. La méthode de recherche naïve d un mot dans un texte consiste à comparer tous les facteurs du texte avec le mot recherché : def recherche(mot, texte): for k in range(len(texte)-len(mot)+1): if texte[k:k+len(mot)] == mot: raise ValueError Si on ne s autorise que des comparaisons entre caractères individuels, il est préférable de commencer par écrire une fonction déterminant si un mot est suffixe d un autre : def suffixe(mot, texte): for k in range(len(mot)): if mot[k]!= texte[k]: (cette fonction suppose que la longueur de mot est inférieure ou égale à celle de texte) avant d écrire la fonction principale : def recherche(mot, texte): for k in range(len(texte)-len(mot)+1): if suffixe(mot, texte[k]): raise ValueError 2. Pour tester cette fonction, commençons par définir une fonction retournant une chaîne de caractère de longueur 1000 arbitraire : def alea(n=1000): chn = 'abcdefghijklmnopqrstuvwxyz' return ''.join([chn[randint(26)] for k in range(n)]) (la méthode S.join renvoie une chaîne de caractères obtenue par concaténation des chaînes passées en paramètres, séparés par les caractères de S ; c est une façon de convertir une liste en un élément de type str). 3. Pour estimer la probabilité qu une chaîne de ce type contienne le mot llg, nous allons modifier la fonction de la première question pour renvoyer un booléen : def recherche(mot, texte): for k in range(len(texte)-len(mot)+1): if texte[k:k+len(mot)] == mot: Réalisons maintenant 10000 fois l expérience consistant à rechercher ce mot dans un texte tiré au hasard : for k in range(10000): if recherche('llg', alea(1000)): print("fréquence d'apparition du mot 'llg' :", s / 10000) Le script ci-dessus donne une probabilité de l ordre de 5,5% page 5

Exercice 4. paradoxe de Walter Penney 1. Nous allons arbitrairement représenter Pile par l entier 0 et Face par l entier 1. Nous pouvons dès lors évaluer le temps d attente de la première apparition de la séquence PPF de la façon suivante : def ppf(): lst = list(randint(2, size = 3)) s = 3 while lst!= [0, 0, 1]: lst.append(randint(2)) del lst[0] Réalisons maintenant 100000 expériences pour évaluer le nombre moyen de tirages nécessaires : for k in range(100000): s += ppf() print('nombre moyen de tirages nécessaires :', s/100000) Le script ci dessus donne un nombre de tirages moyens proche de 8. 2. La même expérience réalisée avec cette fois la séquence FPP donne là encore un nombre de tirages moyens proche de 8. 3. Nous allons maintenant définir une fonction déterminant laquelle des deux séquences apparaît la première : def penney(): lst = list(randint(2, size = 3)) while True: if lst == [0, 0, 1]: return 1 if lst == [1, 0, 0]: return 0 lst.append(randint(2)) del lst[0] 4. Il nous reste à estimer la probabilité que le motif PPF apparaisse en premier en réalisant 100000 expériences : for k in range(100000): s += penney() print('probabilité que PPF apparaisse avant FPP :', s / 100000) Le script ci-dessus conduit à une estimation de l ordre de 25% ; le motif FPP a donc trois fois plus de chances d apparaître en premier. Cet apparent paradoxe s explique aisément en considérant les deux premiers tirages, qui conduisent à l une des quatre configurations équiprobables suivantes : FF, FP, PF et PP. Or les trois premières configurations conduisent nécessairement à l apparition de FPP en premier 2, et seule la troisième fait apparaitre en premier PPF. En réalité, tout est joué après le deuxième tirage! 2. en effet dès lors qu un F est apparu, lorsqu un motif PPF apparaît il est nécessairement précédé d un motif de la forme FPPP PPPF page 6