Vous êtes sur la page 1sur 33

BTS Services informatiques aux organisations – 1re année

ALGORITHMIQUE APPLIQUÉE
TRAVAUX PRATIQUES

BTS Services informatiques aux organisations – 1re année

Élisabeth Martins Da Silva

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

CONNECTÉ À VOTRE AVENIR

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 Capacités attendues en fin de séquence


Avoir compris la démarche à suivre face à l’étude d’un sujet et avoir acquis les
bons réflexes en ce qui concerne l’utilisation du débogueur.

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

après inversion : JOURBON


Cryptage avec opération booléenne et clé
L’étape suivante consiste à changer chaque caractère du message en le combinant avec
un des caractères d’une clé qui sera fixée dans le programme.
La clé est une chaîne qui doit contenir un mot assez long (dans la correction, j’ai utilisé
le mot "cryptographie").
TP 1 La combinaison se fait en réalisant une opération booléenne bit à bit entre le caractère
récupéré à la kème position du message et le caractère récupéré à la kème position de
Initiation
à la cryptographie
la clé.
L’opération à exécuter est un ou exclusif, qui fonctionne donc ainsi :
Page 6 A B A oux B
0 0 0
0 1 1
1 0 1
1 1 0
Remarque spécifique au C++ :
Pour récupérer à chaque fois un seul caractère, vous serez obligé non pas d’utiliser la
fonction substr qui retourne forcément un type string, même s’il est de longueur 1, mais
de gérer la chaîne comme un tableau de caractères. La chaîne peut très bien (et doit)
être déclarée en string, mais ensuite, pour récupérer le kème caractère, vous écrirez
maChaine[k].
Rappel :
Chaque caractère est en réalité codé : il contient donc une valeur numérique qui est
le code ascii du caractère et qui est ensuite interprété au moment de l’affichage pour
apparaître sous forme de lettre.

Attention, la longueur du message ne correspond pas forcément à la longueur de la clé.


Si le message est plus long que la clé, il faudra penser à revenir au début de la clé quand
vous aurez atteint la fin.
kljglfgkjùlkpoejkglknmhkjùmkqrzporghkhlkkjhg
cryptographiecryptographiecryptographiecrypt

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

//--- cryptage du message ---


// inversion entre le début et la fin (le message est coupé en 2)
milieu Å taille(message) div 2
message Å extraire(message, milieu, taille(message)-milieu)
+ extraire(message, 0, milieu)
// oux entre chaque lettre du message et une des lettres de la clé
resultat Å ""
pour k de 0 à taille(message)-1
resultat Å resultat+(message[k] oux cle[k mod taille(cle)])+decalage
finpour

// affichage du message crypté


afficher "crypté = ", resultat

//--- opérations inverses (décryptage) ---


// à nouveau oux permet de revenir à la valeur d’origine TP 1
message Å ""
Initiation
pour k de 0 à taille(resultat)-1 à la cryptographie
message Å message+((resultat[k]-decalage) oux cle[k mod taille(cle)])
finpour Page 11
// attention, le milieu est décalé si la longueur du message est impaire
si taille(message) mod 2 <> 0 alors
milieu Å milieu + 1
finsi
message Å extraire
message Å extraire(message, milieu, taille(message)-milieu)
+ extraire(message, 0, milieu)

// affichage du message décrypté


afficher "message d’origine = ", message
fin
Les commentaires sont là aussi pour vous aider à comprendre l’algorithme.

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 Capacités attendues en fin de séquence


Mieux connaître les manipulations sur les tableaux à 2 dimensions, en particu-
lier à travers les doubles boucles imbriquées. Savoir suivre un mode opératoire.

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 :

Rappel mathématique sur les matrices inverses


Une matrice A de taille n x n est inversible si et seulement si il existe une matrice B de
taille n x n telle que :
AB = BA = I (matrice identité)
I est aussi, dans ce cas, de taille n x n. Une matrice identité est une matrice remplie de 0
sauf sa première diagonale qui est à 1.
B est alors noté A-1."

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)

Voici le mode opératoire pour l’inversion


• Copier la matrice de départ dans la matrice de transition.
• Copier la matrice identité dans la matrice inversée.
• Pour chaque colonne i, faire les traitements suivants :
• pour chaque ligne j faire les traitements suivants :
– si la case (i, j) de la matrice de départ se trouve sur la diagonale et qu’elle est
nulle, l’inversion est impossible, il faut arrêter le programme,
– la case (i, j) de la matrice de transition doit recevoir la case (i, j) de la matrice
de départ divisée par la case (i, i) de la matrice de départ,
– la case (i, j) de la matrice identité doit recevoir la case (i, j) de la matrice inver-
sée divisée par la case (i, 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 ;
• pour chaque colonne k différente de la colonne actuelle i, et pour chaque ligne j,
faire les traitements suivants :
– 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,

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 :

Un exemple d’inversion impossible :

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

Réalisation étape par étape Inversion de matrice


Si vous lisez cette partie, c’est que vous êtes vraiment bloqué.
Le mode opératoire est orienté C++ car la plupart des difficultés que vous pouvez ren- Page 17
contrer risquent d’être au niveau du langage.
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
Commencer par un cartouche en début de fichier.
Les includes nécessaires pour ce projet sont :
• iostream : pour les entrées/sorties (cout et cin) ;
• myconio.h : pour gérer les positionnements d’affichage avec gotoxy ;
• string.h : pour gérer la copie en une ligne d’une matrice dans une autre matrice.
Déclarations
Avant le début du main, déclarez la constante :
#define N 3

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} ;

