Top Banner
26/12/2016 Encadré par :Mr Tragha Mini-projet en algorithmique et complexité réalisé par : Guebba sara Fagroud fatimaezzahra Fagroud fati Par la Pratique On aPPrend l’infOrmatique
29

Rapport Projet Module Complexité

Jan 21, 2018

Download

Education

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Rapport Projet Module Complexité

26/12/2016 Encadré par :Mr Tragha

Mini-projet en algorithmique et

complexité

réalisé par : Guebba sara Fagroud fatimaezzahra

Fagroud fati

Par la Pratique On aPPrend l’infOrmatique

Page 2: Rapport Projet Module Complexité

Rapport Mini-projet

Page 1

I. DEFINITION D’UN ALGORITHME : Un algorithme est une suite finie et non-ambiguë d’opérations ou d'instructions permettant de

résoudre un problème.

Le mot algorithme vient du nom latinisé du mathématicien persan Al-Khawarizmi, surnommé « le

père de l'algèbre ». Le domaine qui étudie les algorithmes est appelé l'algorithmique. On retrouve

aujourd'hui des algorithmes dans de nombreuses applications telles que la cryptographie, le routage

d'informations, la planification et l'optimisation de ressources, la bio-informatique, ...

1-1)Dans quel cas on dit q’un algorithme est correct ?

Un algorithme est correct lorsque pour chaque instance, il se termine en produisant la bonne sortie,

c'est-à-dire qu'il résout le problème posé. On mesure l'efficacité d'un algorithme notamment par sa

durée pour produire le résultat attendu et par sa consommation de mémoire RAM (en partant du

principe que chaque instruction a un temps d'exécution constant). Les ordinateurs sur lesquels

tournent ces algorithmes ne sont pas infiniment rapides : le temps de machine reste une ressource

limitée malgré une augmentation des performances considérable des machines. Un algorithme sera

donc dit performant s'il utilise avec parcimonie les ressources dont il dispose, c'est-à-dire le temps

CPU et la mémoire RAM.

1-2) la notion de complexité :

La complexité d’un problème mathématique P est une mesure de la quantité de ressources

nécessaires à la résolution du problème P.

L'efficacité d'un algorithme peut être évalué en temps et en espace :

complexité en temps : évaluation du temps d'exécution de l'algorithme complexité en espace : évaluation de l'espace mémoire occupé par l'exécution de l'algorithme

Remarque :

Dans ce rapport, on s’intéresse à la complexité temporelle

Page 3: Rapport Projet Module Complexité

Rapport Mini-projet

Page 2

On considère, désormais un algorithme dont le temps maximal d’exécution pour une donnée de taille

n en entrée est noté T(n).

Chercher la complexité au pire, dans la situation la plus défavorable, c’est exactement exprimer T(n)

en général en notation « O ».

Voici un dessin des courbes de chacune des complexités pour voir la plus rapide entre eux

Page 4: Rapport Projet Module Complexité

Rapport Mini-projet

Page 3

II. TABLEAU, LISTE CHAINEE

2-1)C’est quoi un tableau :

Les tableaux sont des ensembles de variables du même type stockées côte à côte en

mémoire.

La taille d'un tableau doit être déterminée avant la compilation, elle ne peut pas dépendre

d'une variable.

Chaque case d'un tableau de type int contient une variable de type int.

Les cases sont numérotées via des indices commençant à 0

: tableau[0], tableau[1],tableau[2], etc.

2-2) C’est quoi une liste chainée ?

Une liste est une structure de données fondamentale en programmation : elle permet de

représenter une suite d'éléments, et de les manipuler très naturellement.

Cette structure est très adaptée à certains algorithmes de tri, entre autres le tri par insertion

2-3)La différence entre tableau et liste chainée :

L’accès à un élément de liste chainé ne se fait pas par index mais à l’aide d’un pointeur.

L’allocation de la mémoire par la liste chainée est faite au moment de l’exécution.

