Anda di halaman 1dari 17

TP d’algorithmique/ 2008-

systemesdeproduction.blogspot.com 2009

• systemesdeproduction.blogspot.com

Introduction

La complexité algorithmique permet de mesurer les


performances d'un algorithme et de le comparer avec d'autres
algorithmes réalisant les mêmes fonctionnalités.
Aussi, ce concept fondamental, indispensable pour tout
informaticien, permet de déterminer si un algorithme et meilleur
qu'un autre et s'il est optimal ou s'il ne doit pas être utilisé.

En effet, l’assimilation des différents mécanismes vus dans le


cours exige une application sur machines. Cela aboutira
inéluctablement à la perception de la grande différences qui réside
entre les algorithmes en terme de temps d’exécution.

Saisissant l’esprit de cette vision, le présent travail pratique


propose de programmer un ensemble de fonction en langage C++,
et de procéder par la suite à la comparaison de leur temps
d’exécution.

1
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

Travail demandé
PROBLEM I

On considère les trois algorithmes de Fibonacci vus dans le


cours.

1) Ecrire en C++ la traduction des trois algorithmes précédents


sous formes de fonction fib1, fib2 et fib3.
2) A partir de quelle valeur de n, il y a dépassement de
capacité ?
3) Implanter un artifice permettant de comparer leurs temps
d’exécution, pour toute valeur de n, sans avoir de problème
de dépassement de capacité.
4) Soient : t(1), t(2) et t(3) les temps d’exécution réels de fib1,
fib2 et fib3 respectivement. écrire un programme principal
permettant de tracer sur le même graphique t1, t2 et t3 en
fonction de n ou 20<=n<= 100 000

PROBLEM II

1) Créer en C++ une classe Tableau contenant comme donnée


un tableau T[1..n] de réels et comme méthodes :
Une fonction generer qui remplit le tableau avec des nombres
aléatoires
Une fonction insertsort qui trie le tableau avec l’algorithme
d’insertion
Une fonction bullsort qui trie le tableau avec l’algorithme bulle
Une fonction quicksort qui trie le tableau avec l’algorithme
quicksort

2) Créer une classe Heap qui hérite da la classe Tableau et qui


implémente comme méthodes ;
Les fonctions vues en cours :
2
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

 Percoler.
 Tamiser.
 Modif_Heap.
 Maximum.
 Eliminer_racine.
 Ajout_noeud.
 Faire_Heap.
 Heapsort.

1) Ecrire un programme principal qui calcul pour chaque valeur


de n=(100,200,300,400,1000,1500) le temps t(n) pris par les
algorithmes de trie : insertsort ,bullsort ,quicksort
,Heapsortet trace un seul diagramme donnant ces temps en
fonction de n (commentaires et conclusion) .

PROBLEM I

1) codage des trois fonctions de Fibonacci en langage


C++

Fonction fib1 : (version itérative)

long int fib1(double n)

{
if(n<=1)
return n;
else
{
long int i;
long int u=0;
long int v=1;
long int w;
for(i=1;i<n;i++)
{
w=u+v;
u=v;
v=w;
}
return w;
}
}
3
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

Fonction fib2 : (version récursive non terminale)

int fib2(int n)
{
if(n<=1)
{
return n;
}
else
{
return fib2(n-1)+fib2(n-2);
}
}

Fonction fib3 : (version récursive terminale)

long int fib3(long int n,long int a,long int b)


{
if (n==0) return a;
if (n==1) return b;
return fib3(n-1,b,a+b);
}

2) valeur de n pour un dépassement mémoire :

Le dépassement mémoire se produit une fois on atteint la valeur de


n=47

4
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

Figure 1 : capture d’écran illustrant le dépassement mémoire pour n=47

3) Comparaison du temps d’exécution des trois codes :

A ce stade, la nécessité d’implémenter des fonctions qui


peuvent schématiser à travers un graphe l’évolution des valeurs
prise par ces fonctions s’impose.
A cet effet, il parait judicieux d’utiliser l’environnement VISUEL
STUDIO C++

Le corps du code qui nous generer le garphe est le suivant :

NB : ce code implémentera les trois fonction dans le meme code ou


bien un fichier « .h » qui sera inclus dans le même code.

