Académique Documents
Professionnel Documents
Culture Documents
ALGORITHMIQUE APPLIQUÉE
TRAVAUX PRATIQUES
ALGORITHMIQUE
APPLIQUÉE
TRAVAUX PRATIQUES
Retrouvez la liste de nos formations sur www.cned.fr
Pour plus d’informations, appelez le 05 49 49 94 94
Du lundi au vendredi, 8 h 30-18 h.
Coût d’une communication ordinaire.
*82940TPPA0013* www.cned.fr
Sommaire
Conseils généraux 3
TP 1 : Initiation à la cryptographie 5
TP 2 : Inversion de matrice 13
TP 3 : Travail sur les graphes 23
Les cours du CNED sont strictement réservés à l’usage privé de leurs destinataires et ne sont pas destinés à une utilisation collective.
Les personnes qui s’en serviraient pour d’autres usages, qui en feraient une reproduction intégrale ou partielle, une traduction sans
le consentement du CNED, s’exposeraient à des poursuites judiciaires et aux sanctions pénales prévues par le Code de la propriété
intellectuelle. Les reproductions par reprographie de livres et de périodiques protégés contenues dans cet ouvrage sont effectuées
par le CNED avec l’autorisation du Centre français d’exploitation du droit de copie (20, rue des Grands Augustins, 75006 Paris).
© CNED 2013
Conseils généraux
Importance des TP
Dans les conseils généraux du fascicule de cours correspondant, vous avez eu des informa-
tions détaillées sur l’organisation de l’épreuve portant sur ce module. C’est une épreuve
pratique où vous allez devoir montrer vos capacités à écrire un algorithme cohérent,
bien structuré, répondant aux attentes du sujet, mais aussi vos capacités à transcrire cet
algorithme dans un langage de votre choix et à en faire la démonstration sur ordinateur.
Tout au long du fascicule de cours, vous avez eu l’occasion d’écrire des algorithmes et
de les coder en C++. À travers ce fascicule de travaux pratiques, vous allez devoir traiter
des sujets qu’il faudra vous-même gérer de bout en bout. L’aide nécessaire vous sera
apportée mais, le but est de contrôler l’acquisition des connaissances abordées dans le
fascicule de cours. Les différents TP sont progressifs puisqu’ils sont à réaliser à chaque
fois en fin d’une des séquences du cours. Cependant, ils essaient au maximum de couvrir
les attentes techniques de l’examen.
Organisation du fascicule
Ce fascicule contient 3 TP, chacun étant à réaliser à la fin d’une séquence du cours (excep-
té la séquence sur la récursivité). Dans le module de cours, il est clairement précisé à quel
moment réaliser un TP. Suivez bien ces indications et ne cherchez pas à vous précipiter
sur les TP si vous n’avez pas étudié la séquence correspondante.
Chaque TP contient 3 parties :
• Présentation du sujet : vous y trouverez la description détaillée du travail à réaliser.
• Aide : dans le cas de gros blocages, l’aide est divisée en 2 parties. Une partie conte-
nant seulement des indications et une seconde partie comportant une démarche Conseils généraux
étape par étape pour réaliser le travail. Attention, cherchez le maximum par vous-
même, en vous aidant du débogueur. Ne faites appel à l’aide qu’en cas de désespoir Page 3
total. Seul le dernier TP ne possède pas d’aide, pour 2 raisons : le sujet est largement
assez détaillé mais, surtout, ce dernier TP touche quasiment toutes les compétences
attendues et doit être réalisé le plus possible en toute autonomie. N’hésitez pas à
passer beaucoup de temps dessus.
• Correction : contient les algorithmes de la correction. Les codes en C++ sont télé-
chargeables, comme pour les corrections des exercices de cours.
Voici les TP proposés :
TP1 : « Initiation à la cryptographie » va vous permettre d’écrire un petit algorithme très
simple de cryptage, exploitant la manipulation des chaînes et les calculs booléens.
Ce TP est à réaliser en fin de séquence 1 « Instructions algorithmiques de base » du cours.
TP2 : « Inversion de matrice » va vous apprendre à suivre un mode opératoire précis pour
créer un programme basé sur une notion mathématique classique dans le domaine du
calcul de matrices.
Ce TP est à réaliser en fin de séquence 2 « Exploitation des tableaux ».
TP3 : « Travail sur les graphes » va vous pousser à réaliser un développement modulaire,
sur un sujet mathématique qui sera clairement expliqué.
Ce TP est à réaliser en fin de séquence 3 « Modularité ».
8 2940 TP PA 00
Logiciels nécessaires
Comme pour le cours, vous allez travailler en C++ sous l’IDE Code::Blocks. Lorsque cela
est nécessaire, référez-vous au mémento du C++ qui se trouve à la fin du fascicule de
cours.
Rappels sur la récupération et l’installation de Code::Blocks (vous avez déjà eu toutes les
indications dans le fascicule de cours) :
La version utilisée pour ce module : 10.05
A priori, vous pouvez utiliser une version plus récente si vous en avez l’occasion : il est
cependant possible qu’il y ait quelques petites différences.
Code::Blocks est directement téléchargeable sur le site officiel du logiciel :
http://www.codeblocks.org/
Pensez à prendre la version qui correspond à votre système et, surtout, choisissez la ver-
sion mingw. Voici le nom du fichier qui a été récupéré pour ce cours :
codeblocks-10.05mingw-setup.exe
Une fois le logiciel installé, il est possible de le « franciser » en partie, pour ceux qui ont
du mal avec l’anglais. Toutes les explications concernant l’installation et la configuration
de Code::Blocks et de la version francisée sont données en début de séquence 1, au
moment où vous en avez besoin pour la première fois.
Bon courage !
Conseils généraux
Page 4
8 2940 TP PA 00
TP 1
Initiation à la cryptographie
Vous allez partir à la découverte de la cryptographie à travers un premier
exemple volontairement très simple (par rapport aux algorithmes de cryp-
tages classiques), mais qui va vous permettre de travailler sur les mani-
pulations de chaînes et sur les calculs booléens. Le but de ce TP est aussi
d’exploiter au maximum les possibilités du débogueur.
X Prérequis
Avoir étudié la séquence 1 « Instructions algorithmiques de base » du fascicule
de cours de ce même module.
X Contenu
TP 1
1. Présentation du sujet ....................................................................................... 6
2. Aide ................................................................................................................... 8 Initiation
à la cryptographie
3. Correction algorithmique............................................................................... 11
Page 5
8 2940 TP PA 00
1. Présentation du sujet
Vous devez créer un programme qui permette de crypter un message textuel.
L’objectif est de donner à l’utilisateur la possibilité de saisir un message puis de lui en
afficher la version cryptée. Pour contrôler que tout a bien marché, le message crypté sera
ensuite décrypté et réaffiché.
Principe du cryptage
Voici les étapes à suivre pour crypter le message.
Inversion
Le message va d’abord être coupé en 2 pour inverser le début et la fin.
Par exemple :
message d’origine : BONJOUR
8 2940 TP PA 00
Décalage
Au final, pour obtenir un résultat qui utilise le maximum de caractères alphabétiques, il
va falloir gérer un décalage par rapport à un caractère.
Pour cela, après chaque opération booléenne entre caractères, il suffit d’ajouter un
caractère de décalage, toujours le même.
Utilisez le caractère ‘-’.
Principe du décryptage
Ici, ce sera à vous de trouver par rapport à la démarche utilisée pour le cryptage.
Travail demandé
Vous devez écrire l’algorithme qui permet de saisir un message, d’afficher sa version
cryptée puis de faire l’opération inverse pour afficher la version décryptée.
Traduisez cet algorithme en C++ pour le tester.
Faites plusieurs tests, en particulier avec des messages de longueur paire et de longueur
impaire. Attention, en C++, vous ne pourrez pas saisir d’espace dans votre message,
sinon seul le premier mot sera pris en compte, et ce n’est pas une erreur de votre part !
C’est un principe lié au flux d’entrée que l’on ne va pas détailler ici car cela sort du cadre
du programme. Donc, si vous avez envie de saisir un message assez long, utilisez un
caractère de séparation autre que l’espace (par exemple, l’étoile).
Même si tout fonctionne bien, faites une exécution pas à pas depuis le début pour voir
en particulier l’évolution des variables, le cryptage se faire étape par étape ainsi que
TP 1
le décryptage. Attention, cette étape est très importante : vous allez voir comment se
construisent les chaînes et, surtout, c’est tout à fait le genre de manipulations que l’on Initiation
peut vous demander à l’examen. Effectivement, on peut vous demander de placer des à la cryptographie
points d’arrêt, d’exécuter pas à pas et de montrer l’évolution des variables. Vous devez
aussi spontanément utiliser le débogueur quand vous n’arrivez pas à trouver une erreur : Page 7
le jury attend cette démarche de votre part.
En cas de blocage...
Le but est de chercher le plus possible par vous-même. Vous allez certainement rencon-
trer des difficultés. Aidez-vous au maximum du débogueur pour trouver les erreurs et
voir l’évolution des variables.
Il est tout à fait normal que vous passiez beaucoup de temps, et plus vous consacrerez de
temps à la recherche et à la compréhension des erreurs, plus vous progresserez.
Si vous restez vraiment bloqué, après plusieurs heures de recherche, alors regardez page
suivante, partie "Aide", les indications qui sont données.
Si, malgré ces indications, vous êtes toujours bloqué, suivez la partie "Réalisation étape
par étape".
Enfin, si, malgré les étapes détaillées et l’utilisation du débogueur, vous êtes encore blo-
qué, essayez au moins de traduire l’algorithme en C++ . Vous trouverez la correction de
l’algorithme à la fin de ce TP.
La correction du codage en C++ est en téléchargement, au même endroit que le cours.
8 2940 TP PA 00
2. Aide
Indications
Inversion
Pour inverser le message, il faut commencer par calculer le milieu par rapport à sa lon-
gueur. Ensuite, à l’aide de la fonction d’extraction de chaînes, il suffit de faire une conca-
ténation entre la sous-chaîne qui part du milieu jusqu’à la fin et la sous-chaîne qui part
du début au milieu (évitez de prendre 2 fois le caractère qui est au milieu).
Cryptage
Pour le cryptage, il faut utiliser une autre variable de type chaîne dans laquelle il est
nécessaire de concaténer le résultat du calcul de cryptage.
Le cryptage se fait en réalisant une boucle pour accéder à chaque caractère du message.
Il faux faire un ou exclusif directement entre le kème caractère du message et le kème
caractère de la clé.
Attention, quand on arrive en fin de clé, il faut se repositionner au début. Le modulo
(mod) devrait vous aider à faire ce calcul simplement...
Décalage
Une fois le ou exclusif effectué, il suffit d’ajouter directement le caractère de décalage.
Ce ne sera pas une concaténation de chaîne qui sera effectuée mais une addition entre
codes ASCII. Comment cela est-il possible ? Parce que le caractère de décalage doit être
TP 1
déclaré de type caractère et non de type chaîne. Du coup, en l’ajoutant à un autre carac-
Initiation tère, ce sont les codes qui sont additionnés.
à la cryptographie
Décryptage complet
Page 8 Il suffit de faire exactement les opérations inverses.
Il faut donc non pas commencer par l’inversion mais par le décalage. Cela dit, il est
possible de gérer le décalage et le cryptage en même temps, mais tout de même dans
l’ordre inverse. Donc, pour chaque caractère du message crypté, vous devez commencer
par enlever (et non additionner) le caractère de décalage avant de faire le ou exclusif.
Mais, au fait, pourquoi l’opération inverse d’un ou exclusif est-elle aussi un ou exclusif ?
C’est tout simplement la particularité du ou exclusif. Regardez :
A B C = A oux B C oux B = A
0 0 0 0
0 1 1 0
1 0 1 1
1 1 0 1
Imaginez que A est un des bits du message d’origine et que B est un des bits de la clé.
C contient le résultat du ou exclusif entre A et B, donc C représente le bit une fois crypté.
Si, ensuite, on refait un ou exclusif entre C (le bit crypté) et B (le bit de la clé), on retombe
sur A (le bit du message d’origine) !
Ça ne marche, bien sûr, qu’avec le ou exclusif.
Ce n’est qu’une fois le décryptage réalisé qu’il faudra à nouveau inverser le début et la
fin du message. Attention, suivant que le message contient un nombre pair ou impair
de lettres, vous pouvez avoir des surprises. Il faut donc penser à faire, dans certains cas,
une petite opération sur milieu.
8 2940 TP PA 00
Réalisation étape par étape
Si vous lisez cette partie, c’est que vous êtes vraiment bloqué.
Voici la démarche étape par étape pour réaliser ce programme. Si vous sentez qu’à l’issue
d’une étape vous comprenez mieux et que vous pouvez continuer seul, n’hésitez pas. Le
but est que vous utilisiez cette aide le moins possible.
Le projet
Contrôlez que le programme contient bien un cartouche d’en-tête (n’oubliez pas que ce
sera un des points d’évaluation à l’examen).
Vous avez besoin de 2 includes :
• iostream : qui permet, comme d’habitude, d’utiliser le cin et le cout ;
• string : pour manipuler des chaînes.
Vous devez aussi avoir, comme d’habitude, le namespace std.
Déclarations
3 variables string sont nécessaires : une pour enregistrer le message d’origine, la deu-
xième pour enregistrer la version cryptée et enfin la dernière pour enregistrer la clé.
Vous pouvez d’ailleurs initialiser directement la clé avec "cryptographie" (ou ce que vous
voulez d’autre).
Le calcul du milieu doit être rangé dans une variable de type entier naturel.
Enfin, une variable de type caractère doit être initialisée avec ‘-’. Elle servira pour le
décalage.
TP 1
Saisie du message
Demandez à l’utilisateur de saisir un message qui sera rangé dans la variable adéquate. Initiation
à la cryptographie
Inversion
Commencez par calculer le milieu en divisant par 2 la taille du message et en rangeant Page 9
le résultat dans la variable déclarée à cet effet.
Utilisez la fonction, substr, sur le message pour concaténer la fin (de la position avec
une longueur de taille moins milieu) avec le début (de la position 0 avec une longueur
équivalente à milieu). La taille s’obtient avec la fonction, size, appliquée au message.
Le résultat de la concaténation doit être rangé dans le message d’origine.
Placez un point d’arrêt juste après l’affectation et contrôlez, en déboguant, que la
variable milieu contient bien le milieu de la taille du message et que, dans message, vous
avez bien le message correctement inversé.
Cryptage et décalage
Initialisez la variable qui va contenir le message crypté à une chaîne vide : "". Pour sim-
plifier, on dira par la suite que cette variable s’appelle ‘resultat’.
Faites une boucle ‘pour’ afin de parcourir tous les caractères du message, en partant de 0.
Dans la boucle, affectez à la variable ‘resultat’ la concaténation entre ce qu’elle contient
déjà et l’opération suivante :
faites un ou exclusif binaire (^) entre le kème caractère du message et le kème caractère
de la clé. Attention, pour accéder au kème caractère en récupérant bien un caractère
et non une chaîne de longueur 1 (ce qui est différent en C++), vous devez écrire, par
exemple, message[k]. Une fois le ou exclusif effectué (mettez d’ailleurs l’opération entre
parenthèses), ajoutez avec un simple + le contenu de la variable décalage.
8 2940 TP PA 00
Il y a encore un problème à résoudre : rappelez-vous que la longueur du message n’est
pas forcément identique à la longueur de la clé. Donc, arrivé en fin de clé, il faut revenir
au début. Pour cela, il suffit de mettre en clé non pas juste k, mais le modulo de k par la
taille de la clé. En effet, en prenant le reste de la division de k par la taille de la clé, on
ne peut jamais dépasser la taille, et on revient régulièrement au début.
Mettez un point d’arrêt avant la boucle ‘pour’ et faites une exécution pas à pas en
observant le contenu des variables. Le but est que vous puissiez contrôler l’évolution de
la construction du message crypté.
Affichage du message crypté
Affichez le contenu de la variable resultat.
Décryptage
Le décryptage commence par la fin. Initialisez la variable message à une chaîne vide
puisqu’on va recréer le message.
Refaites la même boucle que tout à l’heure (copier/coller), excepté que, dans la boucle,
la concaténation se fait cette fois dans message et non dans resultat. De plus, il ne faut
pas ajouter décalage à la fin mais l’enlever directement à resultat[k], avant même de
faire le ou exclusif.
Après la boucle, il faut réaliser à nouveau l’inversion. Attention, il y a un petit souci :
dans le cas où la taille du message est impaire, on ne va pas couper au bon endroit. Donc,
avant de couper comme au début, il faut incrémenter milieu de 1.
Comme vous l’avez fait pour le cryptage, faites une exécution pas à pas pour le décryp-
TP 1 tage afin de voir l’évolution des variables.
Initiation Affichage du message décrypté
à la cryptographie
Il ne reste plus qu’à afficher le message.
Page 10 Faites une exécution normale pour voir si tout se passe bien.
3. Correction algorithmique
Voici une proposition d’algorithme attendu. Attention, les noms des fonctions utilisées
pour manipuler les chaînes sont libres. Ici, j’ai utilisé la fonction nommée, extraire, qui a
été vue dans le cours. Cependant, vous pouvez très bien avoir utilisé d’autres noms : le
principal est que ce soit le plus clair possible.
/* programme cryptage (tp1)
* but : permet de crypter un message et de le décrypter
* auteur : Emds
* date : 12/07/2011
*/
programme cryptage
message, resultat : chaine // message d’origine et message crypté
milieu : entier naturel // position du milieu du message
cle : chaîne // clé utilisée pour le cryptage
decalage : caractère // valeur de décalage
k : entier naturel
8 2940 TP PA 00
debut
// initialisations
cle Å "cryptographie"
decalage Å "-"
// saisie du message
afficher "Entrez un message = "
saisir message
8 2940 TP PA 00
TP 2
Inversion de matrice
Vous allez manipuler des tableaux à 2 dimensions pour gérer des calculs
matriciels. Le but opérationnel du TP est de vous montrer comment obte-
nir par programme l’inverse d’une matrice. Le but pédagogique, au-delà
de la manipulation de tableaux, est de vous apprendre à suivre un mode
opératoire précis.
X Prérequis
Avoir étudié la séquence 2 « Exploitation des tableaux » du fascicule de cours
de ce même module.
X Contenu
1. Présentation du sujet ..................................................................................... 14 TP 2
2. Aide ................................................................................................................. 16
Inversion de matrice
3. Correction algorithmique............................................................................... 20
Page 13
8 2940 TP PA 00
1. Présentation du sujet
Vous allez utiliser l’outil informatique pour calculer l’inverse d’une matrice carrée.
Il existe plusieurs approches plus ou moins complexes. Pour réaliser ce programme, vous
allez suivre un mode opératoire précis.
Le but de ce TP, au-delà de la manipulation de matrices et de la présentation d’une
solution de calcul de l’inverse, est de vous faire suivre un mode opératoire précis. Vous
n’avez pas besoin d’avoir de connaissances mathématiques sur le calcul de l’inverse d’une
matrice pour réaliser ce programme. Cela dit, voici un petit rappel :
Mode opératoire
Pour inverser une matrice, on va travailler avec 4 matrices carrées de taille identique
NxN :
1 2 3 1 0 0 x x x x x x
TP 2 2 3 1 0 1 0 x x x x x x
0 1 -1 0 0 1 x x x x x x
Inversion de matrice
mdep mid mtrans minv
Page 14 (matrice de départ) (matrice identité) (matrice de transition) (matrice inversée)
8 2940 TP PA 00
– la case (k, j) de la matrice identité doit recevoir la case (k, j) de la matrice
inversée moins le produit de la case (i, j) de la matrice inversée par la case (k,
i) de la matrice de départ ;
• copier la matrice de transition dans la matrice de départ ;
• copier la matrice identité dans la matrice inversée.
Travail demandé
Vous devez écrire l’algorithme qui permet de saisir une matrice et d’afficher la matrice
inverse. Vous fixerez avec une constante la taille de la matrice (on partira sur une taille
de 3). La matrice identité doit être correctement initialisée.
Attention, les valeurs manipulées sont des réels : en effet, le résultat des calculs peut être
constitué de valeurs réelles même si vous avez saisi des entiers au départ.
Codez votre algorithme en C++ pour le tester.
Vous ferez en sorte de positionner correctement le curseur pour la saisie. Il est judicieux
de placer dans un premier temps des points pour repérer à l’avance où va se faire la
saisie.
L’arrêt du programme (demandé dans le mode opératoire) se fait par un return 0.
Voici quelques exemples de tests que vous allez pouvoir effectuer pour contrôler que
votre programme fonctionne :
2 exemples avec des valeurs entières en résultat :
TP 2
Inversion de matrice
Page 15
8 2940 TP PA 00
Un exemple donnant des réels :
TP 2 En cas de blocage...
Inversion de matrice
Le mode opératoire vous donne la structure précise du programme : suivez-le à la lettre.
Il est tout à fait normal que vous passiez beaucoup de temps, et plus vous consacrerez de
Page 16 temps à la recherche et à la compréhension des erreurs, plus vous progresserez.
Si vous restez vraiment bloqué, après plusieurs heures de recherche, alors regardez page
suivante, partie "Aide", les indications qui sont données.
Si, malgré ces indications, vous êtes toujours bloqué, suivez la partie "Réalisation étape
par étape".
Enfin, si malgré les étapes détaillées et l’utilisation du débogueur, vous êtes encore blo-
qué, essayez au moins de traduire l’algorithme en C++ . Vous trouverez la correction de
l’algorithme à la fin de ce TP.
La correction du codage en C++ est en téléchargement, au même endroit que le cours.
2. Aide
Indications
Pensez à déclarer une constante contenant 3 et que vous utiliserez partout : aussi bien
pour déclarer les tableaux que pour réaliser les boucles.
Déclarations et initialisations
Pensez à déclarer avant le main la constante N à 3.
Vous avez besoin de 4 matrices de taille N x N : prenez les noms donnés dans le sujet, ce
sera plus simple.
8 2940 TP PA 00
La matrice identité doit être initialisée à l’unité. Le plus simple est, dans un premier
temps, de l’initialiser à 0 (en lui affectant ={0] au moment de sa déclaration, toutes les
cases sont à 0). Puis, il faut faire une simple boucle pour parcourir la diagonale et la
remplir de 1.
Affichages et saisies
Les affichages et saisies des matrices doivent obligatoirement se faire avec 2 boucles
imbriquées (pour gérer les lignes et les colonnes). Utilisez le gotoxy (avec myconio.h)
pour positionner correctement le curseur. Le positionnement pour la saisie d’une matrice
a déjà été vu en exercice.
Calcul de la matrice inverse
À chaque fois qu’il faut réaliser une copie complète d’une matrice dans une autre, utili-
sez la fonction memcpy de l’include string.h : vous trouverez le détail de son fonctionne-
ment dans le mémento du C++ qui se trouve à la fin du fascicule de cours.
Suivez bien les indices utilisés dans le mode opératoire : utilisez les mêmes noms, ce sera
plus simple. Il y a donc bien une grande boucle générale sur les colonnes (i) qui contient
d’abord une boucle sur les lignes (j), puis, après cette boucle, elle contient une double
boucle de parcours total (colonnes/lignes) avec les indices k et j. Il est possible de réutili-
ser l’indice j puisque la boucle précédente utilisant le j est terminée. En revanche, il n’est
pas possible d’utiliser l’indice i car on est encore dans la grande boucle.
Affichage final
Il ne reste plus qu’à afficher la matrice inversée, toujours avec une double boucle et un
positionnement correct.
TP 2
En début de main, déclarez en réel (float) les 4 matrices de taille N x N. Voici, pour
exemple, la déclaration de la première matrice :
float mdep[N][N] ;
8 2940 TP PA 00
Initialisation de la matrice identité
Pour la matrice identité, initialisez-la d’abord à 0 au moment de la déclaration :
float mdep[N][N] = {0} ;
8 2940 TP PA 00
• Copier la matrice identité dans la matrice inversée.
Idem.
• Pour chaque colonne k différente de la colonne actuelle i, et pour chaque ligne j,
faire les traitements suivants :
Toujours dans la grande boucle sur le i, faites une nouvelle boucle faisant varier k
de 0 à N -1. Pour éviter la colonne actuelle, placez un test en début de cette boucle
pour contrôler que k est différent de i, puis, dans ce test, faites une nouvelle boucle
qui fait varier j de 0 à N -1.
– La case (k, j) de la matrice de transition doit recevoir la case (k, j) de la matrice
de départ moins le produit de la case (i, j) par la case (k, i) de la matrice de
départ.
C’est à nouveau une opération où toutes les informations ont été détaillées.
Voici la syntaxe :
mtrans[k][j] = mdep[k][j] - mdep[i][j] * mdep[k][i] ;
– La case (k, j) de la matrice identité doit recevoir la case (k, j) de la matrice
inversée moins le produit de la case (i, j) de la matrice inversée par la case (k,
i) de la matrice de départ.
Même principe. Après cette instruction, fermez la boucle sur j, le test et la
boucle sur k.
• Copier la matrice de transition dans la matrice de départ.
Le fonctionnement de la copie entre matrices a été vu plus haut.
• Copier la matrice identité dans la matrice inversée.
TP 2
Idem. Ensuite, fermez la grande boucle sur le i.
Inversion de matrice
Affichage de la matrice inverse
Il ne reste plus qu’à afficher la matrice inverse, sur le même principe que l’affichage des Page 19
points de départ, sauf qu’il faut décaler l’affichage vers le bas : ajoutez, par exemple, 10
au second indice du gotoxy.
8 2940 TP PA 00
3. Correction algorithmique
Voici une proposition d’algorithme attendu :
/* programme matriceInverse (tp 2)
* but : saisie d’une matrice carrée et inversion de la matrice
* auteur : Emds
* date : 12/07/2011
*/
const : N 3
programme matriceInverse
mdep[N, N] : réel ; // matrice de départ à inverser
mtrans[N, N] : réel ; // matrice transitoire pour le calcul
minv[N, N] : réel ; // matrice inversée
mid[N, N] : réel ; // matrice identité
debut
// initialisation à 0 de la matrice identité
pour i de 0 à N-1
pour j de 0 à N-1
mid[i, j] Å 0
finpour
finpour
TP 2
// initialisation de la matrice identité (remplissage des 1 en diagonale)
Inversion de matrice pour i de 0 à N-1
mid[i, i] Å 1
Page 20
finpour
8 2940 TP PA 00
// calculs
mtrans[i, j] Å mdep[i, j] / mdep[i, i]
mid[i, j] Å minv[i, j] / mdep[i, i]
finpour
mdep Å mtrans
minv Å mid
// parcours complet colonnes/lignes excepté la colonne où on se trouve
pour k de 0 à N-1
si k <> i alors
pour j de 0 à N-1
// calculs
mtrans[k, j] Å mdep[k, j] - mdep[i, j] * mdep[k, i]
mid[k][j] Å minv[k, j] - minv[i, j] * mdep[k, i]
finpour
finsi
finpour
mdep Å mtrans
minv Å mid
finpour
fin
Page 21
Normalement, la mention <arrêt du programme> n’est pas permise dans un algo-
rithme, ni d’ailleurs dans un programme. Elle est cependant tolérée en programmation
lorsqu’elle permet de fortement simplifier le code. C’est le cas ici car, en l’absence de
cette ligne, il faudrait gérer un booléen, changer les boucles ‘pour’ en ‘tantque’ pour
prendre en compte ce booléen, et, après la seconde boucle, insérer un grand test pour
éviter de réaliser la suite des traitements suivant la valeur du booléen.
Évitez tout de même ce genre de facilité à l’examen.
8 2940 TP PA 00
TP 3
Travail sur les graphes
Le but de ce TP est de créer une application modulaire. Le sujet porte sur
la manipulation de matrices pour des recherches d’informations sur des
graphes. Les connaissances mathématiques abordées seront expliquées.
X Prérequis
Avoir étudié la séquence 3 « Modularité » du fascicule de cours de ce même
module.
X Contenu
1. Présentation du sujet ..................................................................................... 24
2. Correction algorithmique............................................................................... 29
TP 3
Travail
sur les graphes
Page 23
8 2940 TP PA 00
1. Présentation du sujet
Le but est de réaliser une application qui permette de réaliser des calculs sur les graphes.
Rappels mathématiques
Un graphe fini simple orienté est constitué de nœuds et de liens orientés entre certains
nœuds.
Exemple de représentation graphique :
A B
C D
0 0 0 1
1 1 0 0
1 2 0 0
0 1 0 1
8 2940 TP PA 00
Interprétation :
Il y a un 2 en ligne 3 colonne 2 car il y a 2 chemins de longueur 2 possibles entre le 3e
nœud (C) et le 2e nœud (B). En effet, on peut passer par D ou par A.
Voici la matrice qui donne les chemins de longueur 3 :
1 1 0 0
0 1 0 1
0 1 0 2
1 1 0 1
Interprétation :
Il y a un 2 en ligne 3 colonne 4 car il y a 2 chemins de longueur 3 possibles entre le 3e
nœud (C) et le 4e nœud (D). En effet, on peut faire CàAàBàD ou CàDàBàD.
Multiplication de matrices
Pour obtenir la matrice des chemins de longueur p, il faut élever à la puissance p la
matrice d’adjacence, donc il faut multiplier la matrice par elle-même (p -1) fois.
Comment se fait la multiplication d’une matrice par elle-même ?
Imaginons que R soit la matrice résultat et M la matrice de départ, de taille n x n. Pour
obtenir R = M x M il faut faire le calcul suivant pour chaque élément de R :
n
1 1 0 1
1 1 0 1
1 1 1 1
1 1 0 1
8 2940 TP PA 00
Interprétation :
Il y a un 0 en ligne 1 colonne 3, ce qui signifie qu’il n’y a aucun chemin possible, quelle
que soit la longueur, entre le 1er nœud (A) et le 3e nœud (C). Effectivement, si vous regar-
dez le graphe, il n’y a aucun chemin.
Fonctionnalités de l’application
L’application doit afficher un menu qui permet soit de saisir une matrice d’adjacence en
précisant sa taille, soit de demander l’affichage de la matrice des chemins de longueur p
(après avoir saisi p), soit de demander l’affichage de la matrice de la fermeture transitive.
L’utilisateur, une fois qu’il a saisi une matrice, peut accéder à nouveau à tous les choix :
saisir une autre matrice ou demander, autant de fois qu’il veut, les autres options qui
s’appliqueront toujours sur la dernière matrice saisie.
Travail demandé
Vous devez écrire l’algorithme qui permet de gérer cette application et le traduire en
C++ pour le tester.
Attention, certaines règles sont à respecter :
Affichages
Les affichages attendus doivent être similaires à ceux présentés ici :
Affichage du menu :
TP 3
Travail
sur les graphes
Page 26
Si le choix 1 est demandé, le nombre de nœuds est demandé puis les points sont affichés
pour saisir la matrice :
La saisie se fait ensuite sur les points, puis le menu se réaffiche en dessous :
8 2940 TP PA 00
Dans le cas du choix 2, la longueur est saisie, puis la matrice d’origine est réaffichée avec,
en dessous, la matrice des chemins de la longueur saisie :
Dans le cas du choix 3, il n’y a rien à saisir. La matrice d’origine est réaffichée avec, en
dessous, la matrice de la fermeture transitive : TP 3
Travail
sur les graphes
Page 27
Dans les cas où les choix 2 et 3 sont appelés alors qu'aucune matrice n'a été saisie, un
message doit s'afficher pour signaler le problème et le menu doit être réaffiché.
8 2940 TP PA 00
Les variables
Fixez une taille maximale aux matrices pour pouvoir les déclarer (par exemple 100), que
vous déclarerez en constante.
Vous mettrez en variable globale (donc déclarées avant le main et avant tous les modules)
la matrice d’origine ainsi que le nombre de nœuds. Pourquoi mettre ces variables en glo-
bale ? Parce qu’elles vont être utilisées vraiment partout et que cela aurait fortement
alourdi les modules en ajoutant à chaque fois 2 paramètres supplémentaires. C’est aussi
l’occasion de vous montrer dans quel cas on peut éventuellement se permettre de mettre
en global des variables.
Contrôles de saisie et positionnement
Faites en sorte que l’utilisateur ne puisse pas saisir une information incorrecte. Par
exemple, le nombre de nœuds ne doit pas pouvoir dépasser la taille de votre constante.
Autre exemple, lors de la saisie de la matrice d’adjacence, il ne doit pas être possible de
saisir une autre valeur que 0 ou 1.
Lorsque les saisies sont erronées, en particulier dans la matrice, faites en sorte que le
curseur se repositionne toujours au bon endroit.
Modularité
Voici les signatures des modules que vous devez obligatoirement créer pour votre pro-
gramme, ainsi que leur rôle :
fonction saisieEntierControle (message : chaine, min : entier, max :
entier, x : entier, y : entier) : entier
TP 3
Rôle de la fonction : affiche, à la position (x, y), le message reçu en paramètre et saisit
Travail
une valeur entière qui doit forcément être comprise entre min et max. En cas d’erreur,
sur les graphes
l’affichage toujours à la position (x, y) est refait et la saisie redemandée.
Page 28 procédure afficheMatrice (m[N, N] : entier, taillem : entier, x : entier,
y : entier)
En cas de blocage...
Attention, cette fois, vous n’aurez pas d’aide. Le sujet est volontairement très précis et
l’expérience des TP précédents, s’ils ont été sérieusement faits, ainsi que des exercices de
cours, doit vous permettre d’y arriver.
Ce TP est le plus important car il couvre quasiment tous les domaines de compétences
attendus. Faites-le sérieusement et en passant du temps à tout tester. Arrivé à ce TP, vous
devez être capable, avec tout ce que vous avez appris, de trouver par vous-même les
solutions. Votre recherche personnelle est indispensable.
Vous trouverez tout de même la correction de l’algorithme à la page suivante ainsi que
le code en C++ au téléchargement.
8 2940 TP PA 00
2. Correction algorithmique
Voici une proposition d’algorithme pour chaque module et le programme principal :
Déclarations globales
const : N 100
/* Variables globales */
matrice[N, N] : entier // matrice d’adjacence du graphe
taille : entier // nombre de nœuds du graphe
Fonction saisieEntierControle
/* fonction saisieEntierControle
* but : saisie d’une valeur entière avec contrôle
* entrée : message (chaine) message à afficher avant la saisie
* min, max (entier) bornes limites pour la saisie
* sortie : valeur saisie
*/
fonction saisieEntierControle (message : entier, // message à afficher
min : entier, max : entier, // bornes de la saisie
x : entier, y : entier) // position de la saisie TP 3
: entier
Travail
valeur : entier sur les graphes
debut
repeter Page 29
// positionnement en (x, y)
afficher message
saisir valeur
jusqu’à (valeur>=min et valeur<=max)
retourner valeur
fin
Procédure afficheMatrice
/* procédure afficheMatrice
* but : affichage d’une matrice
*/
procedure afficheMatrice (m[N, N] : entier, taillem : entier, x : entier,
y : entier)
i, j : entier
debut
pour j de 0 à taillem-1
pour i de 0 à taillem-1
// positionnement en (x+i*4+2, y+j*2+4)
afficher m[i, j]
finpour
finpour
fin
8 2940 TP PA 00
Regardez le calcul de positionnement. Excepté ce point, on retrouve la double boucle
classique pour parcourir un tableau à 2 dimensions.
Procédure saisieMatrice
/* procédure saisieMatrice
* but : saisie d’une matrice
*/
procedure saisieMatrice()
i, j : entier
debut
// effacer l’écran
taille Å saisieEntierControle("Nombre de nœuds du graphe = ",
1, 100, 1, 1)
afficher "Saisie de la matrice d’adjacence du graphe (0 ou 1) : "
// affichage des points
pour j de 0 à taille-1
pour i de 0 à taille-1
// positionnement en (i*4+2, j*2+4)
afficher "."
finpour
finpour
// saisie de la matrice
pour j de 0 à taille-1
pour i de 0 à taille-1
TP 3
matrice[i][j] Å saisieEntierControle("", 0, 1, i*4+2, j*2+4)
Travail finpour
sur les graphes finpour
fin
Page 30
Encore un petit commentaire pour signaler à quel endroit effacer l’écran. Cette ligne
n’est pas obligatoire.
Vous remarquez l’appel de saisieEntierControle, bien pratique pour saisir avec position-
nement et contrôle. Cela simplifie le contenu de la double boucle.
Procédure longueurs
/* procédure longueurs
* but : calcul de la matrice des chemins de longueur p
*/
procédure longueurs()
p : entier // longueur du chemin
puissance[N, N], transposition[N, N] : entier
i, j, k, m : entier // indices
debut
// effacer l’écran
// contrôle si une matrice a été saisie
si taille=0 alors
afficher "Vous devez d’abord saisir une matrice d’adjacence..."
sinon
// saisie de la longueur
p Å saisieEntierControle("Longueur du chemin = ", 1, taille, 1, 1)
// copie de la matrice d’origine dans une matrice de transition
8 2940 TP PA 00
transition Å matrice
// calcul de la puissance
pour k de 1 à p-1
// la matrice est élevée au carré
pour j de 0 à taille-1
pour i de 0 à taille-1
puissance[i][j] Å 0
pour m de 0 à taille-1
puissance[i,j] Å puissance[i,j] + transition[i,m]*matrice[m,j]
finpour
finpour
finpour
// transfert de la matrice pour passer à la puissance suivante
transition Å puissance
finpour
8 2940 TP PA 00
// affichage des 2 matrices
afficheMatrice(matrice, taille, 1, 1)
afficheMatrice(fermtrans, taille, 1, taille*2 + 4)
finsi
fin
L’intérêt de cet algo se situe dans la partie de Warshall. Aviez-vous trouvé l’opération ? Si
ce n’est pas le cas, prenez le temps de comprendre. Rappelez-vous qu’un 0 est considéré
comme FAUX et 1 comme VRAI en valeurs booléennes.
Programme principal
/* programme graphes (tp 3)
* but : calcul des chemins de longueur p et de la fermeture transitive d’un
graphe
* auteur : Emds
* date : 12/07/2011
*/
programme graphes
choix : caractère // mémorisation du choix de l’utilisateur
debut
// initialisation
TP 3 taille Å 0 // nombre de nœuds initialisés à 0
choix Å "Z" // pour rentrer dans la boucle
Travail
sur les graphes
// boucle sur le menu général
tantque choix <> "Q" et choix <> "q"
Page 32
8 2940 TP PA 00
finsi
finsi
fintantque
fin
Le programme principal est, au final, très court : les différentes options sont traitées dans
des procédures.
TP 3
Travail
sur les graphes
Page 33
8 2940 TP PA 00