Pour insérer un élément dans un tableau il aurait fallu déplacer plusieurs éléments mais da

une liste chainée, seulement deux pointeurs sont affectés pour insérer l’élément.

Le tableau a une seule adresse, pour la liste chainée chaque cellule a son adresse.

Page 5: Rapport Projet Module Complexité

Rapport Mini-projet

Page 4

III. LES FICHIERS

3-1) C’est quoi un fichier ?

Un fichier est un ensemble d’information stockées sur une mémoire de masse(disque dur ,clé

..)

Les informations contenues dans le fichier ne sont pas forcément de même type(un char , un

int ,une structure)

3-2)Manipulation des fichiers

3-2-1 déclaration

FILE *fichier ; majuscule obligatoire par FILE

3-2-2 Ouverture

FILE* fopen(const char* nomDuFichier, const char* modeOuverture);

Les modes d’ouvertures :

"r" : lecture seule. Vous pourrez lire le contenu du fichier, mais pas y écrire. Le fichier doit avoir été créé

au préalable.

"w" : écriture seule. Vous pourrez écrire dans le fichier, mais pas lire son contenu. Si le fichier n'existe pas,

il sera créé.

"a" : mode d'ajout. Vous écrirez dans le fichier, en partant de la fin du fichier. Vous ajouterez donc du

texte à la fin du fichier. Si le fichier n'existe pas, il sera créé.

"r+" : lecture et écriture. Vous pourrez lire et écrire dans le fichier. Le fichier doit avoir été créé au

préalable.

"w+" : lecture et écriture, avec suppression du contenu au préalable. Le fichier est donc d'abord vidé de

son contenu, vous pouvez y écrire, et le lire ensuite. Si le fichier n'existe pas, il sera créé.

"a+" : ajout en lecture / écriture à la fin. Vous écrivez et lisez du texte à partir de la fin du fichier.Si le

fichier n'existe pas, il sera créé.

3-3-3 Fermeture

int fclose(FILE* pointeurSurFichier);

3-3-4 Lecture à partir d’un fichier

fgetc : lit un caractère .

int fgetc(FILE* pointeurDeFichier)

fgets : lit une chaîne .

char* fgets(char* chaine, int nbreDeCaracteresALire, FILE* pointeurSurFichier);

fscanf : lit une chaîne formatée.

Page 6: Rapport Projet Module Complexité

Rapport Mini-projet

Page 5

fscanf(fichier, typede char", &char)

3-3-5 Ecriture dans le fichier

fputc : écrit un caractère dans le fichier (UN SEUL caractère à la fois) ;

int fputc(int caractere, FILE* pointeurSurFichier);

fputs : écrit une chaîne dans le fichier ;

char* fputs(const char* chaine, FILE* pointeurSurFichier);

fprintf : écrit une chaîne « formatée » dans le fichier, fonctionnement quasi-identique

àprintf.

IV. QUELQUES EXEMPLES DE TRI

4-1) Tri à par inser tion

Dans l'algorithme, on parcourt le tableau à trier du début à la fin. Au moment où on considère le i-

ème élément, les éléments qui le précèdent sont déjà triés. Pour faire l'analogie avec l'exemple du

jeu de cartes, lorsqu'on est à la i-ème étape du parcours, le i-ème élément est la carte saisie, les

éléments précédents sont la main triée et les éléments suivants correspondent aux cartes encore

mélangées sur la table.

L'objectif d'une étape est d'insérer le i-ème élément à sa place parmi ceux qui précèdent. Il faut

pour cela trouver où l'élément doit être inséré en le comparant aux autres, puis décaler les

éléments afin de pouvoir effectuer l'insertion. En pratique, ces deux actions sont fréquemment

effectuées en une passe, qui consiste à faire « remonter » l'élément au fur et à mesure jusqu'à

rencontrer un élément plus petit.

procédure tri_insertion(tableau T, entier n)

