diff --git a/bubblesort.c b/bubblesort.c index a848827..1e88188 100644 --- a/bubblesort.c +++ b/bubblesort.c @@ -17,5 +17,5 @@ void bubblesort(int* array, int length) swapped++; } } - } while(swapped==1); + } while(swapped>0); } diff --git a/gmon.out b/gmon.out new file mode 100644 index 0000000..bf7cb34 Binary files /dev/null and b/gmon.out differ diff --git a/qiktri.c b/qiktri.c new file mode 100644 index 0000000..c863e33 --- /dev/null +++ b/qiktri.c @@ -0,0 +1,76 @@ +#include "qiktri.h" + +static void insertion_sort(int* array, int low, int high) +{ + for (int i = low + 1; i <= high; i++) + { + int key = array[i]; + int j = i - 1; + while (j >= low && array[j] > key) + { + array[j + 1] = array[j]; + j--; + } + array[j + 1] = key; + } +} + +static int partition_qiktri(int* array, int low, int high) +{ + int mid = low + (high - low) / 2; + + // médiane de trois pour choisir un bon pivot + if (array[mid] < array[low]) { + int tmp = array[mid]; array[mid] = array[low]; array[low] = tmp; + } + if (array[high] < array[low]) { + int tmp = array[high]; array[high] = array[low]; array[low] = tmp; + } + if (array[mid] < array[high]) { + int tmp = array[mid]; array[mid] = array[high]; array[high] = tmp; + } + + int pivot = array[high]; + int i = low - 1; + for (int j = low; j < high; j++) + { + if (array[j] <= pivot) + { + i++; + int temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + } + + int temp = array[i + 1]; + array[i + 1] = array[high]; + array[high] = temp; + + return i + 1; +} + +void qiktri(int* array, int low, int high) // ⬅️ plus de "static" +{ + while (low < high) + { + if (high - low < 16) + { + insertion_sort(array, low, high); + break; + } + + int pi = partition_qiktri(array, low, high); + + if (pi - low < high - pi) + { + qiktri(array, low, pi - 1); + low = pi + 1; + } + else + { + qiktri(array, pi + 1, high); + high = pi - 1; + } + } +} \ No newline at end of file diff --git a/qiktri.h b/qiktri.h new file mode 100644 index 0000000..9400ad7 --- /dev/null +++ b/qiktri.h @@ -0,0 +1,7 @@ +#ifndef QIKTRI_ +#define QIKTRI_ + +// Déclaration des fonctions publiques +void qiktri(int* array, int low, int high); + +#endif diff --git a/rapport_Hugo_raban b/rapport_Hugo_raban new file mode 100644 index 0000000..bdfeb21 --- /dev/null +++ b/rapport_Hugo_raban @@ -0,0 +1,107 @@ +[raban@salle235-04 TD1_DEV51_Qualite_Algo]$ time ./student_rank 1000 1000 0 + +real 0m2.975s +user 0m2.963s +sys 0m0.007s + +[raban@salle235-04 TD1_DEV51_Qualite_Algo]$ gprof ./student_rank + +Flat Profile : temps et nombre d'exécution par fonction + +Each sample counts as 0.01 seconds. + % cumulative self self total + time seconds seconds calls s/call s/call name + 79.14 2.32 2.32 1001000 0.00 0.00 bubblesort + 18.46 2.86 0.54 1000000 0.00 0.00 find_rank_student + 2.05 2.92 0.06 1 0.06 2.92 sort_students + 0.34 2.93 0.01 1 0.01 0.01 generate_ranks + 0.17 2.93 0.01 1000 0.00 0.00 generate_array + 0.00 2.93 0.00 2 0.00 0.00 free_array + 0.00 2.93 0.00 1 0.00 0.01 generate_grades + +légende : + +% time : pourcentage de temps passé sur une fonction. + +Cumulative seconds : somme des secondes compté par celle de la fonction et ceux listés au dela de la seconde + +Self seconds : le nombre de seconde compté par cette fonction seul + +Calls : nombre de fois où la fonction est appelé + +Self ms/call : le nombre moyen de millisecondes passé dans la fonction par appel (si la fonction est profilé +), sinon la colonne reste vide + +Total ms/call : le nombre moyen de millisecondes passé sur la fonction et ses descendants par appel (si la fonction est profilé +), sinon la colonne reste vide + +Name : nom de la fonction + +Call graph : arbre d'appel fonctions + temps execution par fonction + +index % time self children called name + +[1] 100.0 0.00 2.93 main [1] + 0.06 2.86 1/1 sort_students [2] + 0.01 0.00 1/1 generate_ranks [5] + 0.00 0.01 1/1 generate_grades [7] + 0.00 0.00 2/2 free_array [8] +----------------------------------------------- + 0.06 2.86 1/1 main [1] +[2] 99.5 0.06 2.86 1 sort_students [2] + 0.54 2.32 1000000/1000000 find_rank_student [3] + 0.00 0.00 1000/1001000 bubblesort [4] +----------------------------------------------- + 0.54 2.32 1000000/1000000 sort_students [2] +[3] 97.4 0.54 2.32 1000000 find_rank_student [3] + 2.32 0.00 1000000/1001000 bubblesort [4] +----------------------------------------------- + 0.00 0.00 1000/1001000 sort_students [2] + 2.32 0.00 1000000/1001000 find_rank_student [3] +[4] 79.0 2.32 0.00 1001000 bubblesort [4] +----------------------------------------------- + 0.01 0.00 1/1 main [1] +[5] 0.3 0.01 0.00 1 generate_ranks [5] +----------------------------------------------- + 0.01 0.00 1000/1000 generate_grades [7] +[6] 0.2 0.01 0.00 1000 generate_array [6] +----------------------------------------------- + 0.00 0.01 1/1 main [1] +[7] 0.2 0.00 0.01 1 generate_grades [7] + 0.01 0.00 1000/1000 generate_array [6] +----------------------------------------------- + 0.00 0.00 2/2 main [1] +[8] 0.0 0.00 0.00 2 free_array [8] +----------------------------------------------- + +légende : + +Index : nombre unique donné à chaque éléments de la table + +% time : pourcentage du "total" de temps qui ont été passé sur cette fonction et ses enfants + +Self : nombre total de temps passé par la fonction + +Children : nombre total de temps passé par la fonction par ses enfants + +Called : nombre de fois que la fonction à été appellé. Si la fonction s'appelle elle-même, le nombre n'inclue pas les appelles récursifs + +Name : nom de la fonction + + +fonction la plus lente : bubblesort + +N?ombre d'appel important de bubblesortr dans la fonction : 1000000 + + +Optimisation possible : +- modifier find_rank_student et sort_student afin qu'il y est un seul tri + une gestion des égalité un peu mieux +- dans bubblesort, mettre while(swapped>0) + +temps : 3,145s, c'est bien mais pas assez + +usage de heapsort au lieu de bubblesort. + +temps : 0.124s super efficace! + +Pour qiktri, il est plus lent alors qu'il est censé etre plus rapide. \ No newline at end of file diff --git a/student_rank b/student_rank new file mode 100755 index 0000000..c93e3b1 Binary files /dev/null and b/student_rank differ diff --git a/student_rank.c b/student_rank.c index af84003..a5ace6b 100644 --- a/student_rank.c +++ b/student_rank.c @@ -5,6 +5,7 @@ #include #include "heapsort.h" #include "bubblesort.h" +#include "qiktri.h" void generate_grades(int** students_array, int students_number, int grades_number) { @@ -51,38 +52,50 @@ void print_student_array(int** students_array, int students_number, int grades_n printf("----------------------\n"); } -int find_rank_student(int student_grade, int* grades_array, int students_number) +int find_rank_student(int student_grade, int* sorted_grades, int students_number) { - int position = -1; - int i = 0; - bubblesort(grades_array,students_number); - for(i = students_number-1; i >= 0; i--) + int i; + int rank = 1; + + for(i = students_number - 1; i >= 0; i--) { - if(grades_array[i] == student_grade) - { - position = students_number-i; - break; - } + if(sorted_grades[i] == student_grade) + { + return rank; + } + + if(i > 0 && sorted_grades[i] != sorted_grades[i-1]) + { + rank++; + } } - return position; + return -1; } void sort_students(int** students_rank, int** students_array, int students_number, int grades_number) { - int i = 0, j = 0; + int i, j; for(i = 0; i < grades_number; i++) { - int * grades = (int*) malloc(students_number*sizeof(int)); - for(j = 0; j < students_number; j++) - { - grades[j] = students_array[j][i]; - } - bubblesort(grades,students_number); - for(j = 0; j < students_number; j++) - { - students_rank[j][i] = find_rank_student(students_array[j][i],grades,students_number); - } - free(grades); + int *grades = (int*) malloc(students_number * sizeof(int)); + if(grades == NULL) { + fprintf(stderr, "Erreur : malloc a échoué\n"); + exit(1); + } + + for(j = 0; j < students_number; j++) + { + grades[j] = students_array[j][i]; + } + + qiktri(grades, 0, students_number - 1); + + for(j = 0; j < students_number; j++) + { + students_rank[j][i] = find_rank_student(students_array[j][i], grades, students_number); + } + + free(grades); } } @@ -121,5 +134,4 @@ int main(int argc, char** argv) free(student_grades); free(student_ranks); return 0; -} - +} \ No newline at end of file