MATHÉMATIQUES DISCRÈTES Chapitre 2 (section 1) François Meunier DMI
Algorithmes Fondement de la programmation et du développement de logiciel. Généralement, un algorithme représente une procédure définie effectuant une tâche donnée. Un programme est une description d’un algorithme, écrit dans un language qu’un ordinateur peut interpréter, utilisant que des opérations que l’ordinateur peut exécuter. Un programme est l’implémentation de son algorithme correspondant.
Algorithmes déjà utilisés Arithmétique: Addition de deux nombres naturels sous forme décimale, en utilisant la retenue. Similaire: Soustraction en utilisant l’emprunt. Multiplication & division. Votre recette de cuisine préférée. Comment vous inscrire aux cours de l’UQTR. Comment voter auX électionS.
Langages de programmation Langages programmation communs: Récents: Java, C, C++, C#, Visual Basic, JavaScript, Perl, Tcl, Pascal, et autres… Anciens: Fortran, Cobol, Lisp, Basic Assembleurs, codage de bas-niveau. Dans ce cours, nous utiliserons un langage “pseudo-code”.
Exemple d’Algorithme (Français) Tâche: Avec une séquence {ai}=a1,…,an, aiN, trouver le plus grand élément. Algorithme correspondant, en Français: Initialiser une variable temporaire v (valeur la plus grande actuelle) à la valeur de a1. Inspecter les prochains éléments ai dans la séquence. SI ai>v, Alors ré-initialiser v avec la valeur de ai. Répéter les 2 dernières étapes tant qu’il y a des éléments dans la séquence, & retourner v.
Execution d’un Algorithme Quand un logiciel est démarré, son programme ou son algorithme est alors exécuté par un ordinateur. Avec un algorithme, nous pouvons aussi faire l’exécution à la main, en parcourant chacune des étapes de façon crayon-papier. Avant ~1940, “ordinateur” signifiait une personne dont la tâche était d’exécuter des algorithmes.
Exécution de l’algorithme Max Avec {ai}=1,7,12,3,15,8,5. Trouver le maximum… Initialiser v = a1 = 1. Inspecter l’élément: a2 = 7. SI a2>v? OUI, alors v est initialisé à 7. Inspecter l’élément : a3 = 12. SI 12>7? OUI, v est initialisé à 12. SI 3>12? NON, v reste inchangé. SI 15>12? OUI, v est initialisé à 15.
Caractéristiques d’un Algorithme Input: Informations entrantes. Output: Informations sortantes. Précision: Algorithme définit précisément. Correctitude: Outputs reliés aux inputs. Finitude: Exécutable dans un temps fini. Efficacité: Chaque instruction est exécutable. Généralité: Fonctionne pour différents inputs. Efficience: Utilise un minimun de ressources (CPU, mémoire).
Langage Pseudocode Déclaration ÉNONCÉS procédure nom(argument: type) variable := expression Énoncés informels début énoncés fin {commentaires} si condition alors énoncés [sinon énoncés] pour variable := valeur initiale à valeur finale faire énoncés tant que condition faire énoncés nomproc(arguments) retourne expression
procédure nomproc(arg: type) Permet de définir une procédure nomproc avec comme inputs (arguments) arg qui sont des objets de type type. Exemple: procédure maximum(L: liste d’entiers) [énoncés cherchant le maximum…]
variable := expression Un énoncé d’assignation évalue l’expression expression, et réassigne la variable à la valeur du résultat. Exemple d’assignation: v := 3x+7 (si x est 5, v devient 22.) En pseudocode, une expression peut être exprimée de façon informelle: x := entier le plus grand de la liste L
Énoncé Informel Nous pouvons écrire un énoncé informel en français, si son sens reste clair et précis: ex: “permuter x et y” Seulement possible en pseudo-code. Un algorithme ne doit pas être trop général, trop vague. Décomposer un algorithme en étapes assez detaillées.
début énoncés fin Grouper une séquence d’énoncés ensemble: début énoncé 1 énoncé 2 … énoncé n fin Cette séquence est utilisée comme un seul énoncé. Peut être utilisé: Après la déclaration d’une procédure. Dans un énoncé si après le alors ou le sinon. Dans le corps des boucles pour ou tant que. Parenthèses {} sont utilisées dans plusieurs langages.
{commentaire} Pas exécuté (ne fait rien). Texte en Langage-Naturel exprimant certains aspects de la procédure aux lecteurs humains. Aussi appelé remarque (REM) dans des langages de programmation, ex:. BASIC. Exemple, du programme max: {Noter que v est le plus grand entier trouvé actuellement pour un i donné.}
si condition alors énoncé Évaluation de l’expression propositionelle condition. Si le résultat de la proposition est VRAIE, alors exécuter les énoncés énoncés; autrement, passer aux énoncés suivant l’énoncé si. Variante: si cond alors énon1 sinon énon2 ssi cond est Fause, exécuter énon2.
tant que condition énoncés Évaluer l’expression propositionelle (Booléenne) condition. Si le résultat est Vrai, alors exécuter énoncés. Répéter ces deux actions tant que condition n’est pas Fause; alors poursuivre au prochain énoncé.
pour var := début à fin énoncés début une expression entière. fin une expression entière. Sens: Répéter l’exécution des énoncés, avec la variable var := début, ensuite avec var := début+1, ensuite avec var := début+2, etc., avec finallement var := fin. Question: Qu’arrive-t-il si énoncés changent la valeur de var, ou les valeurs des expressions de début ou fin ?
pour var := début à fin énoncés Le pour peut être exprimé en terme du tant que: début var := début tant que var fin début énoncés var := var + 1 fin fin
procédure(argument) Un appel de la procédure procédure, en fournissant en input les valeurs des expressions argument. Plusieurs langages de programmation réfèrent à la notion de fonctions (un appel de procédure est similaire à l’application d’une fonction f(x)), ou sous-routines, sous-programmes, ou méthodes.
Procédure Max en pseudocode procédure max(a1, a2, …, an: entiers) v := a1 {premier élément plus grand} pour i := 2 à n {visiter les autres éléments} si ai > v alors v := ai {autre plus grand} { v correspond à la valeur la plus grande de la liste} retourner v
Exemple de création d’algorithme Supposons que nous voulons écrire un algorithme qui évalue le prédicat: EstPremier:N→{T,F} Détermine si un nombre naturel donné est premier. Définir une première forme de cette fonction en logique des prédicats: n: EstPremier(n) ¬1<d<n: d|n d divise n sans reste
Exemple EstPremier , suite… Notez que la forme existentielle peut être réécrite sous forme universelle : ¬1<d<n: d|n 1<d<n: d | n 2≤ d ≤ n−1: d | n La forme universelle peut être traduite directement sous forme d’un énoncé de boucle pour: pour d := 2 to n−1 { Tester les diviseurs >1 & <n } si d|n alors retourner F {n a un diviseur d; non premier} retourner V { aucun diviseur; n est premier} d ne divise pas n de façon entière (reste ≠0)
Optimiser EstPremier Optimisation possible: pour d := 2 à n1/2 si d|n alors retourner F retourner V Théorème soujacent: Si n a des diviseurs entiers, d ≤ n1/2. Preuve: Supposons un diviseur de n, a > 1, avec b :≡ n/a. Alors n = ab, mais si a > n1/2 alors b < n1/2 (sachant que a est le plus petit diviseur) et n = ab = (n1/2)2 = n, donc b serait alors un diviseur < que a ce qui est une contradiction. Notez un intervalle de recherche plus petit.
Autre exemple Problème de recherche dans une liste ordonnée. Avec une liste L de n éléments triés dans un ordre donné (ex: numérique, alphabétique), Avec un élément x donné, Déterminez si x est dans la liste, Si présent, retourner la position de x dans la liste.
Algo. #1: Recherche Linéaire procédure recherche linéaire (x: entier, a1, a2, …, an: suite d’entiers) i := 1 {commencer au début de la liste} tant que (i n x ai) faire {TTQ non trouvé} i := i + 1 {prochaine position} fin si i n alors position := i {trouvé} sinon position := 0 {non trouvé} retourner position {0 si non trouvé}
Algo. #2: Recherche Binaire À chaque étape, inspecter l’élément milieu de la liste résiduelle pour la séparer en deux et en éliminer aussi la moitié pour ainsi converger vers l’élément recherché. <x <x <x >x
Algo. #2: Recherche Binaire procédure recherche binaire (x:entier, a1, a2, …, an: suite d’entiers) i := 1 {extrémité gauche de l’intervalle} j := n {extrémité droite de l’intervalle} tant que i<j début {TTQ intervalle >1 élément} m := (i+j)/2 {point milieu} si x>am alors i := m+1 sinon j := m fin si x = ai alors position := i sinon position := 0 retourner position
Autres exercises Algorithme qui calcule la somme des valeurs entières d’un liste. procédure somme(a1, a2, …, an: entiers) s := 0 {accumulateur} pour i := 1 à n faire {parcourir la liste} s := s + ai {+ l’élément ai} {s est la somme de tous les éléments} retourner s
Algorithme de tri Les opérations de tri sont communes dans plusieurs applications. Ex: tableurs, BD Aussi utiliser comme fonction dans des algorithmes de traitement de données. Deux algorithmes de tri: Tri à bulle Tri par insertion Peu efficaces, ne devraient pas être utilisés sur de larges BDs
Tri à bulle Les éléments les plus petits montent en haut de la liste. 30 31 1 32 33 2 34 3 30 1 31 32 2 33 3 34 1 30 31 2 32 3 33 34 1 30 2 31 3 32 33 34 1 2 30 3 31 32 33 34 1 2 3 30 31 32 33 34
Tri par insertion Description de l’algorithme: Pour chaque élément de la liste, “Insérer” cet élément à la position appropriée dans la liste triée générée actuellement: Faire une recherche binaire pour trouver la position où doit être inséré le nouvel élément. Déplacer les éléments déjà triés de une position vers le bas. Insérer le nouvel élément à la position laissée vacante.
Revue: Algorithmes Caractéristiques des algorithmes. Pseudocode. Exemples: Algorithmes Max, nombre premier, recherche linéaire & binaire, de tri. Comment évaluer formellement l’efficacité des algorithmes?