pour i de 1 à n - 1

# mémoriser la valeur de T[i]

x ← T[i]

# déplacer d'un cran vers la droite les éléments de T[0]..T[i-1]

qui sont plus grands que lui

j ← i

tant que j > 0 et T[j - 1] > x

T[j] ← T[j - 1]

j ← j - 1

fin tant que

# et mettre la valeur dans le "trou" que ça a laissé

T[j] ← x

fin pour

Page 7: Rapport Projet Module Complexité

Rapport Mini-projet

Page 6

fin procédure

4-2) Tri à par selection

Sur un tableau de n éléments (numérotés de 1 à n), le principe du tri par sélection est le

suivant :

rechercher le plus petit élément du tableau, et l'échanger avec l'élément d'indice 1 ;

rechercher le second plus petit élément du tableau, et l'échanger avec l'élément d'indice 2 ;

continuer de cette façon jusqu'à ce que le tableau soit entièrement trié.

procédure tri_selection(tableau t, entier n)

pour i de 1 à n - 1

min ← i

pour j de i + 1 à n

si t[j] < t[min], alors min ← j

fin pour

si min ≠ i, alors échanger t[i] et t[min]

fin pour

fin procédure

4-3 Tri par bulle :

Le tri à bulles ou tri par propagation est un algorithme de tri. Il consiste à comparer répétitivement

les éléments consécutifs d'un tableau, et à les permuter lorsqu'ils sont mal triés. Il doit son nom au

fait qu'il déplace rapidement les plus grands éléments en fin de tableau, comme des bulles d'air qui

remonteraient rapidement à la surface d'un liquide.

tri_à_bulles(Tableau T)

pour i allant de taille de T - 1 à 1

pour j allant de 0 à i - 1

si T[j+1] < T[j]

échanger(T[j+1], T[j])

V. OUTILS ET ENVIRONNEMENTS DE DEVELOPPEMENT

5-1) le langage C

Page 8: Rapport Projet Module Complexité

Rapport Mini-projet

Page 7

C est un langage de programmation impératif et généraliste. Inventé au début des années 1970 pour

réécrire UNIX, C est devenu un des langages les plus utilisés. De nombreux langages plus modernes

comme C++, Java et PHP reprennent des aspects de C.

Le langage C reste un des langages les plus utilisés actuellement. Cela est dû au fait que le langage C

est un langage qui comporte des instructions et des structures de haut niveau (contrairement à

l'assembleur par exemple) tout en générant un code très rapide grâce à un compilateur très

performant.

5-2) le codeblocks

est un environnement de développement intégré libre et multiplateforme. Il est écrit en C++ grâce à

la bibliothèque wxWidgets. CodeBlocks est orienté C et C++, mais il supporte d'autres langages

comme FORTRAN ou le D.

CodeBlocks est développé pour Linux, Windows et Mac OS X. Des utilisateurs indiquent avoir

réussi à compiler le code source sous FreeBSD [réf. nécessaire]3.

CodeBlocks est simple, voire intuitif, d'utilisation pour un programmeur. Il se révèle t outefois

fort complet dès qu'on en explore un peu les options.

Son architecture de plug-ins permet de l'étendre et de le personnaliser, tout en n'y incluant

que ce que l'on souhaite utiliser. La plupart étant inclus dans l'archive et l'installeur, il n'est

de ce fait pas nécessaire de les installer un à un.

Page 9: Rapport Projet Module Complexité

Rapport Mini-projet

Page 8

VI. ETUDE THEORIQUE :

6-1) Complexité tri par inser tion :

Le tri effectue n-1 insertions. A la i ème itération, dans le pire des cas, l’algorithme effectue i-

1 recopies. Le coût du tri est donc : O(n²).

Dans le meilleur des cas le tri par insertion requiert seulement O(n) traitements. C’est le cas

lorsque l’élément à insérer reste à sa place, donc quand la suite est déjà triée. On peut