Ensuite, faites une simple boucle de 0 à N -1 pour initialiser la première diagonale à 1.


Chaque élément de la diagonale a forcément le même indice de ligne et de colonne.
Voilà pourquoi une simple boucle suffit : vous allez utiliser le même indice pour la ligne
et la colonne.
Affichage des points pour la saisie
Ce point a déjà été abordé dans l’exercice 3 de la séquence 2 du fascicule de cours.
Regardez la correction. Il suffit de faire une double boucle et d’utiliser les indices de
boucle pour positionner le curseur avec gotoxy.
Saisie de la matrice d’origine
Même remarque : la saisie avec un positionnement correct a été vue dans le même exer-
cice. Là encore, il faut une double boucle.
Calcul de la matrice inverse
Reprenons le mode opératoire donné dans le sujet :
• Copier la matrice de départ dans la matrice de transition
Utilisez memcpy pour faire cette copie en une ligne. Voici la syntaxe (qui est aussi
expliquée dans le mémento du C++, à la fin du fascicule de cours) :
memcpy(mtrans, mdep, sizeof mdep) ;
TP 2
• Copier la matrice identité dans la matrice inversée
Inversion de matrice Même principe, mais avec d’autres matrices.
• Pour chaque colonne i, faire les traitements suivants :
Page 18
Faites une boucle faisant varier i de 0 à N -1.
• Pour chaque ligne j, faire les traitements suivants :
Faites une boucle faisant varier j de 0 à N -1.
– Si la case (i, j) de la matrice de départ se trouve sur la diagonale et qu’elle est
nulle, l’inversion est impossible, il faut arrêter le programme.
Rappelez-vous qu’une case est sur la diagonale si son indice de ligne est le
même que l’indice de colonne : vérifiez donc seulement si la case d’indice (i, i)
est égale à 0. Si c’est le cas, affichez un message puis faites directement return
0 pour arrêter le programme. Fermez le test.
– La case (i, j) de la matrice de transition doit recevoir la case (i, j) de la matrice
de départ divisée par la case (i, i) de la matrice de départ.
Vous bloquez sur cette ligne ?... alors voici la syntaxe :
mtrans[i][j] = mdep[i][j] / mdep[i][i] ;

Attention, vous êtes toujours dans la boucle sur le j.


– La case (i, j) de la matrice identité doit recevoir la case (i, j) de la matrice inver-
sée divisée par la case (i, i) de la matrice de départ.
Même principe que la ligne précédente. Vous êtes toujours dans la boucle sur j.
Pensez ici à fermer la boucle sur le j.
• Copier la matrice de transition dans la matrice de départ.
La syntaxe a déjà été vue plus haut.

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

// saisie de la matrice NxN


pour i de 0 à N-1
pour j de 0 à N-1
saisir mdep[i, j]
finpour
finpour

//--- calcul de la matrice inverse ---


mtrans Å mdep
minv Å mid
// parcours des colonnes
pour i de 0 à N-1
// parcours des lignes de la colonne
pour j de 0 à N-1
// si on trouve un 0 sur la diagonale, inversion impossible
si mdep[i, i] = 0 alors
afficher "inversion impossible"
<arrêt du programme>
finsi

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

// affichage de la matrice inverse


pour i de 0 à N-1
pour j de 0 à N-1
afficher minv[i, j]
finpour TP 2
finpour
Inversion de matrice

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 Capacités attendues en fin de séquence


Avoir compris comment développer une application en la décomposant en plu-
sieurs modules. Savoir créer des outils réutilisables.

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

Ce graphe comporte 4 nœuds.