void CTst1Dlg::OnButton1()
{

clock_t start, finish;


long int fib33[10],fib22[10];
long int temps_debut = GetTickCount();
long int temps_fin = GetTickCount();
long int n=20;
for (long int i=0;i<100;i++)
{
mtimer timer;
fib1(n);
a[i]= timer.elapsed_usec();;//temps_fin-
temps_debut;
timer;
fib3(n,0,1);
b[i]= timer.elapsed_usec();;//temps_fin-
temps_debut;
this->UpdateData(false);
5
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

n=n+100;
}
n=1;
for(i=0;i<10;i++)
{
mtimer timer;
fib2(n);
c[i]= timer.elapsed_usec();
n=n+2;
}
txt= a[0];
txt1= a[1];
txt2= a[2];
txt3= a[3];
txt4= a[4];
txt5= a[5];

this->UpdateData(false);
this->Invalidate();
}
//trace

CString mess="iterative";
CPen p(PS_SOLID,5,RGB(60,255,60));
CPen p2(PS_SOLID,5,RGB(200,0,15));
CPen p3(PS_SOLID,5,RGB(200,0,200));
CPen p0(PS_SOLID,5,RGB(0,0,0));

dc.SelectObject(&p);

dc.TextOut(270,347,mess);
dc.MoveTo(230,350);
dc.LineTo(260,350);

mess="recursive terminale";
dc.SelectObject(&p2);

dc.TextOut(270,362,mess);
dc.MoveTo(230,365);
dc.LineTo(260,365);

mess="recursive ";
dc.SelectObject(&p3);

dc.TextOut(270,377,mess);
dc.MoveTo(230,380);
dc.LineTo(260,380);

6
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

dc.SelectObject(&p0);
mess="t(n)";
dc.TextOut(20,230,mess);
mess="(n)";
dc.TextOut(605,610,mess);
dc.MoveTo(30,250);
dc.LineTo(30,600);
dc.MoveTo(30,600);
dc.LineTo(600,600);
int n=3;
if (a[9]>0)
{
dc.SelectObject(&p);
dc.MoveTo(30,600);
for(int i=0;i<100;i++)
{
dc.LineTo((30+n)*2,600-(a[i])/10);

dc.MoveTo((30+n)*2,600-(a[i])/10);
n=n+2;
}

}
dc.SelectObject(&p2);
n=3;
if (b[9]>0)
{
dc.MoveTo(30,600);
for(int i=0;i<100;i++)
{
dc.LineTo((30+n)*2,600-b[i]/10);

dc.MoveTo((30+n)*2,600-b[i]/10);
n=n+2;
}
dc.SelectObject(&p3);
//fib2
n=10;
if (c[9]>0)
{
dc.MoveTo(30,600);
for(int i=0;i<10;i++)
{
dc.LineTo((30+n)*1,600-c[i]);

dc.MoveTo((30+n)*1,600-c[i]);
n=n+3;
}

7
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

}
}
CDialog::OnPaint();
}
}

Apres exécution de ce code nous obtiendrons le graphe


suivant :

Fib1 itérative
Fib2 récursive non
terminale

Figure 2 : capture d’écran du graphe illustrant l’évolution du temps


d’exécution

8
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

PROBLEM II

1) Création de la classe abstraite Tableau

class Tableau{
protected:
int *Tab;
static int Max;
public:
int GetMax(){return Max;}
int SetMax(int max){this->Max=max;}
Tableau(int N);
// l’ensemble de ces
void remplire(void);
méthodes seront redéfinis
void generer(void);
dans la classe dérivée Heap
void afficher(void);
void insertsort(void);
void quick_sort(int,int);
void generation(int ) ;
};

2) Création de la classe Heap

int Tableau::Max=0;
class Heap: public Tableau{

public:
Heap(int );
void percoler(int);
void tamiser(int);
void faire_Heap();
void heap_sort(void) ;
void ajouter_noeud(int);
void suprimer_racine(void);
void modifier_noeud(int, int);
};

3) implémentation de différentes méthodes :

9
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

//********************génération d'un tableau des nombres


aléatoires******************

