Les principes de l Algorithmique et Programmation 1 Introduction Informatique : traitement automatisé de l information. Algorithme : ensemble de règles opératoires dont l application permet de résoudre un problème en un nombre fini d opérations. Programme : séquences d instructions et de données enregistrées sur un support et susceptibles d être traitée par un ordinateur. Données : objets manipulés par le programme. Structures de Données : organisation des données dans des structures ayant une représentation fixée et des opérations d accès, modification,... Le programme est la traduction d un algorithme et des structures de données dans un langage de programmation qui impose une syntaxe rigoureuse. Objectif de l analyste programmeur : Ecrire un programme dans un langage donné dont l exécution permet de résoudre un problème. Exercice 1 Donner les avantages d un algorithme sur un programme. Donner les avantages d un programme sur un algorithme. Exercice 2 Citer des exemples d algorithmes. 1
Exercice 3 Le texte suivant est-il un algorithme? Recette de la pate à choux : Ingrédients : 1/4 litre d eau, 100g de beurre, 125g de farine, 4 oeufs,1 pincée de sel, 1 cuillérée de sucre. Dans une casserole, faire bouillir l eau avec le beurre, le sel le sucre. A la première ébullition, retirer la casserole du feu, et verser la farine. Tourner rapidement avec un ecuillère en bois en travaillant sur le feu jusqu à ce qu elle se détache complètement de la casserole. Hors du feu ajouter les oeufs un à un en travaillant chaque fois la préparation avec la cuillère. 2 Les Langages 2.1 Constituants Une langue : Syntaxe : catégories de mots (noms, verbes, adjectifs,...), règles de grammaire... Analyse lexicale permet de reconnaitre les mots de la langue. Analyse syntaxique permet de reconnaitre les phrases bien formées. Sémantique : une phrase bien formée n a pas toujours un sens. Catégories de langages : langue naturelle : syntaxe et sémantique assez laxistes mais souple d emploi. On peut se comprendre même avec des phrases peu orthodoxes et incorrectes. Sémantique intuitive mais pouvant être ambigue. Le récepteur est un être humain intelligent et réactif. langage informatique : syntaxe rigoureuse et rigide. La sémantique n est pas intuitive et met en oeuvre des cadres complexes (meme si les principes sont simples) et difficiles à bien apprehender. Le récepteur est une machine denuée d intelligence. langage de description d algorithme : une syntaxe moins rigide mais assez stricte pour ne pas donner d ambiguité sur la sémantique de ce qui est décrit. 2.2 Un exemple Problème : Donner la table de conversion de franc en euro de 100 en 100 depuis 0 jusqu à 1000 en utilisant un coefficient de conversion de 6.56 Données : somme en franc et euros Algorithme : répétition du calcul de conversion de 100 en 100 MIN=0 MAX=1000 INTER=100 COEF=6.56 franc=min Tant que franc <=MAX faire euro=franc/coef afficher euro franc=franc+inter fait Programmes C : /* File: conver.c Auteurs: Prof cree le 08 02 04 modifie le: 08 02 04 */ /* conversion des sommes en francs en euros */ /* affichage de 0 a 1000 par intervalle de 100 */ #include <stdio.h> 2
#define MIN 0 /*somme minimale a convertir */ #define MAX 1000 /*somme maximale a convertir */ #define INTER 100 /*intervalle entre deux sommes*/ #define COEF 6.56 /*coefficient de conversion */ int main () { float franc, euro; franc=min; while (franc <= MAX) { euro = franc / COEF; printf("somme: en franc %4.0f en euro %6.2f\n",franc, euro); franc=franc+inter; } return 0; } Programme : def franc2euro(): " conversion des sommes en francs en euros \ affichage de 0 a 1000 par intervalle de 100" MIN=0 MAX=1000 INTER=100 COEF=6.56 franc=min while (franc<=max): euro=franc/coef print "somme en franc: ",franc, "en euro: ",euro franc=franc+inter Les deux programmes sont similaires mais différents : l un est plus simple que l autre. Tous les deux sont décrits dans un langage impératif 1 et implémentent un même algorithme de conversion qui repose sur la répétition d une opération simple. Dans ce cours d initiation, nous allons apprendre à écrire des programmes en. Exercice 4 Trouver les exemples d algorithmes les plus anciens connus. Calcul de surface (carré, triangle,..), algorithme d euclide (1er siecle), des restes chinois. Exercice 5 Décrire l algorithme de résolution d une équation du second degré. 3 Langage et Machine Pour commencer nous donnons la syntaxe des langages que nous utilisons. Nous donnons à la fois la syntaxe d un vrai langage informatique : et un langage de description d algorithme. 3.1 Commentaires Les commentaires servent à expliquer le comportement du programmes (en langue naturelle) et ne jouent aucun role dans le comportement du langage. #ce programme calcule la surface d un cercle 1. en fait python est un langage objet, mais on ne le verra que sous son aspect impératif 3
3.2 Les expressions Les noms appelés identificateurs : désignent des variables, fonctions,... Usuellement x,y,pi,taux de change,..., i.e. suite de caractères (commençant par une lettre en général) Les expressions : combinaisons de noms, valeur définies, avec des opérateurs (prédéfinis dans le langage et fabriqués par le concepteur du programme). pi*(r**2), x+z,... Exp ::= C Idf Exp op Exp Ici seuls des opérateurs binaires notés de manière infixée sont utilisés. La définition s étend si on a des opérateurs unaires, ternaires,..., des appels de fonctions f(exp 1,...,exp n ) (si f est l identificateur notant une fonction qui a une arité n). Certaines suites de caractères ne sont pas autorisées comme identificateurs car ce sont des mots réservés : leur sens est prédéfini et correspond à des constructions du langage. Exemple if, while, for,... Opérateurs classiques : Arithmétique :+,-,*,/, % Opérateur de comparaison (à résultat booléen V ou F) <,>,==,<=,>= Opérateur booléen and, or (à arguments et résultat booléen) Ambiguité : que signifie 4+3*2? Pour lever les ambiguités on utilise le parenthésage (4+3)*2 ou 4+(3*2) ou bien les règles de priorité prédéfinies : **plus fort que *,/ plus forts que +,-. Sinon l évaluation se fait de Gauche à Droite en cas de même priorité : 5*10/6 Exercice 6 Donner le résultat de l évaluation de : 2**3*3-1, 8/2+3, 1-2*3+1 3.3 Constructions de base Remarque : en python, l indentation fait partie de la syntaxe (elle remplace l utilisation de parenthèse ou de mots clé begin end). Instructions de base affectation : var=exp var=exp Sens intuitif : Donne la valeur de exp à var condition : si cond alors Ins1 sinon Ins2 fsi if cond: Ins1 else: Ins2 avec la variante elif en cas de suite de conditions Sens intuitif : si l évaluation de cond donne vrai on évalue Ins1 sinon on évalue Ins2. Itération : Tant que cond faire Inst fait : while cond: Inst Sens intuitif : Tant que evaluer cond donne vrai on effectue Inst Sequence : Ins1 Ins2 Ins1 Ins2 Sens intuitif : Ins1 est effectuée suivie de Ins2 (si Ins1 termine). 4
Entree/sortie : x=input() output(x) x=input() ou x=raw_input() print x Appel de fonction : f(x 1,...,x n ) (si f est une fonction d arité n qui ne renvoie pas de résultat, comme print ou read). x=f(x1,..;,xn) Si on veut utiliser une fonction qui renvoie une valeur, cela se fera en utilisant l affectation x = f(exp 1,...,exp n ). Notation graphique : elle permet de représenter la structure de contrôle du programme de manière visuelle. L objet représenté est appelé le graphe de contrôle du programme. Affectation x:=exp x:=exp Conditionnelle if cond then Inst1 else Inst2 fi true cond false While cond do Inst false cond true Inst1 Inst1; Inst2 Inst Inst2 Langage correspond à une syntaxe rigoureuse (/= langue nat). Un programme est source est une phrase de ce langage. Il reste une suite de caractères pouvant etre écrite par un éditeur et compréhensible par l humain. Un programme appelé compilateur traduit ce texte en un programme exécutable (binaire ou code objet) qui est un ensemble d instructions machine (compréhensible par la machine mais pas l humain). Dans un langage interpreté le source est traduit à la volée en instruction machine. Source > compilé > bytecode > interprété > résultat 3.4 Typage Chaque variable a un type. Un type est un ensemble de valeurs (les entiers, les réels,..) et chaque type correspond une représentation machine. Le type int correspond aux entiers représentés sur 32 bits (ou 64) de -2**31 à 2**31-1. Le type long correspond aux entiers de taille supérieure. Le type float correspond aux réels représentés selon la norme IEEE sur 64 bits. Les types simples sont les types int long float. Les autres types sont les types composites (ou complexes) chaines, listes,... Ils seront décrits plus en détail ultérieurement. En le typage est dynamique : l interpréteur calcule le type des variables à la volée sans que celui-ci doive être déclaré (comme en C, Java). Dans ces langage le typage est statique car il est calculé à la compilation du programme. 5
4 Modèle d exécution 4.1 Mémoire Mémoire d une machine Environnement adresse case mémoire 0 1... 999 1000 nom de variable x 1... x n adresse case mémoire 0 réservée 1 val 1... n val n... 1000 Le lien entre nom et adresse se fait lors de la compilation. L exécution du programme correspond se définit en décrivant comment l environnement est modifié par les instructions du programme et comment les expressions sont calculées dans l environnement courant. 4.2 Sémantique opérationnelle Le sémantique opérationnelle est un modèle abstrait qui permet d associer un sens précis à un langage. On modélise l environnement par une suite (x 1,v 1 ),...,(x n,v n ) avec x 1,...,x n les variables du programme et v 1,...,v n des valeurs. Env est l ensemble des environnements et I l ensemble des programmes (vus comme une suite d instructions). Dans ce qui suit E désigne un environnement (E Env). Règle d evaluation d une expression On considère les expressions données par la grammaire: Exp ::= C Idf Exp op Exp avec C une valeur constante (dans R ou Z). La fonction eval(e,e) décrit comment donner une valeur à une expression e Exp dans un environnement E Env. eval(e,c) = C eval(e,x i ) = v i eval(e,e 1 op e 2 ) = v 1 op v 2 v 1 = eval(e,e 1 ),v 2 = eval(e,e 2 ) Sémantique d un programme Le sémantique d un programme (suite d instructions I) est une fonction Env,I Env qui décrit comment calculer un environnement E se transforme en un environnement E quand on exécute I. eval(e,e) v (E,x = e) E [x v] Exemple : E = {(x,1),(y, 1)} et I = x = y +x alors eval(e,x+y) donne 0 et donc (E,x = y +x) {(x,0),(y, 1)} eval(e,cond) = True E,I 1 E (E,if cond then : I 1 else I 2 ) E eval(e,cond) = False E,I 2 E (E,if cond then : I 1 elsei 2 ) E eval(e,cond) = True E,I E (E,while cond : I) (E,while cond : I) 6
eval(e,cond) = False (E,while cond : I) E Une manière compliquée d exprimer des choses naturelles? Le modèle est plus intéressant quand on cherche à définir fonctions du premier ordre ou d ordre supérieur, mécanisme d exceptions,...ou qu on veut définir la sémantique d un langage objet. Dans ce modèle on voit qu évaluer une expression sans affecter le résultat ne modifie pas l environnement donc c est une opération inutile. Modèle concret : voir cours d initiation. Le compilateur ou l interpréteur traduit le programme en instructions machine exécutables par le processeur. Les données et les instructions sont chargées dans les registres du CPU, registre compteur ordinal, compteur instruction, le registre et l UAL exécute. Ici tout est représentation binaire 0 ou 1. 5 De l Analyse au Programme Une fois défini le problème, on commence par identifier et structurer les objets qui interviennent (les données), puis on détermine la méthode permettant de résoudre le problème (l algorithme), et enfin on combine le tout en un programme. Ce processus se décrit par Programme= Structure de Données + Algorithme (Loi de Wirth, d après Niklaus Wirth) Poser et analyser le problème. Cette étape sert à bien comprendre ce qui est à faire, permet de préciser certains points. Cela correspond à l analyse du cahier des charges. Ecrire un programme permettant de trouver le cout du trajet le plus court entre deux stations de métro Quels objets et quelles structures de données? Identifier la manière dont les objets intervenant dans le programme sont structurés et se représentent à l aide de données informatiques classiques : variables, chaines, listes, arbres, graphes,...qui correspondent à une représentation et des opérations sur ces représentations. Graphe des lignes de métro avec opération successeur, prédeceseur, cout d une arete,... Un station est un noeud, s il y a un ligne passant entre deux stations on ajoute une arête (non-orientée, c.a.d. qu on peut la prendre dans chaque sens). La SD donne pour chaque station la liste des stations accessibles. Elle donne également pour chaque arête le cout de cette arête 2. Quel Algorithme? Quel est le mécanisme de calcul qui va permettre de résoudre le problème (formule de calcul des solutions d une équation, exploration d un arbre de recherche,...). Il y a des techniques d analyse (descendante, ascendante, objet,...) qui permettent d affiner l analyse jusqu à obtenir une méthode n utilisant que des constructions élémentaires qui se transposent facilement en des instructions de programmation. graphe,...) à partir des objets représentés dans les SD choisies. Ici on cherche une fonction trajetmin(s,t) qui renvoie le cout minimal entre s et t. Idée de départ : Partir de s i et pour chaque successeur s calculer cout(s i,s)+trajetmin(s,s f ) et garder la valeur minimale. Cette idée doit être raffinée : 1. Cas d arrêt du calcul (cas terminal) : s = t 2. Transformer garder la valeur minimale en une itération calculant cette valeur. 3. Il ne faut pas tourner en rond : nécessité de marquer les sommets pour signaler qu on ne doit pas revenir sur un sommet déjà visité. 2. pour un graphe orienté, les arêtes ne sont pas symétriques, (s,t) peut exister mais pas (t,s) et le coût peut être différent entre (s,t) et (t,s) 7
4. Enlever le marquage une fois le calcul terminé. Cette première approche de l algorithme impose de modifier la structure de donnée en ajoutant pourchaquesommetunemarque(vrai,fauxou0,1ou..)poursavoirsilesommetpeut êtreutilisé. Une version plus précise de l algorithme est : trajetmin(s,t) : # calcul du plus court chemin entre s et t #le graphe est supposé connexe si s==t alors renvoyer le résultat 0 sinon fsi marquer s cout=+infini pour chaque successeur non marqué s de s faire cout=min(cout, coutarete(s,s )+trajetmin(s,t)) fait demarquer(s) renvoyer le résultat cout Validation de l algorithme Une fois un algorithme déterminé il faut répondre à plusieurs questions qui peuvent entrainer une remise en question de l algorithme. L algorithme est il correct : Donne-t-il la bonne réponse dans tous les cas? Répondre à cette question est difficile et on se limitera à des preuves informelles dans le cadre de ce cours. Voir comment il traite les cas limite, faire un raisonnement informel pour prouver la correction sont essentiels ici. Est-ce que l algorithme est suffisamment efficace : cela demande une analyse de complexité. On se limitera aux cas facile dans ce cours. Est-ce que l algorithme est facile à implémenter? Un algorithme simple est toujours préférable. Passage au programme En utilisant une implémentation des structures de données et l algorithme choisi, on peut passer aux instructions dans le langage de programmation choisi. Dans le cas précédent, l implémentation des structures de données choisies se fera avec des listes qui permettront de réaliser tous les opérations utilisées dans l algorithme. Validation du programme Une fois le programme écrit, on le valide par un jeu de tests qui permet de constater que son comportement est conforme à la spécification (l énoncé du problème). Eventuellement on corrige et on recommence. Les tests doivent aussi permettre de vérifier que la solution trouvée est acceptable en temps de calcul et place mémoire demandée. Par exemple, l algorithme décrit ci-dessus se revèlera rapidement inefficace pour des graphes de grande taille et il est nécessaire d en trouver de plus rapide (ce qu on fera plus tard en utilisant des algorithmes reposant sur le principe de programmation dynamique). Que retenir? Voici des questions auxquelles il faut savoir répondre sans hésiter et qui portent sur les points importants à comprendre et retenir. Une réponse syntaxiquement correcte ne suffit pas, il faut aussi comprendre la question et savoir expliquer sa réponse. Quel est le principe de fonctionnement d une machine Pourquoi doit-on apprendre un langage de programmation? Qu est-ce qu un algorithme? Qu est-ce qu un langage de programmation? Quelle est la différence entre langage de programmation et algorithme? 8
A quoi sert un compilateur? Quelle différence entre un compilateur et un éditeur de texte? Qu est-ce qu un programme source? Qu est-ce qu un exécutable? Qu est-ce qu une donnée? une structure de donnée? Quelles sont les instructions de bases d un langage impératif? Commment décrire un algorithme? 9