Matrice d’adjacence
La matrice d’adjacence présente dans une matrice tous les liens orientés entre les nœuds.
TP 3
C’est une matrice carrée et la position (i, j) est à 1 s’il y a un chemin direct de i vers j, elle
est à 0 s’il n’y a pas de chemin.
Travail Dans cet exemple, voici la matrice d’adjacence :
sur les graphes
0 1 0 0
Page 24
0 0 0 1
1 0 0 1
1 1 0 0
Interprétation :
Il y a un 1 à la ligne 1 colonne 2 car il y a un chemin qui va du 1er nœud (A) vers le 2e
nœud (B). Par contre, il y a un 0 à la ligne 2 colonne 1 car il n'y a pas de chemin qui aille
du 2e nœud (B) vers le 1er nœud (A).
Chemins de longueur p
La matrice d’adjacence ne donne que les chemins directs. En regardant l’exemple, on voit
qu’il y a possibilité d’aller de A à D en passant par B. Mais, pour cela, il faut emprunter
2 liens, donc un chemin de longueur 2. Pour obtenir la matrice qui permet de connaître
les chemins de longueur p possibles, il suffit d’élever la matrice d’adjacence à la puis-
sance p, donc la multiplier par elle-même (p -1) fois.
En gardant l’exemple précédent, voici la matrice qui donne les chemins de longueur 2 :

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

R(i, j) = Y M(i, k) * M(k, j)


k=1
TP 3
Donc, par exemple pour une matrice 4 x 4, cela donnerait (pour ceux qui ont du mal avec
Travail
le signe Y) : sur les graphes
R(i, j) = M(i, 1)*M(1, j) + M(i, 2)*M(2, j) + M(i, 3)*M(3, j) + M(i, 4)*M(4, j)
Page 25
Fermeture transitive
La matrice de la fermeture transitive permet de savoir, pour chaque nœud du graphe, les
nœuds auxquels il peut avoir accès quelle que soit la longueur du chemin.
Pour trouver la fermeture transitive, on commence par récupérer la matrice d’adjacence.
Puis il faut mettre la première grande diagonale à 1. Ensuite, on utilise la constatation de
Warshall : "S’il existe un moyen d’aller du nœud x vers le nœud y ET un moyen d’aller du
nœud y vers le nœud z, alors il existe un moyen d’aller du nœud x vers le nœud z." S’il
y avait déjà un 1 dans la case, il ne faut pas le perdre, donc le résultat du ET précédent
doit être combiné avec un OU avec le contenu actuel de la case.
Vous allez certainement passer du temps à trouver l’algorithme de cette partie. Vous
pourrez contrôler si vous avez le bon algo si vous obtenez le résultat suivant.
Pour l’exemple précédent, on obtient la matrice de fermeture transitive suivante :

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)

Rôle de la procédure : en se positionnant en (x, y), affiche la matrice passée en para-


mètre, en affichant les valeurs toutes les 4 colonnes et toutes les 2 lignes.
Pourquoi taillem est-il en paramètre alors que la taille (nombre de nœud) est en variable
globale ? Pour rendre cette procédure réutilisable. Lors de l’appel de cette procédure, ce
n’est pas choquant d’envoyer en paramètre une variable globale (c’était l’occasion aussi
de vous montrer cet aspect).
En dehors de ces 2 modules obligatoires, à vous de faire en sorte qu’il y ait le moins
de codes possible dans le programme principal et que les différentes options du menu
soient traitées dans des modules différents.

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

La constante sert à déclarer le tableau et va servir à déclarer les autres tableaux. En


revanche, elle ne sera pas utilisée dans les boucles car elle ne représente pas la taille
réelle (le nombre de nœuds) : les matrices ne sont pas complètement remplies.

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

Vous remarquez que le positionnement est mis en commentaire car, normalement, il


n’intervient pas en algorithmique mais juste dans le code. Comme, ici, on reçoit des
paramètres qui sont directement liés au positionnement, alors l’information est précisée.

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

// affichage des 2 matrices


afficheMatrice(matrice, taille, 1, 1)
afficheMatrice(puissance, taille, 1, taille*2 + 4)
finsi
fin
Le point intéressant se situe au niveau du calcul de la matrice élevée à la puissance. Une
matrice de transition est nécessaire.
TP 3
Procédure fermeture
Travail
/* procédure fermeture sur les graphes
* but : calcul de la matrice de la fermeture transitive
*/ Page 31
procédure fermeture()
fermtrans[N, N] : entier
i, j, k : entier
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
// copie de la matrice d’origine dans une de fermeture transitive
fermtrans Å matrice
// algorithme de warshall
pour i de 0 à taille-1
fermtrans[i, i] Å 1
finpour
pour k de 0 à taille-1
pour i de 0 à taille-1
pour j de 0 à taille-1
fermtrans[i,j] Å fermtrans[i,j] ou
(fermtrans[i,k] et fermtrans[k,j])
finpour
finpour
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

// affichage du menu et saisie du choix


afficher "Saisie d’une nouvelle matrice ............... 1"
afficher "Matrice des chemins de longueur p ........... 2"
afficher "Fermeture transitive ........................ 3"
afficher "Quitter ..................................... Q"
afficher "Choix : "
saisir choix

// traitement des différents choix


si choix="1" alors
saisieMatrice()
sinon
si choix="2" alors
longueurs()
sinon
si choix="3" alors
fermeture()
finsi

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

Vous aimerez peut-être aussi