void Tableau::generer()
{ int nombre;
cout<<"donner la taille de votre tableau\n";
cin>>nombre;
SetMax(nombre);
for(int i=0;i<Max;i++)
{
Tab[i]=random(200);
}
}
void Tableau::generation(int nombre)
{ ;
SetMax(nombre);
for(int i=0;i<Max;i++)
{
Tab[i]=random(156);
}
}
Tableau::Tableau(int N){
Tab=new int[N];
//Max=9;
}
void Tableau::remplire() //(int n)
{int nombre;
cout<<"donner la taille de votre tableau\n";
cin>>nombre;
SetMax(nombre);
for (int i = 0 ; i <Max ; i++)
{
printf("Tab[%d] = ",i);
cin>>Tab[i];
}

10
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

Figure 3 : exemple d’exécution de la méthode « générer » en mode console

//*********************la fonction de trie par


insertion******************************

void Tableau::insertsort()
{
int j,x;
for(int i=1;i<Max;i++)
{
x=Tab[i];
j=i-1;
while(j>=0 && x <Tab[j])
{
Tab[j+1]=Tab[j];
j=j-1;
}
Tab[j+1]=x;
}
}

Figure 4 : exemple d’exécution de la méthode « insertsort» en mode console

//**************************la fonction de trie quicksort


******************************

void Tableau::quick_sort(int p,int r)


{
int pivot;
if (p < r)
{
pivot=pivoter(p,r);
quick_sort(p,pivot-1);

11
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

quick_sort(pivot+1,r);
}
}

Figure 5 : exemple d’exécution de la méthode « quicksort» en mode console

//**************création de la classe Heap et redifinition


desthodes***********************

Heap::Heap(int N):Tableau(N)
{
}
void Heap::percoler(int i)
{
int h = i;
int j ;
do
{
j = h;
if ((j > 0) && (Tab[j / 2] <
Tab[h]))
{
h = j / 2;
int aux;
aux = Tab[j];
Tab[j] = Tab[h];
Tab[h] = aux;
}
}while ( j != h);
}

12
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

//****************redéfinition de la méthode tamiser**************************

void Heap::tamiser(int i)
{
int j,z;
int k=i;
do
{
j=k;
if((2*j+1<Max) && (this-
>Tab[2*j+1]>this->Tab[k]))
{
k=2*j+1;
}
if(((2*j+2)<Max) && (this-
>Tab[2*j+2]>this->Tab[k]))
{
k=2*j+2;
}
z=this->Tab[j];
this->Tab[j]=this->Tab[k];
this->Tab[k]=z;
}
while(j!=k);
}

//****************redéfinition de la méthode ajouter**************************

void Heap::ajouter_noeud(int val)


{
Tab[Max]=val;
percoler(Max);
Max++;
}

13
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

Figure 6 : exemple d’exécution de la méthode « ajouter» en mode console

//****************redéfinition de la méthode supprimer


**************************

void Heap::suprimer_racine(void)
{
this-
>Tab[0]=this->Tab[Max--];
Max-- ;
this-
>tamiser(0);
Max++;
}

//****************redéfinition de la méthode modifier **************************

void Heap::modifier_noeud(int i, int valeur)


{
int
ancien=Tab[i];
Tab[i]=val;

if(ancien>valeur)

tamiser(i);
else
this-
>percoler(i);
}

14
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

Figure7 : exemple d’exécution de la méthode « modifier» en mode console

4) comparaison du temps d’exécution :

Cette phase consiste à comparer le temps d’exécution des


différents algorithmes de tris.
Afin d’y parvenir nous allons refaire la même procédure
évoquée lors du premier TP.
En premier lieu nous allons stocker les six valeurs proposées
dans un tableau Y[]
avec n={100,200,300,400,1000,1500}
le code qui nous permettra de manipuler les méthodes qui
retourne des valeurs en terme de temps d’exécution est le suivant :

M_timer timer;
/* c’est une classe prédéfinie contenant des
méthodes qui permettent de calculer le temps
d’exécution d’un programme */
for(int i=0;i<=5;i++)
{
tab.generer(Y[i]);//génère un tableau avec les
valeurs prédéfinies de n

15
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

timer; //initialisation
du timer
tab.insertsort(0,Y[i]); // application de la méthode
de calcule de temps à la méthode insersort
a[i]=timer.elapsed_usec(); // méthode
prédéfinis qui retourne le temps d’exécution

}
this->Invalidate();// retourner les paramètres
nécessaires pour tracer la
courbe

L’exécution simultané de ce code et la sa duplication pour


toutes les fonctions de tries donne lieu à ce graphe avec quatre
boutons pour chaque fonction de tries :

Tri rapide
Tri
insertion
Tri
monceau

Figure 8 : capture d’écran du graphe illustrant l’évolution du temps


d’exécution des fonctions de tris

CONCLUSION
16
TP d’algorithmique/ 2008-
systemesdeproduction.blogspot.com 2009

A partir de la figure n°8, on déduit aisément que l’algorithmes


le plus puissant de tri est le tri rapide dont le temps d’exécution
reste relativement identique au tri Monceau pour des valeurs
moyenne de n (<inferieures à 1000) .

Toutefois, les deux autres méthodes de tri (quicksort,


insersort) et nettement plus lentes.

En guise de conclusion, l’apport de ce TP nous a été d’une


grande utilité en termes d’apprentissage de nouvelles techniques.

En effet, le dernier volet de chaque problème exigeait de notre


part la maitrise d’un outil graphique. Et c’est à travers ce TP que
notre équipe a pu advenir à ce but .

17

Anda mungkin juga menyukai