montrer que le tri par insertion est quadratique en moyenne

6-2) Complexité tri à bulles

Dans le pire des cas, la complexité du tri à bulles est aussi en O(n²). Le pire des cas est, pour

ce tri, une liste triée en sens inverse.

Le meilleur des cas est une liste triée. Si l'algorithme est confronté à ce cas, sa complexité

s'améliore en O(n), ce qui signifie qu'il ne fait que n comparaisons pour n valeurs à trier (en

réalité, pour des raisons d'intervalles, il n'en fait que n-1).

VII. ETUDE PRATIQUE :

Listes chainés

Fonction calculant la longueur de la liste :

Fonction recherche d’un élément :

int lengthList(llist L)

{

int n=0;

llist p=L;

while(p!=NULL)

{

n++;

p=p->nxt;

}

return n;

}

int rechercherElement(llist liste, char *valeur)

{

simple *tmp=liste;

int i=0;

Page 10: Rapport Projet Module Complexité

Rapport Mini-projet

Page 9

Fonction tri à bulles :

Fonction tri par insertion :

llist Tribulles(llist L)

{int taille=sizeof(char*);

llist Temp=(llist)malloc(taille);

llist temp=L,temp2;

int i,j;

int n=lengthList(L);

for(i=0;i<n-1;i++){

temp=L;temp2=temp->nxt;

while(temp2!=NULL) {

if(strcmp(temp2->val,temp->val)<0)

{ Temp->val=temp->val;

temp->val=temp2->val;

temp2->val=Temp->val;}

temp=temp->nxt;temp2=temp2->nxt; }

} }

void trier(llist l){

llist temp, temp1, temp2;

temp=temp1=temp2=NULL;

char *min;

min=malloc(Ma*sizeof(char));

Page 11: Rapport Projet Module Complexité

Rapport Mini-projet

Page 10

Fonction ajout en fin d’une liste:

llist ajouterEnFin(llist liste, char *valeur)

{ simple* nouvelElement = malloc(sizeof(simple));

/* On assigne la valeur au nouvel élément */

nouvelElement->val = valeur;

/* On ajoute en fin, donc aucun élément ne va suivre */

nouvelElement->nxt = NULL;

Page 12: Rapport Projet Module Complexité

Rapport Mini-projet

Page 11

Page 13: Rapport Projet Module Complexité

Rapport Mini-projet

Page 12

Fonction main:

int main()

{

float temps;

clock_t debut, fin;

char a[50];

llist liste=NULL;

FILE *fich;

char *C=malloc(sizeof(C));

char* v=NULL;

fich=fopen("exemple.txt","r");/*ouverture de notre fichier*/

if(fich!=NULL){

while(!feof(fich) ){

fscanf(fich,"%s",C);

v=malloc(strlen(C)+1); /*on alloue de la mémoire notre chaine +1*/

strcpy(v,C);

liste = ajouterEnFin(liste, v);/*on remplie la chaine*/

}

}

fclose(fich);

int choixMenu;/*menu*/

printf("---Menu---\n\n");

printf("1.afficher votre liste!\n");

printf("2.chercher un element!\n");

printf("3.Trier la liste (tri par insertion)!\n");

printf("4.Trier la liste (tri à bulles)!\n");

printf("\nVotre choix?\n\n");

scanf("%d", &choixMenu);

Page 14: Rapport Projet Module Complexité

Rapport Mini-projet

Page 13

int S;

switch(choixMenu)

{case 1:

debut = clock();

afficherListe(liste);

printf("\n\n");

fin= clock();

temps = (float)(fin-debut)/CLOCKS_PER_SEC;

printf("\ntemps = %f\n", temps);

printf("vous voulez continuer taper 1 pour continuer et 0 pour exit");

scanf("%d",&S);

switch (S)

{ case 1:

main();

break;

case 0:

break;}

break;

case 2:

debut = clock();

printf("donner l'element à chercher");

scanf("%s",&a);

int p=Recherche(liste,a);

printf("la valeur cherchée est trouve %d\n\n",p);

fin= clock();

temps = (float)(fin-debut)/CLOCKS_PER_SEC;

printf("\ntemps = %f\n", temps);

printf("vous voulez continuer taper 1 pour continuer et 0 pour exit");

scanf("%d",&S);

Page 15: Rapport Projet Module Complexité

Rapport Mini-projet

Page 14

switch (S)

{ case 1:

main();

break;

case 0:

return 0;

}

main();

break;

case 3:

debut = clock();

trier(liste);

afficherListe(liste);

fin= clock();

temps = (float)(fin-debut)/CLOCKS_PER_SEC;

printf("\ntemps = %f\n", temps);

printf("vous voulez continuer taper 1 pour continuer et 0 pour exit");

scanf("%d",&S);

switch (S)

{ case 1:

main();

break;

case 0:

return 0;

}

break;

Page 16: Rapport Projet Module Complexité

Rapport Mini-projet

Page 15

case 4:

debut = clock();

Tribulles(liste);

afficherListe(liste);

fin= clock();

temps = (float)(fin-debut)/CLOCKS_PER_SEC;

printf("\ntemps = %f\n", temps);

printf("vous voulez continuer taper 1 pour continuer et 0 pour exit");

scanf("%d",&S);

switch (S)

{ case 1:

main();

break;

case 0:

return 0;

}

break;

default:

printf("Ce choix n'existe pas dans notre menu !");

break;

}

system("PAUSE");

return 0;

}

Page 17: Rapport Projet Module Complexité

Rapport Mini-projet

Page 16

Si on choisit 1 :

Si on choisit 2 :

Si on choisit 3:

Page 18: Rapport Projet Module Complexité

Rapport Mini-projet

Page 17

Si on choisit 4:

Page 19: Rapport Projet Module Complexité

Rapport Mini-projet

Page 18

Tableaux

Fonction recherche d’un élément :

Fonction tri à bulles :

int recherche(char tab[max][Ma],char val[10])

{

int i,a;

for(i=0;i<max;i++)

{

if(strcmp(val,tab[i])==0)

{

a=i;

break;

}

}

return a; }

void tribulles(char t[max][Ma],int n)

{

int i,j;

char cle[30];

for(i=0;i<n;i++)

{

for(j=n-1;j>=i+1;--j)

{

if(strcmp(t[j-1],t[j])<0)

{

strcpy(cle,t[j-1]);

strcpy(t[j-1],t[j]);

strcpy(t[j],cle);

}

}

Page 20: Rapport Projet Module Complexité

Rapport Mini-projet

Page 19

Fonction tri par insertion :

void triInsertion ( char tab[max][Ma],int n) /*la fonction de tri par insertion ne retourne rien

donc void*/

{

int i,j;

char cle[30];

for(i=1;i<=n;i++) /* boucle for pour parcours du tableau */

{

j=i;

strcpy(cle,tab[j]);

while( j>=1 && strcmp(tab[j-1],cle)<0) /* boucle while qui fait le test et insert les

éléments */

{

strcpy(tab[j],tab[j-1]);

j=j-1;

strcpy(tab[j],cle);

}

Page 21: Rapport Projet Module Complexité

Rapport Mini-projet

Page 20

Fonction main :

int main()

{

float temps;

clock_t debut, fin;

char ch[10];

FILE *fich;

int D,i,x;

char C[max]="",T[max][Ma];

char* v;

fich=fopen("exemple.txt","r");

i=0;

if(fich!=NULL){

while(fgets (C,max,fich)!=NULL ){ /*on prend ligne par ligne*/

v=strtok(C," "); /*on divise ligne en mot par strtok*/

while(v!=NULL && i<max){

strcpy(T[i],v);

v=strtok(NULL," ");

i++;

} } }

printf("\n\n\n");

int choixMenu;

printf("---Menu---\n\n");

printf("1.afficher votre tableau !\n");

printf("2.chercher un element!\n");

printf("3.Trier le tableau (tri par insertion)!\n");

printf("4.Trier le tableau (tri à bulles)!\n");

printf("\nVotre choix?\n\n");

scanf("%d", &choixMenu);

if(choixMenu==1){

Page 22: Rapport Projet Module Complexité

Rapport Mini-projet

Page 21

int S;

if(choixMenu==1){

debut = clock();

for(x=0;x<i;x++){

printf("\tT[%d]=%s",x,T[x]);

printf("\n\n");}

fin= clock();

temps = (float)(fin-debut)/CLOCKS_PER_SEC;

printf("\ntemps = %f\n", temps);

printf("vous voulez continuer taper 1 pour continuer et 0 pour exit");

scanf("%d",&S);

{if(S==1)

main();

else

return 0; } }

if(choixMenu==2){

debut = clock();

printf("donner l'element à chercher");

scanf("%s",&ch);

D=recherche(T,ch);

printf("la valeur cherchée se trouve %d\a",D);

fin= clock();

temps = (float)(fin-debut)/CLOCKS_PER_SEC;

printf("\ntemps = %f\n", temps);

printf("vous voulez continuer taper 1 pour continuer et 0 pour exit");

scanf("%d",&S);

if(S==1)

{

main();}

else

return 0;

}

Page 23: Rapport Projet Module Complexité

Rapport Mini-projet

Page 22

if(choixMenu==3) {

debut = clock();

triInsertion(T,10);

for(i=0;i<10;i++){

printf(" T[%d]=%s ",i,T[i]);}

fin= clock();

temps = (float)(fin-debut)/CLOCKS_PER_SEC;

printf("\ntemps = %f\n", temps);

printf("vous voulez continuer taper 1 pour continuer et 0 pour exit");

scanf("%d",&S);

if(S==1)

{

main();}

else

return 0;

}

if(choixMenu==4) {

debut = clock();

tribulles(T,10);

for(i=0;i<10;i++){

printf(" T[%d]=%s ",i,T[i]);}

fin= clock();

temps = (float)(fin-debut)/CLOCKS_PER_SEC;

printf("\ntemps = %f\n", temps);

printf("vous voulez continuer taper 1 pour continuer et 0 pour exit");

scanf("%d",&S);

if(S==1)

{

main();}

else

return 0;

}

Page 24: Rapport Projet Module Complexité

Rapport Mini-projet

Page 23

Si on tape 1 :

Si on tape 2 :

else

printf("Ce choix n'existe pas dans notre menu !");}

}

Page 25: Rapport Projet Module Complexité

Rapport Mini-projet

Page 24

Si on tape 3 :

Si on tape 4 :

Page 26: Rapport Projet Module Complexité

Rapport Mini-projet

Page 25

On a pour le tri par insertion ou par bulles la compléxité soit pour les listes chainées ou par les tableaus

vaut

O(n²)

Donc pour le temps d’éxecution du tri par insertion dans le tableau :

Pour les listes chainées on a :

Complexité

théorique

Temps d’exécution

avec structure 1

(tableaux)

Temps d’exécution

avec structure 2

(liste chainée)

Algorithme 1 : tri par

insertion

O(n²) 0.002 0.001

Algorithme 2 : tri à

bulles

O(n²) 0.000 0.001

Algorithme 3 :

recherche

sequentielle

O(n) 2.56 3.77

Page 27: Rapport Projet Module Complexité

Rapport Mini-projet

Page 26

Pour le tri par bulle pour le tableau :

Page 28: Rapport Projet Module Complexité

Rapport Mini-projet

Page 27

Pour le tri des listes chainées par bulle :

Pour la recherche d’un mot dans le tableau :

Pour la recherche d’un mot dans la liste

Page 29: Rapport Projet Module Complexité

Rapport Mini-projet

Page 28