Commit 3b4dc716 authored by Barbier's avatar Barbier
Browse files

Version 1

parent 5c2b975a
Pipeline #4653 passed with stage
in 8 seconds
Barbier Alain 11500443
Ferreira Daniel 11706647
CC= gcc CC= gcc
CXXFLAGS= -Wall -ansi --pedantic -O3 CXXFLAGS= -Wall -ansi --pedantic -O3
CPP_O_FILE = arraylist.o analyzer.o main.o CPP_O_FILE = dynamic_arraylist.o analyzer.o dynamic_proba_aleatoire_main.o
LIB = -lm LIB = -lm
......
#include "dynamic_arraylist.h"
#include<stdio.h>
#include<stdlib.h>
arraylist_t * arraylist_create(){
arraylist_t * res = (arraylist_t *) malloc( sizeof(arraylist_t) );
res->data = (int *) malloc( sizeof(int) * 4 );
res->capacity = 4;
res->size = 0;
return res;
}
void arraylist_destroy(arraylist_t * a){
if( a != NULL ){
if( a->data != NULL )
free( a->data );
free( a );
}
}
void swap(int *x, int *y){
int temp = *x;
*x = *y;
*y = temp;
}
// pour avoir l'index du père du noeud à l'index i
int pere(int i) {
return (i-1) / 2;
}
// pour avoir l'index de l'enfant gauche du noeud à l'index i
int gauche(int i) {
return (2*i + 1);
}
//pour avoir l'index de l'enfant droit du noeud à l'index i
int droite(int i) {
return (2*i + 2);
}
int arraylist_append(arraylist_t * a, int x){
int nbSwap = 0;
if( a!=NULL ){
if( arraylist_do_we_need_to_enlarge_capacity(a) ){
arraylist_enlarge_capacity(a);
}
a->data[a->size++] = x;
//------Algorithme tas binaire
int i = a->size - 1;
while(i > 0 && a->data[pere(i)] > a->data[i]){
swap(&a->data[i], &a->data[pere(i)]);
nbSwap++;
i = pere(i);
}
//------FIN Algo
}
return nbSwap;
}
int entasserMin(arraylist_t * a,int i){
int nbSwap = 0;
int g = gauche(i);
int d = droite(i);
int minimum = i;
if(g < a->size && a->data[g] < a->data[minimum]){
minimum = g; //le fils gauche est plus petit que le minimum
}
if(d < a->size && a->data[d] < a->data[minimum]){
minimum = d; //le fils droit est plus petit que le minimum
}
if(minimum != i){
swap(&a->data[i],&a->data[minimum]);
nbSwap++;
nbSwap += entasserMin(a,minimum);
}
return nbSwap;
}
int arraylist_extraire_min(arraylist_t * a){
int nbSwap = 0;
if(a != NULL && a->size > 0){
if( arraylist_do_we_need_to_reduce_capacity(a) ){
arraylist_reduce_capacity(a);
}
if(a->size == 1){
a->size--;
return nbSwap;
}
a->data[0] = a->data[a->size - 1];
a->size--;
nbSwap = entasserMin(a,0);
}
return nbSwap;
}
int arraylist_get(arraylist_t * a, int pos){
if( a != NULL && pos >0 && pos < a->size ){
return a->data[pos];
}
printf("Wrong parameter pos=%d or NULL list", pos);
return -1;
}
size_t arraylist_size(arraylist_t * a){
return ( a!=NULL) ? a->size : -1;
}
size_t arraylist_capacity(arraylist_t * a){
return ( a!=NULL) ? a->capacity : -1;
}
char arraylist_do_we_need_to_enlarge_capacity(arraylist_t * a){
return a->size == a->capacity ? TRUE: FALSE;
}
void arraylist_enlarge_capacity(arraylist_t * a){
a->capacity *= 2;
a->data = (int *) realloc(a->data, sizeof(int) * a->capacity);
}
char arraylist_do_we_need_to_reduce_capacity(arraylist_t * a){
return ( a->size <= a->capacity/4 && a->size >4 )? TRUE: FALSE;
}
void arraylist_reduce_capacity(arraylist_t * a){
a->capacity /= 2;
a->data = (int *) realloc(a->data, sizeof(int) * a->capacity);
}
#ifndef __ARRAYLIST_H
#define __ARRAYLIST_H
#define FALSE 0
#define TRUE 1
#include <stddef.h>
/**
Tableau dynamique d'entiers.
*/
typedef struct arraylist_s{
// Pointeur vers la zone de mémoire où les entiers seront stockées.
int * data;
// Taille réelle, ou capacité de stockage, du tableau.
size_t capacity;
// Nombre d'éléments stockés dans le tableau.
size_t size;
} arraylist_t;
/**
Fonction d'initialisation d'un tableau dynamique.
Complexité en temps/espace, pire et meilleur cas : O(1)
@return Un pointeur sur un tableau dynamique nouvellement alloué.
*/
arraylist_t * arraylist_create();
/**
Fonction de libération de la mémoire occupée par un tableau dynamique.
Complexité en temps/espace, pire et meilleur cas : O(1)
@param a est un pointeur vers l'espace mémoire que la fonction va libérer.
*/
void arraylist_destroy(arraylist_t * a);
/**
Ajoute une valeur dans le tableau.
Complexité en temps/espace, pire cas : O(log2(size))
Complexité en temps/espace, meilleur cas : O(1)
Complexité amortie : O(1)
@param a est le tableau auquel on souhaite ajouter une valeur.
@param x est la valeur que l'on souhaite ajouter.
@returns nb_Swap qui correspond au nombre de swap
*/
int arraylist_append(arraylist_t * a, int x);
/**
Extrait la racine (l'entier de plus petite valeur) du tas_min
Complexité en temps, pire cas : O(log2(size))
Complexité en temps, meilleur cas : O(1)
Complexité amortie : O(1)
@param a est le tableau auquel on souhaite extraire la racine.
@returns nb_Swap qui correspond au nombre de swap
*/
int arraylist_extraire_min(arraylist_t * a);
/**
Renvoie la valeur située à la position donnée par l'utilisateur.
Complexité en temps/espace, pire cas : O(1)
@param a est un pointeur vers un tableau.
@param pos est la l'indice de la case on l'utilisateur veut connaître la valeur.
@returns la valeur située à la position donnée par l'utilisateur.
*/
int arraylist_get(arraylist_t * a, int pos);
/**
Renvoie le nombre d'éléments stockés dans le tableau.
Complexité en temps/espace, pire cas : O(1)
@param a est un pointeur vers un tableau.
@returns le nombre d'éléments stockés dans le tableau.
*/
size_t arraylist_size(arraylist_t * a);
/**
Renvoie la capacité de stockage du tableau.
Complexité en temps/espace, pire cas : O(1)
@param a est un pointeur vers un tableau.
@returns la capacité de stockage du tableau.
*/
size_t arraylist_capacity(arraylist_t * a);
/**
Cette fonction détermine la règle selon laquelle un espace mémoire plus grand sera alloué ou non.
@param a est un pointeur vers un tableau.
@returns VRAI si le tableau doit être agrandi, FAUX sinon.
*/
char arraylist_do_we_need_to_enlarge_capacity(arraylist_t * a);
/**
Cette fonction augmente la capacité du tableau.
@param a est un pointeur vers un tableau.
*/
void arraylist_enlarge_capacity(arraylist_t * a);
/**
Cette fonction détermine la règle selon laquelle un espace mémoire plus petit sera alloué ou non.
@param a est un pointeur vers un tableau.
@returns VRAI si le tableau doit être réduit, FAUX sinon.
*/
char arraylist_do_we_need_to_reduce_capacity(arraylist_t * a);
/**
Cette fonction réduit la capacité du tableau.
@param a est un pointeur vers un tableau.
*/
void arraylist_reduce_capacity(arraylist_t * a);
#endif
#include<stdio.h>
#include <time.h>
#include<stdlib.h>
#include "dynamic_arraylist.h"
#include "analyzer.h"
int main(int argc, char ** argv){
int i;
// Tableau dynamique.
arraylist_t * a = arraylist_create();
// Analyse du temps pris par les opérations.
analyzer_t * time_analysis = analyzer_create();
// Analyse du nombre de swaps faites par les opérations.
analyzer_t * swap_analysis = analyzer_create();
// Analyse de l'espace mémoire inutilisé.
analyzer_t * memory_analysis = analyzer_create();
// Mesure de la durée d'une opération.
struct timespec before, after;
clockid_t clk_id = CLOCK_REALTIME;
// Nombre de swaps realisés.
int nbSwap = 0;
int nb_aleatoire;
srand(time(NULL));
float p = 0.1;
double resultat;
for(i = 0; i < 1000000 ; i++){
nb_aleatoire = rand() % 1000000;
resultat = (double) rand() / RAND_MAX;
// Ajout ou extraction d'un élément et mesure du temps pris par l'opération.
clock_gettime(clk_id, &before);
if(resultat <= p) { // P
nbSwap = arraylist_append(a, nb_aleatoire); // On ajoute une valeur aléatoire
}
else { // 1 - P
nbSwap = arraylist_extraire_min(a);
}
clock_gettime(clk_id, &after);
// Enregistrement du temps pris par l'opération
analyzer_append(time_analysis, after.tv_nsec - before.tv_nsec);
// Enregistrement du nombre de swaps efféctués par l'opération.
analyzer_append(swap_analysis,nbSwap);
// Enregistrement de l'espace mémoire non-utilisé.
analyzer_append(memory_analysis,arraylist_capacity(a)-arraylist_size(a));
}
// Affichage de quelques statistiques sur l'expérience.
fprintf(stderr, "Total cost: %Lf\n", get_total_cost(time_analysis));
fprintf(stderr, "Average cost: %Lf\n", get_average_cost(time_analysis));
fprintf(stderr, "Variance: %Lf\n", get_variance(time_analysis));
fprintf(stderr, "Standard deviation: %Lf\n", get_standard_deviation(time_analysis));
// Sauvegarde les données de l'expérience.
save_values(time_analysis, "../plots/dynamic_binary_heap_extract_amortized_time_C.plot");
save_values(swap_analysis, "../plots/dynamic_binary_heap_extract_swap_C.plot");
save_values(memory_analysis, "../plots/dynamic_binary_heap_extract_wasted_memory_C.plot");
// Nettoyage de la mémoire avant la sortie du programme
arraylist_destroy(a);
analyzer_destroy(time_analysis);
analyzer_destroy(swap_analysis);
analyzer_destroy(memory_analysis);
return EXIT_SUCCESS;
}
#include "fixed_arraylist.h"
#include<stdio.h>
#include<stdlib.h>
arraylist_t * arraylist_create(){
arraylist_t * res = (arraylist_t *) malloc( sizeof(arraylist_t) );
res->data = (int *) malloc( sizeof(int) * 1000000 );
res->capacity = 1000000;
res->size = 0;
return res;
}
void arraylist_destroy(arraylist_t * a){
if( a != NULL ){
if( a->data != NULL )
free( a->data );
free( a );
}
}
void swap(int *x, int *y){
int temp = *x;
*x = *y;
*y = temp;
}
// pour avoir l'index du père du noeud à l'index i
int pere(int i) {
return (i-1) / 2;
}
// pour avoir l'index de l'enfant gauche du noeud à l'index i
int gauche(int i) {
return (2*i + 1);
}
//pour avoir l'index de l'enfant droit du noeud à l'index i
int droite(int i) {
return (2*i + 2);
}
int arraylist_append(arraylist_t * a, int x){
int nbSwap = 0;
if( a!=NULL ){
if( arraylist_do_we_need_to_enlarge_capacity(a) ){
printf("On ne peut plus ajouter d'element car le tas binaire est plein\n");
return nbSwap;
}
a->data[a->size++] = x;
//------Algorithme tas binaire
int i = a->size - 1;
while(i > 0 && a->data[pere(i)] > a->data[i]){
swap(&a->data[i], &a->data[pere(i)]);
nbSwap++;
i = pere(i);
}
//------FIN Algo
}
return nbSwap;
}
int entasserMin(arraylist_t * a,int i){
int nbSwap = 0;
int g = gauche(i);
int d = droite(i);
int minimum = i;
if(g < a->size && a->data[g] < a->data[minimum]){
minimum = g; //le fils gauche est plus petit que le minimum
}
if(d < a->size && a->data[d] < a->data[minimum]){
minimum = d; //le fils droit est plus petit que le minimum
}
if(minimum != i){
swap(&a->data[i],&a->data[minimum]);
nbSwap++;
nbSwap += entasserMin(a,minimum);
}
return nbSwap;
}
int arraylist_extraire_min(arraylist_t * a){
int nbSwap = 0;
if(a != NULL && a->size > 0){
if(a->size == 1){
a->size--;
return nbSwap;
}
a->data[0] = a->data[a->size - 1];
a->size--;
nbSwap = entasserMin(a,0);
}
return nbSwap;
}
int arraylist_get(arraylist_t * a, int pos){
if( a != NULL && pos >0 && pos < a->size ){
return a->data[pos];
}
printf("Wrong parameter pos=%d or NULL list", pos);
return -1;
}
size_t arraylist_size(arraylist_t * a){
return ( a!=NULL) ? a->size : -1;
}
size_t arraylist_capacity(arraylist_t * a){
return ( a!=NULL) ? a->capacity : -1;
}
char arraylist_do_we_need_to_enlarge_capacity(arraylist_t * a){
return a->size == a->capacity ? TRUE: FALSE;
}
#ifndef __ARRAYLIST_H
#define __ARRAYLIST_H
#define FALSE 0
#define TRUE 1
#include <stddef.h>
/**
Tableau fixe d'entiers.
*/
typedef struct arraylist_s{
// Pointeur vers la zone de mémoire où les entiers seront stockées.
int * data;
// Taille réelle, ou capacité de stockage, du tableau.
size_t capacity;
// Nombre d'éléments stockés dans le tableau.
size_t size;
} arraylist_t;
/**
Fonction d'initialisation d'un tableau fixe.
Complexité en temps/espace, pire et meilleur cas : O(1)
@return Un pointeur sur un tableau fixe d'1000000 éléments nouvellement alloué.
*/
arraylist_t * arraylist_create();
/**
Fonction de libération de la mémoire occupée par un tableau fixe.
Complexité en temps/espace, pire et meilleur cas : O(1)
@param a est un pointeur vers l'espace mémoire que la fonction va libérer.
*/
void arraylist_destroy(arraylist_t * a);
/**
Ajoute une valeur dans le tableau.
Complexité en temps/espace, pire cas : O(log2(size))
Complexité en temps/espace, meilleur cas : O(1)
Complexité amortie : O(1)
@param a est le tableau auquel on souhaite ajouter une valeur.
@param x est la valeur que l'on souhaite ajouter.
@returns nb_Swap qui correspond au nombre de swap
*/
int arraylist_append(arraylist_t * a, int x);
/**
Extrait la racine (l'entier de plus petite valeur) du tas_min
Complexité en temps, pire cas : O(log2(size))
Complexité en temps, meilleur cas : O(1)
Complexité amortie : O(1)
@param a est le tableau auquel on souhaite extraire la racine.
@returns nb_Swap qui correspond au nombre de swap
*/
int arraylist_extraire_min(arraylist_t * a);
/**
Renvoie la valeur située à la position donnée par l'utilisateur.
Complexité en temps/espace, pire cas : O(1)
@param a est un pointeur vers un tableau.
@param pos est la l'indice de la case on l'utilisateur veut connaître la valeur.
@returns la valeur située à la position donnée par l'utilisateur.
*/
int arraylist_get(arraylist_t * a, int pos);
/**
Renvoie le nombre d'éléments stockés dans le tableau.
Complexité en temps/espace, pire cas : O(1)
@param a est un pointeur vers un tableau.
@returns le nombre d'éléments stockés dans le tableau.
*/
size_t arraylist_size(arraylist_t * a);
/**
Renvoie la capacité de stockage du tableau.
Complexité en temps/espace, pire cas : O(1)
@param a est un pointeur vers un tableau.
@returns la capacité de stockage du tableau.
*/
size_t arraylist_capacity(arraylist_t * a);
/**
Cette fonction détermine la règle selon laquelle le tableau a atteint le nombre maximum d'éleemnts ou non
@param a est un pointeur vers un tableau.
@returns VRAI si le tableau est plein, FAUX sinon.
*/
char arraylist_do_we_need_to_enlarge_capacity(arraylist_t * a);
#endif
#include<stdio.h>
#include <time.h>
#include<stdlib.h>
#include "fixed_arraylist.h"
#include "analyzer.h"
int main(int argc, char ** argv){
int i;
// Tableau fixe.
arraylist_t * a = arraylist_create();
// Analyse du temps pris par les opérations.
analyzer_t * time_analysis = analyzer_create();
// Analyse du nombre de swaps faites par les opérations.
analyzer_t * swap_analysis = analyzer_create();
// Analyse de l'espace mémoire inutilisé.
analyzer_t * memory_analysis = analyzer_create();
// Mesure de la durée d'une opération.
struct timespec before, after;
clockid_t clk_id = CLOCK_REALTIME;
// Nombre de swaps realisés.
int nbSwap = 0;
int nb_aleatoire;
srand(time(NULL));
float p = 0.1;
double resultat;
for(i = 0; i < 1000000 ; i++){
nb_aleatoire = rand() % 1000000;
resultat = (double) rand() / RAND_MAX;
// Ajout ou extraction d'un élément et mesure du temps pris par l'opération.
clock_gettime(clk_id, &before);
if(resultat <= p) { // P
nbSwap = arraylist_append(a, nb_aleatoire); // On ajoute une valeur aléatoire
}
else { // 1 - P
nbSwap = arraylist_extraire_min(a);
}
clock_gettime(clk_id, &after);
// Enregistrement du temps pris par l'opération
analyzer_append(time_analysis, after.tv_nsec - before.tv_nsec);
// Enregistrement du nombre de swaps efféctués par l'opération.
analyzer_append(swap_analysis,nbSwap);
// Enregistrement de l'espace mémoire non-utilisé.
analyzer_append(memory_analysis,arraylist_capacity(a)-arraylist_size(a));
}
// Affichage de quelques statistiques sur l'expérience.
fprintf(stderr, "Total cost: %Lf\n", get_total_cost(time_analysis));
fprintf(stderr, "Average cost: %Lf\n", get_average_cost(time_analysis));
fprintf(stderr, "Variance: %Lf\n", get_variance(time_analysis));
fprintf(stderr, "Standard deviation: %Lf\n", get_standard_deviation(time_analysis));
// Sauvegarde les données de l'expérience.
save_values(time_analysis, "../plots/fixed_binary_heap_extract_amortized_time_C.plot");
save_values(swap_analysis, "../plots/fixed_binary_heap_extract_swap_C.plot");
save_values(memory_analysis, "../plots/fixed_binary_heap_extract_wasted_memory_C.plot");
// Nettoyage de la mémoire avant la sortie du programme
arraylist_destroy(a);
analyzer_destroy(time_analysis);
analyzer_destroy(swap_analysis);
analyzer_destroy(memory_analysis);
return EXIT_SUCCESS;
}
CC= g++
CXXFLAGS= -Wall -ansi --pedantic -g
CPP_O_FILE = analyzer.o main.o
all: $(CPP_O_FILE)
$(CC) $(CXXFLAGS) -o arraylist_analysis $(CPP_O_FILE)
clean:
rm -rf *.o
rm -rf *~
rm -rf arraylist_analysis
%.o: %.cpp
$(CC) $(CPPFLAGS) -c $< -o $@
#include "analyzer.hpp"
#include <fstream>