From e9a008de043988e0521d3df71f6f321c7ad6a821 Mon Sep 17 00:00:00 2001 From: Nicolas Floquet Date: Tue, 2 Mar 2021 17:03:12 +0100 Subject: [PATCH 01/16] =?UTF-8?q?2=20mars=20-=20Tout=20d=C3=A9but=20graphe?= =?UTF-8?q?=20fichier=20test=20=C3=A0=20continuer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pagerank/src/test_base.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 pagerank/src/test_base.py diff --git a/pagerank/src/test_base.py b/pagerank/src/test_base.py new file mode 100644 index 0000000..efa5826 --- /dev/null +++ b/pagerank/src/test_base.py @@ -0,0 +1,27 @@ +from scipy import sparse +from numpy.random import rand + +print("On crée une matrice creuse de taille 10x10, elle est initialement vide \nAffichons la") + +A = sparse.lil_matrix((10, 10)) + +print(A) +print("Rien ne s'est passé, car j'ai affiché une matrice creuse vide\n\ +Vide donc elle n'a que des 0\n\ +Donc rien ne s'est affiché\n\ +Pour rappel les 0 d'une matrice creuse ne sont pas stockés") + +A[0, :5] = rand(5) #5 coefficients +print("Des colonnes 0 à 4 à la ligne 0, on a ajouté des valeurs au hasard") + +print(A) + +A[1, 5:7] = A[0, :2] #2 nouveaux +print("Des colonnes 5 à 7 à la ligne 1, on a ajouté des valeurs au hasard") + +print(A) + +A.setdiag(rand(10)) #9 autres +print("On ajoute des nouvelles valeurs sur toutes la diagonale avec la fonction setdiag") + +print(A) # affichage type:'creux' 26 coefficients sur 100 non nuls -- GitLab From 56d653542890f526566a40c0e47fbc7e75467748 Mon Sep 17 00:00:00 2001 From: Nicolas Floquet Date: Mon, 8 Mar 2021 22:07:19 +0100 Subject: [PATCH 02/16] Pratiquement rien 08_03_21 --- pagerank/src/Fonctions_PageRank.py | 10 ++++++++++ pagerank/src/PageRank.py | 10 ++++++++++ pagerank/test/test_base.py | 27 +++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 pagerank/src/Fonctions_PageRank.py create mode 100644 pagerank/src/PageRank.py create mode 100644 pagerank/test/test_base.py diff --git a/pagerank/src/Fonctions_PageRank.py b/pagerank/src/Fonctions_PageRank.py new file mode 100644 index 0000000..f1e56a3 --- /dev/null +++ b/pagerank/src/Fonctions_PageRank.py @@ -0,0 +1,10 @@ +from scipy import sparse +from numpy.random import rand + + +def add_sommet(pagerank, URL): + #this.list_url[this.list_url.length] = url + +def add_arete(pagerank, i, j): + pagerank[i, j] = 1 + diff --git a/pagerank/src/PageRank.py b/pagerank/src/PageRank.py new file mode 100644 index 0000000..34dd495 --- /dev/null +++ b/pagerank/src/PageRank.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +class PageRank : + """Classe pour le pagerank : + -Graphe les liens (arêtes) entre les différentes URLs (sommets) + -liste_url une liste des différentes URLs (chaîne de char)""" + + def __init__(self, graphe, liste_url) : + """Constructeur PageRank""" + self.graphe = graphe + self.liste_url = liste_url diff --git a/pagerank/test/test_base.py b/pagerank/test/test_base.py new file mode 100644 index 0000000..efa5826 --- /dev/null +++ b/pagerank/test/test_base.py @@ -0,0 +1,27 @@ +from scipy import sparse +from numpy.random import rand + +print("On crée une matrice creuse de taille 10x10, elle est initialement vide \nAffichons la") + +A = sparse.lil_matrix((10, 10)) + +print(A) +print("Rien ne s'est passé, car j'ai affiché une matrice creuse vide\n\ +Vide donc elle n'a que des 0\n\ +Donc rien ne s'est affiché\n\ +Pour rappel les 0 d'une matrice creuse ne sont pas stockés") + +A[0, :5] = rand(5) #5 coefficients +print("Des colonnes 0 à 4 à la ligne 0, on a ajouté des valeurs au hasard") + +print(A) + +A[1, 5:7] = A[0, :2] #2 nouveaux +print("Des colonnes 5 à 7 à la ligne 1, on a ajouté des valeurs au hasard") + +print(A) + +A.setdiag(rand(10)) #9 autres +print("On ajoute des nouvelles valeurs sur toutes la diagonale avec la fonction setdiag") + +print(A) # affichage type:'creux' 26 coefficients sur 100 non nuls -- GitLab From 1e74f8c0b3a979b641555ec0f607f5e3773b896e Mon Sep 17 00:00:00 2001 From: Nicolas Floquet Date: Mon, 15 Mar 2021 22:05:19 +0100 Subject: [PATCH 03/16] FLOQUET_NICOLAS_Graphe_v02_C --- pagerank/src/Fonctions_PageRank.py | 10 - pagerank/src/PageRank.py | 10 - pagerank/src/graphe.c | 301 +++++++++++++++++++++++++++++ pagerank/src/graphe.h | 97 ++++++++++ pagerank/src/test_base.py | 27 --- 5 files changed, 398 insertions(+), 47 deletions(-) delete mode 100644 pagerank/src/Fonctions_PageRank.py delete mode 100644 pagerank/src/PageRank.py create mode 100644 pagerank/src/graphe.c create mode 100644 pagerank/src/graphe.h delete mode 100644 pagerank/src/test_base.py diff --git a/pagerank/src/Fonctions_PageRank.py b/pagerank/src/Fonctions_PageRank.py deleted file mode 100644 index f1e56a3..0000000 --- a/pagerank/src/Fonctions_PageRank.py +++ /dev/null @@ -1,10 +0,0 @@ -from scipy import sparse -from numpy.random import rand - - -def add_sommet(pagerank, URL): - #this.list_url[this.list_url.length] = url - -def add_arete(pagerank, i, j): - pagerank[i, j] = 1 - diff --git a/pagerank/src/PageRank.py b/pagerank/src/PageRank.py deleted file mode 100644 index 34dd495..0000000 --- a/pagerank/src/PageRank.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -class PageRank : - """Classe pour le pagerank : - -Graphe les liens (arêtes) entre les différentes URLs (sommets) - -liste_url une liste des différentes URLs (chaîne de char)""" - - def __init__(self, graphe, liste_url) : - """Constructeur PageRank""" - self.graphe = graphe - self.liste_url = liste_url diff --git a/pagerank/src/graphe.c b/pagerank/src/graphe.c new file mode 100644 index 0000000..8d752bc --- /dev/null +++ b/pagerank/src/graphe.c @@ -0,0 +1,301 @@ +#include +#include +#include "graphe.h" + + + +/** Fonction qui crée un graphe vide qui sera stocké à l'adresse g déjà allouée + * @param g un pointeur vers un graphe alloué en mémoire + * @param n le nombre strictement positif de cases des tableaux du graphe + * @requires n > 0 + * @return 0 si le graphe a été créé et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation + * O(n) + */ +int creer_graphe(graphe* g, int n) +{ + int i; + if(n <= 0) + { + printf("Erreur paramètre creer_graphe, n <= 0"); + return -1; + } + if(!(g->ligne = (int*) malloc(sizeof(int) * n))) + { + printf("Erreur allocation creer_graphe, g->ligne"); + return -2; + } + if(!(g->col = (int*) malloc(sizeof(int) * n))) + { + printf("Erreur allocation creer_graphe, g->col"); + free(g->ligne); + return -2; + } + g->max = n; + g->premierVide = 0; + for(i = 0; i < n; i++) + { + //printf("%d\n", i); + g->ligne[i] = -1; + g->col[i] = -1; + } + return 0; +} + + + +/** Libère la mémoire allouée dans un graphe, mais pas le graphe lui même (le pointeur donné en paramètre reste à libérer + * @param g un pointeur vers un graphe alloué en mémoire + */ +void graphe_detruire(graphe* g) +{ + if(g) + { + free(g->ligne); + free(g->col); + } +} + +/** Renvoie la taille maximale actuelle des tableaux du graphe g + * @param g un pointeur vers un graphe alloué en mémoire + * @return g->max un entier + * O(1) + */ +int get_max(graphe* g) +{ + return g->max; +} + + +/** Renvoie l'indice du premier (-1 -1) dans le graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @return g->premierVide un entier + * O(1) + */ +int get_premier_vide(graphe* g) +{ + return g->premierVide; +} + + +/** Renvoie le plus grand indice des sommets du graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @return un entier + * O(n) + */ +int get_plus_grand_sommet(graphe* g) +{ + int i, tmp, res = -1; + if(g) + { + for(i = 0; i < get_max(g); i++) + { + tmp = max(g->ligne[i], g->col[i]); + if(tmp > res) + { + res = tmp; + } + } + } + return res; +} + + +/** Ajoute une arête entre les sommets i et j du graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param i un des sommets de l'arête + * @param j un des sommets de l'arête + */ +void ajouter_arete(graphe *g, int i, int j) +{ + if(g) + { + if(get_premier_vide(g) == get_max(g)) + { + g->max *= 2; + g->ligne = realloc(g->ligne, g->max * sizeof(int)); + g->col = realloc(g->col, g->max * sizeof(int)); + for(int i = get_premier_vide(g); i < get_max(g); i++) + { + g->ligne[i] = -1; + g->col[i] = -1; + } + } + g->ligne[get_premier_vide(g)] = i; + g->col[get_premier_vide(g)] = j; + g->premierVide++; + } + //printf("ajouter_arete dans un graphe vide\n"); +} + + +/** Supprime une arête entre les sommets i et j du graphe (ou j et i) + * @param g un pointeur vers un graphe alloué en mémoire + * @param i un des sommets de l'arête + * @param j un des sommets de l'arête + * O(n) + */ +void supprimer_arete(graphe *g, int i, int j) +{ + if(g) + { + int cpt, flag = 0; + for(cpt = 0; cpt < get_premier_vide(g); cpt++) + { + if(flag) + { //On a trouvé l'arête et on l'a enlevée, donc maintenant il suffit de décaler le reste d'une case à gauche + g->ligne[cpt] = g->ligne[cpt+1]; + g->col[cpt] = g->col[cpt+1]; + } + else + { + if((g->ligne[cpt] == i && g->col[cpt] == j) || (g->ligne[cpt] == j && g->col[cpt] == i)) + { + flag = 1; + g->ligne[cpt] = g->ligne[cpt+1]; + g->col[cpt] = g->col[cpt+1]; + } + } + } + if(flag) + { + g->premierVide--; + } + } + //printf("ajouter_arete dans un graphe vide\n"); +} + + +/** Retire un sommet du graphe, assure qu'aucun sommet n'a d'arête allant vers ce dernier et qu'aucune arête ne part de celui ci. + * Puis les sommets supérieurs sont renommés, ex : si x = 5, 6->5, 7->6 etc + * @param g un pointeur vers un graphe alloué en mémoire + * @param x le sommet à retirer + * O(n) + */ +void retirer_sommet(graphe* g, int x) +{ + if(g) + { + int n = get_plus_grand_sommet(g), i; + if(x >= 0 && x < n) + { + int nbCasesVides = 0, *casesVides = (int*) calloc(sizeof(int), get_max(g)); + if(!casesVides) + { + printf("Erreur allocation retirer_sommet (tableau casesVides)\n"); + return; + } + for(i=0; i < get_max(g); i++) + { + casesVides[i]--; + } + for(i=0; i < get_max(g); i++) + { + if(g->ligne[i] == x || g->col[i] == x) + { //Une arête part de x, ou arrive en x, on retire le sommet donc tout part + g->ligne[i] = -1; + g->col[i] = -1; + casesVides[nbCasesVides++] = i; + } + else + { // Rien n'est supprimé, mais les indices des sommets > x sont décrémentés + if(g->ligne[i] > x) + { + g->ligne[i]--; + } + if(g->col[i] > x) + { + g->col[i]--; + } + } + } + g->premierVide -= nbCasesVides; + //Maintenant on a aucune trace du sommet x, mais plein de (-1 -1) où il était (ATTENTION ON PEUT ENCORE VOIR DES SOMMETS X, MAIS CE SONT LES ANCIENS SOMMETS X+1, CECI N'EST PAS UN BUG, NE PAS DÉBUGGER) + //Il faut retasser tout ça + + for(i = get_max(g) - 1; i >= 0 && nbCasesVides; i--) + { + if(g->ligne[i] != -1) + { //Pas une case vide, donc on peut l'échanger avec une case vide + g->ligne[casesVides[nbCasesVides-1]] = g->ligne[i]; + g->col[casesVides[nbCasesVides-1]] = g->col[i]; + nbCasesVides--; + g->ligne[i] = -1; + g->col[i] = -1; + } + } + free(casesVides); + } + //printf("retirer_sommet hors limites [0; n-1]\n"); + } + //printf("retirer_sommet dans un graphe vide\n"); +} + + +void graphe_afficher(graphe* g) +{ + if(g) + { + printf("Graphe à %d arêtes\n", get_premier_vide(g)); + int lim = get_plus_grand_sommet(g)+1, i, v, w; + int* matrice = (int*) calloc(sizeof(int), lim * lim); + if(!matrice) + { + printf("Erreur allocation graphe_afficher \n"); + return; + } + for(i = 0; i < g->premierVide; i++) + { + matrice[g->ligne[i] * lim + g->col[i]]++; + matrice[g->col[i] * lim + g->ligne[i]]++; + } + /* matrice d'adjacence faite */ + /* ligne indices colonnes */ + printf("\t\t"); + for (w = 0 ; w < lim ; w++) + { + printf("%d\t", w); + } + printf("\n"); + + printf("\t\t"); + for (w = 0 ; w < lim ; w++) + { + printf("_\t"); + } + printf("\n"); + + /* lignes de la matrice */ + for (v = 0 ; v < lim ; v++) + { + printf("%d\t|\t", v); + for (w = 0 ; w < lim ; w++) + { + printf("%d\t", matrice[v * lim + w]); + } + printf("|\n"); + } + printf("\t\t"); + for (w = 0 ; w < lim ; w++) + { + printf("_\t"); + } + printf("\n"); + free(matrice); + } + else + { + printf("Erreur graphe_afficher Le graphe est NULL\n"); + } +} + + +/** Renvoie le maximum entre 2 entiers + * @param x un entier + * @param y un entier + * @return un entier, le plus grand des 2 paramètres + * O(1) + */ +int max(int x, int y) +{ + return (x > y) ? x : y; +} diff --git a/pagerank/src/graphe.h b/pagerank/src/graphe.h new file mode 100644 index 0000000..d94e477 --- /dev/null +++ b/pagerank/src/graphe.h @@ -0,0 +1,97 @@ +#ifndef GRAPHE_H +#define GRAPHE_H + + +struct s_graphe { + int max; // Longueur de chacun des tableaux + int premierVide; // Indice du premier (-1 -1) + int *ligne; // Indices i {-1 si non défini, entre 0 et n-1 sinon} + int *col; // Indices j {-1 si non défini, entre 0 et n-1 sinon} +}; +typedef struct s_graphe graphe; + +/** Fonction qui crée un graphe vide qui sera stocké à l'adresse g déjà allouée + * @param g un pointeur vers un graphe alloué en mémoire + * @param n le nombre strictement positif de cases des tableaux du graphe + * @requires n > 0 + * @return 0 si le graphe a été créé et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation + * O(n) + */ +int creer_graphe(graphe* g, int n); + + +/** Libère la mémoire allouée dans un graphe, mais pas le graphe lui même (le pointeur donné en paramètre reste à libérer + * @param g un pointeur vers un graphe alloué en mémoire + * O(n); + */ +void graphe_detruire(graphe* g); + + +/** Renvoie la taille maximale actuelle des tableaux du graphe g + * @param g un pointeur vers un graphe alloué en mémoire + * @return g->max un entier + * O(1) + */ +int get_max(graphe* g); + + +/** Renvoie l'indice du premier (-1 -1) dans le graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @return g->premierVide un entier + * O(1) + */ +int get_premier_vide(graphe* g); + + +/** Renvoie le plus grand indice des sommets du graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @return un entier + * O(n) + */ +int get_plus_grand_sommet(graphe* g); + + +/** Ajoute une arête entre les sommets i et j du graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param i un des sommets de l'arête + * @param j un des sommets de l'arête + * O(1) + */ +void ajouter_arete(graphe *g, int i, int j); + + +/** Supprime une arête entre les sommets i et j du graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param i un des sommets de l'arête + * @param j un des sommets de l'arête + * O(n) + */ +void supprimer_arete(graphe *g, int i, int j); + + +/** Retire un sommet du graphe, assure qu'aucun sommet n'a d'arête allant vers ce dernier et qu'aucune arête ne part de celui ci. + * Puis les sommets supérieurs sont renommés, ex : si x = 5, 6->5, 7->6 etc + * @param g un pointeur vers un graphe alloué en mémoire + * @param x le sommet à retirer + * O(n) + */ +void retirer_sommet(graphe* g, int x); + + +void graphe_afficher(graphe* g); + + +/** Renvoie le maximum entre 2 entiers + * @param x un entier + * @param y un entier + * @return un entier, le plus grand des 2 paramètres + * O(1) + */ +int max(int x, int y); + + +//afficher tableaux +//2 sommets sont-ils connectés? (valeur > 0) + + +#endif diff --git a/pagerank/src/test_base.py b/pagerank/src/test_base.py deleted file mode 100644 index efa5826..0000000 --- a/pagerank/src/test_base.py +++ /dev/null @@ -1,27 +0,0 @@ -from scipy import sparse -from numpy.random import rand - -print("On crée une matrice creuse de taille 10x10, elle est initialement vide \nAffichons la") - -A = sparse.lil_matrix((10, 10)) - -print(A) -print("Rien ne s'est passé, car j'ai affiché une matrice creuse vide\n\ -Vide donc elle n'a que des 0\n\ -Donc rien ne s'est affiché\n\ -Pour rappel les 0 d'une matrice creuse ne sont pas stockés") - -A[0, :5] = rand(5) #5 coefficients -print("Des colonnes 0 à 4 à la ligne 0, on a ajouté des valeurs au hasard") - -print(A) - -A[1, 5:7] = A[0, :2] #2 nouveaux -print("Des colonnes 5 à 7 à la ligne 1, on a ajouté des valeurs au hasard") - -print(A) - -A.setdiag(rand(10)) #9 autres -print("On ajoute des nouvelles valeurs sur toutes la diagonale avec la fonction setdiag") - -print(A) # affichage type:'creux' 26 coefficients sur 100 non nuls -- GitLab From a1f26453360e871da94668e5db39ec5203b9e2d5 Mon Sep 17 00:00:00 2001 From: Nicolas Floquet Date: Mon, 15 Mar 2021 22:07:17 +0100 Subject: [PATCH 04/16] FLOQUET_NICOLAS_Graphe_v03_avec_test_graphe --- pagerank/test/Makefile | 12 ++++++++++++ pagerank/test/test-graphe.c | 39 +++++++++++++++++++++++++++++++++++++ pagerank/test/test_base.py | 27 ------------------------- 3 files changed, 51 insertions(+), 27 deletions(-) create mode 100644 pagerank/test/Makefile create mode 100644 pagerank/test/test-graphe.c delete mode 100644 pagerank/test/test_base.py diff --git a/pagerank/test/Makefile b/pagerank/test/Makefile new file mode 100644 index 0000000..2abbb88 --- /dev/null +++ b/pagerank/test/Makefile @@ -0,0 +1,12 @@ +CC= gcc +CXXFLAGS= -Wall --pedantic -O3 + +CPP_O_FILE = test-graphe.o +LIB = -lm + + +all: $(CPP_O_FILE) + $(CC) $(CXXFLAGS) -o test-graphe.exe test-graphe.c ../src/graphe.c $(LIB) + +clean: + rm -rf *.o *.exe diff --git a/pagerank/test/test-graphe.c b/pagerank/test/test-graphe.c new file mode 100644 index 0000000..9377a34 --- /dev/null +++ b/pagerank/test/test-graphe.c @@ -0,0 +1,39 @@ +#include +#include +#include "../src/graphe.h" + +#define NB_SOMMETS 7 + +int main() +{ + graphe g; + creer_graphe(&g, NB_SOMMETS); + ajouter_arete(&g, 0, 1); + ajouter_arete(&g, 0, 9); + ajouter_arete(&g, 1, 3); + ajouter_arete(&g, 1, 2); + ajouter_arete(&g, 1, 4); + ajouter_arete(&g, 2, 4); + ajouter_arete(&g, 3, 4); + ajouter_arete(&g, 3, 5); + ajouter_arete(&g, 4, 5); + ajouter_arete(&g, 4, 6); + ajouter_arete(&g, 5, 6); + + graphe_afficher(&g); + + printf("Retirons le sommet 4 (un nouveau sommet 4 prendra sa place\n"); + + retirer_sommet(&g, 4); + + printf("Retirons les arêtes 4-5, 1-3, et 5-4 (déjà retirée)\n"); + supprimer_arete(&g, 4, 5); + graphe_afficher(&g); + supprimer_arete(&g, 1, 3); + graphe_afficher(&g); + supprimer_arete(&g, 5, 4); + graphe_afficher(&g); + + graphe_detruire(&g); + return EXIT_SUCCESS; +} diff --git a/pagerank/test/test_base.py b/pagerank/test/test_base.py deleted file mode 100644 index efa5826..0000000 --- a/pagerank/test/test_base.py +++ /dev/null @@ -1,27 +0,0 @@ -from scipy import sparse -from numpy.random import rand - -print("On crée une matrice creuse de taille 10x10, elle est initialement vide \nAffichons la") - -A = sparse.lil_matrix((10, 10)) - -print(A) -print("Rien ne s'est passé, car j'ai affiché une matrice creuse vide\n\ -Vide donc elle n'a que des 0\n\ -Donc rien ne s'est affiché\n\ -Pour rappel les 0 d'une matrice creuse ne sont pas stockés") - -A[0, :5] = rand(5) #5 coefficients -print("Des colonnes 0 à 4 à la ligne 0, on a ajouté des valeurs au hasard") - -print(A) - -A[1, 5:7] = A[0, :2] #2 nouveaux -print("Des colonnes 5 à 7 à la ligne 1, on a ajouté des valeurs au hasard") - -print(A) - -A.setdiag(rand(10)) #9 autres -print("On ajoute des nouvelles valeurs sur toutes la diagonale avec la fonction setdiag") - -print(A) # affichage type:'creux' 26 coefficients sur 100 non nuls -- GitLab From 3541ccdf382ae86b74d6ba3a80658d00edc6d86e Mon Sep 17 00:00:00 2001 From: Nicolas Floquet Date: Fri, 19 Mar 2021 22:00:22 +0100 Subject: [PATCH 05/16] =?UTF-8?q?Graphe=20et=20Liste=5FURL=20suite=20PageR?= =?UTF-8?q?ank=20d=C3=A9but?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pagerank/src/graphe.c | 196 +++++++++++++++++++++++++++----- pagerank/src/graphe.h | 66 +++++++++-- pagerank/src/liste_url.c | 216 ++++++++++++++++++++++++++++++++++++ pagerank/src/liste_url.h | 95 ++++++++++++++++ pagerank/src/pagerank.c | 153 +++++++++++++++++++++++++ pagerank/src/pagerank.h | 72 ++++++++++++ pagerank/test/Makefile | 3 +- pagerank/test/test-graphe.c | 49 +++++--- pagerank/test/test-liste.c | 29 +++++ 9 files changed, 825 insertions(+), 54 deletions(-) create mode 100644 pagerank/src/liste_url.c create mode 100644 pagerank/src/liste_url.h create mode 100644 pagerank/src/pagerank.c create mode 100644 pagerank/src/pagerank.h create mode 100644 pagerank/test/test-liste.c diff --git a/pagerank/src/graphe.c b/pagerank/src/graphe.c index 8d752bc..b01e43f 100644 --- a/pagerank/src/graphe.c +++ b/pagerank/src/graphe.c @@ -16,17 +16,17 @@ int creer_graphe(graphe* g, int n) int i; if(n <= 0) { - printf("Erreur paramètre creer_graphe, n <= 0"); + printf("Erreur paramètre creer_graphe, n <= 0\n"); return -1; } if(!(g->ligne = (int*) malloc(sizeof(int) * n))) { - printf("Erreur allocation creer_graphe, g->ligne"); + printf("Erreur allocation creer_graphe, g->ligne\n"); return -2; } if(!(g->col = (int*) malloc(sizeof(int) * n))) { - printf("Erreur allocation creer_graphe, g->col"); + printf("Erreur allocation creer_graphe, g->col\n"); free(g->ligne); return -2; } @@ -55,12 +55,13 @@ void graphe_detruire(graphe* g) } } + /** Renvoie la taille maximale actuelle des tableaux du graphe g * @param g un pointeur vers un graphe alloué en mémoire * @return g->max un entier * O(1) */ -int get_max(graphe* g) +int graphe_get_max(graphe* g) { return g->max; } @@ -71,23 +72,58 @@ int get_max(graphe* g) * @return g->premierVide un entier * O(1) */ -int get_premier_vide(graphe* g) +int graphe_get_premier_vide(graphe* g) { return g->premierVide; } +/** Indique si un sommet est dans le graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un entier, le sommet dont on veut savoir s'il est dans le graphe + * @return 1 si le sommet est dans le graphe et 0 sinon + * O(n) + */ +int graphe_contains(graphe* g, int u) +{ + return (graphe_find(g, u) != -1); +} + + +/** Donne l'indice de la première occurence d'un sommet dans le graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un entier, le sommet dont on veut connaître l'indice dans le graphe + * @return l'indice de le sommet si il est dans le graphe et -1 sinon + * O(n) + */ +int graphe_find(graphe* g, int u) +{ + if(g && u >= 0 && u <= graphe_get_plus_grand_sommet(g)) + { + int i; + for(i = 0; i < graphe_get_premier_vide(g); i++) + { + if(g->ligne[i] == u || g->col[i] == u) + { + return i; + } + } + } + return -1; +} + + /** Renvoie le plus grand indice des sommets du graphe * @param g un pointeur vers un graphe alloué en mémoire * @return un entier * O(n) */ -int get_plus_grand_sommet(graphe* g) +int graphe_get_plus_grand_sommet(graphe* g) { int i, tmp, res = -1; if(g) { - for(i = 0; i < get_max(g); i++) + for(i = 0; i < graphe_get_max(g); i++) { tmp = max(g->ligne[i], g->col[i]); if(tmp > res) @@ -105,26 +141,26 @@ int get_plus_grand_sommet(graphe* g) * @param i un des sommets de l'arête * @param j un des sommets de l'arête */ -void ajouter_arete(graphe *g, int i, int j) +void graphe_ajouter_arete(graphe* g, int i, int j) { if(g) { - if(get_premier_vide(g) == get_max(g)) + if(graphe_get_premier_vide(g) == graphe_get_max(g)) { g->max *= 2; g->ligne = realloc(g->ligne, g->max * sizeof(int)); g->col = realloc(g->col, g->max * sizeof(int)); - for(int i = get_premier_vide(g); i < get_max(g); i++) + for(int i = graphe_get_premier_vide(g); i < graphe_get_max(g); i++) { g->ligne[i] = -1; g->col[i] = -1; } } - g->ligne[get_premier_vide(g)] = i; - g->col[get_premier_vide(g)] = j; + g->ligne[graphe_get_premier_vide(g)] = i; + g->col[graphe_get_premier_vide(g)] = j; g->premierVide++; } - //printf("ajouter_arete dans un graphe vide\n"); + //printf("graphe_ajouter_arete dans un graphe vide\n"); } @@ -134,12 +170,12 @@ void ajouter_arete(graphe *g, int i, int j) * @param j un des sommets de l'arête * O(n) */ -void supprimer_arete(graphe *g, int i, int j) +void graphe_supprimer_arete(graphe* g, int i, int j) { if(g) { int cpt, flag = 0; - for(cpt = 0; cpt < get_premier_vide(g); cpt++) + for(cpt = 0; cpt < graphe_get_premier_vide(g); cpt++) { if(flag) { //On a trouvé l'arête et on l'a enlevée, donc maintenant il suffit de décaler le reste d'une case à gauche @@ -161,7 +197,7 @@ void supprimer_arete(graphe *g, int i, int j) g->premierVide--; } } - //printf("ajouter_arete dans un graphe vide\n"); + //printf("graphe_supprimer_arete dans un graphe vide\n"); } @@ -171,24 +207,24 @@ void supprimer_arete(graphe *g, int i, int j) * @param x le sommet à retirer * O(n) */ -void retirer_sommet(graphe* g, int x) +void graphe_retirer_sommet(graphe* g, int x) { if(g) { - int n = get_plus_grand_sommet(g), i; + int n = graphe_get_plus_grand_sommet(g), i; if(x >= 0 && x < n) { - int nbCasesVides = 0, *casesVides = (int*) calloc(sizeof(int), get_max(g)); + int nbCasesVides = 0, *casesVides = (int*) calloc(sizeof(int), graphe_get_max(g)); if(!casesVides) { - printf("Erreur allocation retirer_sommet (tableau casesVides)\n"); + printf("Erreur allocation graphe_retirer_sommet (tableau casesVides)\n"); return; } - for(i=0; i < get_max(g); i++) + for(i=0; i < graphe_get_max(g); i++) { casesVides[i]--; } - for(i=0; i < get_max(g); i++) + for(i=0; i < graphe_get_max(g); i++) { if(g->ligne[i] == x || g->col[i] == x) { //Une arête part de x, ou arrive en x, on retire le sommet donc tout part @@ -212,7 +248,7 @@ void retirer_sommet(graphe* g, int x) //Maintenant on a aucune trace du sommet x, mais plein de (-1 -1) où il était (ATTENTION ON PEUT ENCORE VOIR DES SOMMETS X, MAIS CE SONT LES ANCIENS SOMMETS X+1, CECI N'EST PAS UN BUG, NE PAS DÉBUGGER) //Il faut retasser tout ça - for(i = get_max(g) - 1; i >= 0 && nbCasesVides; i--) + for(i = graphe_get_max(g) - 1; i >= 0 && nbCasesVides; i--) { if(g->ligne[i] != -1) { //Pas une case vide, donc on peut l'échanger avec une case vide @@ -225,18 +261,82 @@ void retirer_sommet(graphe* g, int x) } free(casesVides); } - //printf("retirer_sommet hors limites [0; n-1]\n"); + //printf("graphe_retirer_sommet hors limites [0; n-1]\n"); + } + //printf("graphe_retirer_sommet dans un graphe vide\n"); +} + + +/** Indique si 2 sommets sont adjacents ou non, s'il existe une arête les reliant + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un des sommets de l'arête + * @param v un des sommets de l'arête + * @return 1 si les sommets sont adjacents et 0 sinon + * O(n) + */ +int graphe_voisins(graphe* g, int u, int v) +{ + if(g) + { + int max = graphe_get_plus_grand_sommet(g); + if(u >= 0 && v >= 0 && u <= max && v <= max) + { + int i; + for(i = 0; i < graphe_get_premier_vide(g); i++) + { + if(g->ligne[i] == u && g->col[i] == v) + { + return 1; + } + if(g->ligne[i] == v && g->col[i] == u) + { + return 1; + } + } + } + } + return 0; +} + + +/** Indique si 1 sommet est successeur d'un autre ou non + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un des sommets de l'arête + * @param v un des sommets de l'arête + * @return 1 si v est un successeur de u et 0 sinon + * O(n) + */ +int graphe_est_succ(graphe* g, int u, int v) +{ + if(g) + { + int max = graphe_get_plus_grand_sommet(g); + if(u >= 0 && v >= 0 && u <= max && v <= max) + { + int i; + for(i = 0; i < graphe_get_premier_vide(g); i++) + { + if(g->ligne[i] == u && g->col[i] == v) + { + return 1; + } + } + } } - //printf("retirer_sommet dans un graphe vide\n"); + return 0; } +/** Affiche le graphe sous la forme d'une matrice d'adjacence + * @param g un pointeur vers un graphe alloué en mémoire + * O(n) + */ void graphe_afficher(graphe* g) { if(g) { - printf("Graphe à %d arêtes\n", get_premier_vide(g)); - int lim = get_plus_grand_sommet(g)+1, i, v, w; + printf("Graphe à %d arêtes\n", graphe_get_premier_vide(g)); + int lim = graphe_get_plus_grand_sommet(g)+1, i, v, w; int* matrice = (int*) calloc(sizeof(int), lim * lim); if(!matrice) { @@ -289,6 +389,48 @@ void graphe_afficher(graphe* g) } +/** Affiche le graphe sous la forme des 2 tableaux le composant + * @param g un pointeur vers un graphe alloué en mémoire + * O(n) + */ +void graphe_afficher_tableaux(graphe* g) +{ + int i; + printf("\n======================"); + printf("\nIndices\t\t"); + for (i = 0; i < graphe_get_max(g); i++) + { + printf("| %2d ", i); + } + printf("\n\nlignes :\t"); + for (i = 0; i < graphe_get_max(g); i++) + { + if(i < graphe_get_premier_vide(g)) + { + printf("| %2d ", g->ligne[i]); + } + else + { //Il ne devrait y avoir que des (-1) + printf("| (%d) ", g->ligne[i]); + } + } + printf("\ncolonnes :\t"); + for (i = 0; i < graphe_get_max(g); i++) + { + if(i < graphe_get_premier_vide(g)) + { + printf("| %2d ", g->col[i]); + } + else + { //Il ne devrait y avoir que des (-1) + printf("| (%d) ", g->col[i]); + } + } + printf("\n======================"); + printf("\n\n"); +} + + /** Renvoie le maximum entre 2 entiers * @param x un entier * @param y un entier diff --git a/pagerank/src/graphe.h b/pagerank/src/graphe.h index d94e477..ee77415 100644 --- a/pagerank/src/graphe.h +++ b/pagerank/src/graphe.h @@ -32,7 +32,7 @@ void graphe_detruire(graphe* g); * @return g->max un entier * O(1) */ -int get_max(graphe* g); +int graphe_get_max(graphe* g); /** Renvoie l'indice du premier (-1 -1) dans le graphe @@ -40,7 +40,25 @@ int get_max(graphe* g); * @return g->premierVide un entier * O(1) */ -int get_premier_vide(graphe* g); +int graphe_get_premier_vide(graphe* g); + + +/** Indique si un sommet est dans le graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un entier, le sommet dont on veut savoir s'il est dans le graphe + * @return 1 si le sommet est dans le graphe et 0 sinon + * O(n) + */ +int graphe_contains(graphe* g, int u); + + +/** Donne l'indice de la première occurence d'un sommet dans le graphe + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un entier, le sommet dont on veut connaître l'indice dans le graphe + * @return l'indice de le sommet si il est dans le graphe et -1 sinon + * O(n) + */ +int graphe_find(graphe* g, int u); /** Renvoie le plus grand indice des sommets du graphe @@ -48,7 +66,7 @@ int get_premier_vide(graphe* g); * @return un entier * O(n) */ -int get_plus_grand_sommet(graphe* g); +int graphe_get_plus_grand_sommet(graphe* g); /** Ajoute une arête entre les sommets i et j du graphe @@ -57,7 +75,7 @@ int get_plus_grand_sommet(graphe* g); * @param j un des sommets de l'arête * O(1) */ -void ajouter_arete(graphe *g, int i, int j); +void graphe_ajouter_arete(graphe* g, int i, int j); /** Supprime une arête entre les sommets i et j du graphe @@ -66,7 +84,7 @@ void ajouter_arete(graphe *g, int i, int j); * @param j un des sommets de l'arête * O(n) */ -void supprimer_arete(graphe *g, int i, int j); +void graphe_supprimer_arete(graphe* g, int i, int j); /** Retire un sommet du graphe, assure qu'aucun sommet n'a d'arête allant vers ce dernier et qu'aucune arête ne part de celui ci. @@ -75,12 +93,43 @@ void supprimer_arete(graphe *g, int i, int j); * @param x le sommet à retirer * O(n) */ -void retirer_sommet(graphe* g, int x); +void graphe_retirer_sommet(graphe* g, int x); + + +/** Indique si 2 sommets sont adjacents ou non, s'il existe une arête les reliant + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un des sommets de l'arête + * @param v un des sommets de l'arête + * @return 1 si les sommets sont adjacents et 0 sinon + * O(n) + */ +int graphe_voisins(graphe* g, int u, int v); +/** Indique si 1 sommet est successeur d'un autre ou non + * @param g un pointeur vers un graphe alloué en mémoire + * @param u un des sommets de l'arête + * @param v un des sommets de l'arête + * @return 1 si v est un successeur de u et 0 sinon + * O(n) + */ +int graphe_est_succ(graphe* g, int u, int v); + + +/** Affiche le graphe sous la forme d'une matrice d'adjacence + * @param g un pointeur vers un graphe alloué en mémoire + * O(n) + */ void graphe_afficher(graphe* g); +/** Affiche le graphe sous la forme des 2 tableaux le composant + * @param g un pointeur vers un graphe alloué en mémoire + * O(n) + */ +void graphe_afficher_tableaux(graphe* g); + + /** Renvoie le maximum entre 2 entiers * @param x un entier * @param y un entier @@ -89,9 +138,4 @@ void graphe_afficher(graphe* g); */ int max(int x, int y); - -//afficher tableaux -//2 sommets sont-ils connectés? (valeur > 0) - - #endif diff --git a/pagerank/src/liste_url.c b/pagerank/src/liste_url.c new file mode 100644 index 0000000..dbf7df7 --- /dev/null +++ b/pagerank/src/liste_url.c @@ -0,0 +1,216 @@ +#include +#include +#include +#include "liste_url.h" + + +/** Fonction qui crée une liste d'url qui est stockée à l'adresse donnée en argument, déjà allouée, la liste aura déjà n cases pour stocker des URLs (c'est un tableau dynamique, sa taille pourra être amenée à augmenter) + * @param l une liste d'url allouée en mémoire + * @param n un entier strictement positif, la taille de la liste + * @return 0 si la liste a été créée et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation + * O(n) + */ +int creer_liste(liste_url* l, int n) +{ + if(n <= 0) + { + printf("Erreur paramètre creer_liste, n <= 0\n"); + return -1; + } + if(!(l->urls = (char**) calloc(sizeof(char*), n))) + { + printf("Erreur allocation creer_liste, l->urls\n"); + return -2; + } + l->max = n; + l->premierNULL = 0; + return 0; +} + + +/** Renvoie la taille maximale actuelle de la liste l + * @param l un pointeur vers une liste allouée en mémoire + * @return g->max un entier + * O(1) + */ +int liste_get_max(liste_url* l) +{ + return l->max; +} + + +/** Renvoie l'indice du premier NULL dans le liste + * @param l un pointeur vers une liste allouée en mémoire + * @return l->premierNULL un entier + * O(1) + */ +int liste_get_premier_NULL(liste_url* l) +{ + return l->premierNULL; +} + + +/** Indique si une url est dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL dont on veut savoir si elle est dans la liste + * @return 1 si l'URL est dans la liste et 0 sinon + * O(n) + */ +int liste_contains(liste_url* l, char* s) +{ + return (liste_find(l, s) != -1); +} + + +/** Donne l'indice d'une url est dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL dont on veut connaître l'indice dans la liste + * @return l'indice de l'URL si elle est dans la liste et -1 sinon + * O(n) + */ +int liste_find(liste_url* l, char* s) +{ + if(l && s) + { + int i; + for(i = 0; i < liste_get_premier_NULL(l); i++) + { + if(!strcmp(s, liste_get_i(l, i))) + { + return i; + } + } + } + return -1; +} + + +/** Renvoie l'url à l'indice i dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param i un entier + * @return l->urls[i] un entier si 0 <= i < liste_get_max(l), NULL sinon + * O(1) + */ +char* liste_get_i(liste_url* l, int i) +{ + if(0 <= i && i < liste_get_max(l)) + { + return l->urls[i]; + } + return NULL; +} + + +/** Ajoute une url à la première case vide dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL à ajouter + * O(1) + */ +void liste_add(liste_url* l, char* s) +{ + if(l) + { + if(liste_get_premier_NULL(l) == liste_get_max(l)) + { //Réallocation si nécessaire, complexité amortie en temps linéaire + l->max *= 2; + char** nouvelleListe = (char**) calloc(sizeof(char*), liste_get_max(l)); + + for (int i = 0; i < liste_get_premier_NULL(l); i++) + { + nouvelleListe[i] = (char*) malloc(sizeof(char) * (strlen(l->urls[i]) + 1)); + strcpy(nouvelleListe[i], l->urls[i]); + free(l->urls[i]); + } + nouvelleListe[l->premierNULL] = (char*) calloc(sizeof(char), strlen(s)+1); + strcpy(nouvelleListe[l->premierNULL++], s); + free(l->urls); + l->urls = nouvelleListe; + return; + } + l->urls[l->premierNULL] = (char*) calloc(sizeof(char), strlen(s)+1); + strcpy(l->urls[l->premierNULL++], s); + } +} + + +/** Retire une url de la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL à retirer + * O(n) + */ +void liste_remove(liste_url* l, char* s) +{ + if(l && s) + { + int i, trouve = 0; + for(i = 0; i < liste_get_premier_NULL(l); i++) + { + if(!trouve && (!strcmp(s, liste_get_i(l, i)))) + { + free(liste_get_i(l, i)); + l->urls[i] = l->urls[i+1]; + trouve = 1; + } + else if(trouve) + { + if(i+1 < liste_get_max(l)) + { + l->urls[i] = l->urls[i+1]; + } + else + { + l->urls[i] = NULL; + } + } + } + l->premierNULL--; + } +} + + +/** Libère la mémoire allouée dans une liste et toutes les chaînes contenues dedans + * @param l une liste d'url allouée en mémoire + * O(n) + */ +void liste_detruire(liste_url* l) +{ + if(l) + { + int i; + for(i = 0; i < liste_get_premier_NULL(l); i++) + { + free(l->urls[i]); + l->urls[i] = NULL; + } + free(l->urls); + } +} + + +/** Affiche la liste d'URLs + * @param l un pointeur vers une liste allouée en mémoire + * O(n) + */ +void liste_afficher(liste_url* l) +{ + if(l) + { + int i, n = liste_get_max(l); + printf("i\t|\tURLs:\n"); + for(i = 0; i < n; i++) + { + if(i < liste_get_premier_NULL(l)) + { + printf("%d \t|\t\"%s\"\n", i, liste_get_i(l, i)); + } + else + { + printf("%d \t|\tNULL\n", i); + } + } + } + else + { + printf("La liste est NULL\n"); + } +} diff --git a/pagerank/src/liste_url.h b/pagerank/src/liste_url.h new file mode 100644 index 0000000..b18dd53 --- /dev/null +++ b/pagerank/src/liste_url.h @@ -0,0 +1,95 @@ +#ifndef LISTE_URL_H +#define LISTE_URL_H + + +struct s_liste_url { + int max; // Longueur de la liste allouée + int premierNULL; // Indice de la première chaîne NULL + char** urls; // Les urls de la liste +}; +typedef struct s_liste_url liste_url; + + +/** Fonction qui crée une liste d'url qui est stockée à l'adresse donnée en argument, déjà allouée, la liste aura déjà n cases pour stocker des URLs (c'est un tableau dynamique, sa taille pourra être amenée à augmenter) + * @param l une liste d'url allouée en mémoire + * @param n un entier strictement positif, la taille de la liste + * @return 0 si la liste a été créée et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation + * O(n) + */ +int creer_liste(liste_url* l, int n); + + +/** Renvoie la taille maximale actuelle de la liste l + * @param l un pointeur vers une liste allouée en mémoire + * @return g->max un entier + * O(1) + */ +int liste_get_max(liste_url* l); + + +/** Renvoie l'indice du premier NULL dans le liste + * @param l un pointeur vers une liste allouée en mémoire + * @return l->premierNULL un entier + * O(1) + */ +int liste_get_premier_NULL(liste_url* l); + + +/** Indique si une url est dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL dont on veut savoir si elle est dans la liste + * @return 1 si l'URL est dans la liste et 0 sinon + * O(n) + */ +int liste_contains(liste_url* l, char* s); + + +/** Donne l'indice d'une url est dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL dont on veut connaître l'indice dans la liste + * @return l'indice de l'URL si elle est dans la liste et -1 sinon + * O(n) + */ +int liste_find(liste_url* l, char* s); + + +/** Renvoie l'url à l'indice i dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param i un entier + * @return l->urls[i] un entier si 0 <= i < liste_get_max(l), NULL sinon + * O(1) + */ +char* liste_get_i(liste_url* l, int i); + + +/** Ajoute une url à la première case vide dans la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL à ajouter + * O(1) + */ +void liste_add(liste_url* l, char* s); + + +/** Retire une url de la liste + * @param l un pointeur vers une liste allouée en mémoire + * @param s une chaîne, l'URL à retirer + * O(n) + */ +void liste_remove(liste_url* l, char* s); + + + +/** Libère la mémoire allouée dans une liste et toutes les chaînes contenues dedans + * @param l une liste d'url allouée en mémoire + * O(n) + */ +void liste_detruire(liste_url* l); + + +/** Affiche la liste d'URLs + * @param l un pointeur vers une liste allouée en mémoire + * O(n) + */ +void liste_afficher(liste_url* l); + +#endif diff --git a/pagerank/src/pagerank.c b/pagerank/src/pagerank.c new file mode 100644 index 0000000..37c8087 --- /dev/null +++ b/pagerank/src/pagerank.c @@ -0,0 +1,153 @@ +#include +#include +#include "pagerank.h" + +/** Fonction qui crée un pagerank pour n URLs qui est stocké à l'adresse donnée en argument, déjà allouée, + * @param p un pagerank alloué en mémoire + * @param n un entier strictement positif, la taille du graphe et de la liste du pagerank + * @return 0 si la liste a été créée et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation + * O(n) + */ +int creer_pagerank(pagerank* p, int n) +{ + int i; + if(n <= 0) + { + printf("Erreur paramètre creer_pagerank, n <= 0\n"); + return -1; + } + if(!(p->g = (graphe) malloc(sizeof(graphe)))) + { + printf("Erreur allocation creer_pagerank, malloc p->g\n"); + return -2; + } + if(creer_graphe(&p->g, n)) + { + free(p->g); + printf("Erreur allocation creer_pagerank, creer_graphe\n"); + return -2; + } + if(!(p->l = (liste_url) malloc(sizeof(liste_url)))) + { + graphe_detruire(&p->g); + free(p->g); + printf("Erreur allocation creer_pagerank, malloc p->l\n"); + return -2; + } + if(creer_liste(&p->l, n)) + { + graphe_detruire(&p->g); + free(p->g); + free(p->l); + printf("Erreur allocation creer_pagerank, creer_liste\n"); + return -2; + } + return 0; +} + + +/** Libère la mémoire allouée dans un pagerank + * @param p un pagerank alloué en mémoire + * O(n) + */ +void pagerank_detruire(pagerank* p) +{ + if(p) + { + if(p->g) + { + graphe_detruire(p->g); + free(p->g); + p->g = NULL; + } + if(p->l) + { + liste_detruire(p->l); + free(p->l); + p->l = NULL; + } + free(p); + } +} + + +/** Ajoute une URL à la première case vide dans la liste + * @param p un pagerank alloué en mémoire + * @param s une chaîne, l'URL à ajouter + * O(1) + */ +void pagerank_add_URL(pagerank* p, char* s) +{ + if(p && p->l) + { + liste_add(p->l, s); + } +} + + +/** Retire une URL de la liste du pagerank + * @param p un pagerank alloué en mémoire + * @param s une chaîne, l'URL à retirer + * O(n) + */ +void pagerank_remove_URL(pagerank* p, char* s) +{ + if(p && p->l) + { + liste_remove(p->l, s); + } +} + +/** Relie 2 URLs sous la forme d'une arête entre les sommets i et j du graphe du pagerank + * @param p un pagerank alloué en mémoire + * @param i un des sommets de l'arête + * @param j un des sommets de l'arête + * O(n) + */ +void pagerank_relier_URL(pagerank* p, int i, int j) +{ + if(p && p->l && p->g) + { + if(liste_contains(p->l, i) && liste_contains(p->l, j)) + { + graphe_ajouter_arete(p->g, i, j); + } + } +} + + +/** Delie 2 URLs en retirant une arête entre les sommets i et j du graphe du pagerank s'il y en a une + * @param p un pagerank alloué en mémoire + * @param i un des sommets de l'arête + * @param j un des sommets de l'arête + * O(n) + */ +void pagerank_delier_URL(pagerank* p, int i, int j) +{ + if(p && p->l && p->g) + { + if(liste_contains(p->l, i) && liste_contains(p->l, j)) + { + graphe_supprimer_arete(p->g, i, j); + } + } +} + + +/** Retire une URL du pagerank en retirant le sommet de son graphe, et l'URL de sa liste + * @param p un pagerank alloué en mémoire + * @param s une chaîne, l'URL à retirer + * O(n) + */ +void pagerank_retirer_URL(pagerank* p, char* s) +{ + if(p && p->l && p->g) + { + int x = liste_get_i(p->l, s); + if(x != -1) + { + liste_remove(p->l, s); + graphe_retirer_sommet(p->p, x); + } + } +} diff --git a/pagerank/src/pagerank.h b/pagerank/src/pagerank.h new file mode 100644 index 0000000..057123f --- /dev/null +++ b/pagerank/src/pagerank.h @@ -0,0 +1,72 @@ +#ifndef PAGERANK_H +#define PAGERANK_H + +struct s_pagerank { + graphe g; //Le graphe du pagerank + pagerank l; //La liste de toutes les URLs du pagerank +}; +typedef struct s_pagerank pagerank; + + +/** Fonction qui crée un pagerank pour n URLs qui est stocké à l'adresse donnée en argument, déjà allouée, + * @param p un pagerank alloué en mémoire + * @param n un entier strictement positif, la taille du graphe et de la liste du pagerank + * @return 0 si la liste a été créée et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation + * O(n) + */ +int creer_pagerank(pagerank* p, int n); + + +/** Libère la mémoire allouée dans un pagerank + * @param p un pagerank alloué en mémoire + * O(n) + */ +void pagerank_detruire(pagerank* p); + + +/** Ajoute une URL à la première case vide dans la liste + * @param p un pagerank alloué en mémoire + * @param s une chaîne, l'URL à ajouter + * O(1) + */ +void pagerank_add_URL(pagerank* p, char* s); + + +/** Retire une URL de la liste du pagerank + * @param p un pagerank alloué en mémoire + * @param s une chaîne, l'URL à retirer + * O(n) + */ +void pagerank_remove_URL(pagerank* p, char* s); + + +/** Relie 2 URLs sous la forme d'une arête entre les sommets i et j du graphe du pagerank + * @param p un pagerank alloué en mémoire + * @param i un des sommets de l'arête + * @param j un des sommets de l'arête + * O(n) + */ +void pagerank_relier_URL(pagerank* p, int i, int j); + + +/** Delie 2 URLs en retirant une arête entre les sommets i et j du graphe du pagerank s'il y en a une + * @param p un pagerank alloué en mémoire + * @param i un des sommets de l'arête + * @param j un des sommets de l'arête + * O(n) + */ +void pagerank_delier_URL(pagerank* p, int i, int j); + + +/** Retire une URL du pagerank en retirant le sommet de son graphe, et l'URL de sa liste + * @param p un pagerank alloué en mémoire + * @param s une chaîne, l'URL à retirer + * O(n) + */ +void pagerank_retirer_URL(pagerank* p, int x); + + +//int pagerank isValid test indices +// est lié à + +#endif diff --git a/pagerank/test/Makefile b/pagerank/test/Makefile index 2abbb88..905bcc2 100644 --- a/pagerank/test/Makefile +++ b/pagerank/test/Makefile @@ -1,12 +1,13 @@ CC= gcc CXXFLAGS= -Wall --pedantic -O3 -CPP_O_FILE = test-graphe.o +CPP_O_FILE = test-graphe.o test-liste.o LIB = -lm all: $(CPP_O_FILE) $(CC) $(CXXFLAGS) -o test-graphe.exe test-graphe.c ../src/graphe.c $(LIB) + $(CC) $(CXXFLAGS) -o test-liste.exe test-liste.c ../src/liste_url.c $(LIB) clean: rm -rf *.o *.exe diff --git a/pagerank/test/test-graphe.c b/pagerank/test/test-graphe.c index 9377a34..7796804 100644 --- a/pagerank/test/test-graphe.c +++ b/pagerank/test/test-graphe.c @@ -8,32 +8,51 @@ int main() { graphe g; creer_graphe(&g, NB_SOMMETS); - ajouter_arete(&g, 0, 1); - ajouter_arete(&g, 0, 9); - ajouter_arete(&g, 1, 3); - ajouter_arete(&g, 1, 2); - ajouter_arete(&g, 1, 4); - ajouter_arete(&g, 2, 4); - ajouter_arete(&g, 3, 4); - ajouter_arete(&g, 3, 5); - ajouter_arete(&g, 4, 5); - ajouter_arete(&g, 4, 6); - ajouter_arete(&g, 5, 6); + graphe_ajouter_arete(&g, 0, 1); + graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 0, 9); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 1, 3); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 1, 2); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 1, 4); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 2, 4); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 3, 4); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 3, 5); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 4, 5); + //graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 4, 6); + graphe_afficher_tableaux(&g); + graphe_ajouter_arete(&g, 5, 6); + graphe_afficher_tableaux(&g); graphe_afficher(&g); + printf("Le graphe %s le sommet 9, indice : %d\n", (graphe_contains(&g, 9) ? "contient" : "ne contient pas"), graphe_find(&g, 9)); printf("Retirons le sommet 4 (un nouveau sommet 4 prendra sa place\n"); - retirer_sommet(&g, 4); + graphe_retirer_sommet(&g, 4); printf("Retirons les arêtes 4-5, 1-3, et 5-4 (déjà retirée)\n"); - supprimer_arete(&g, 4, 5); + graphe_supprimer_arete(&g, 4, 5); graphe_afficher(&g); - supprimer_arete(&g, 1, 3); + graphe_supprimer_arete(&g, 1, 3); graphe_afficher(&g); - supprimer_arete(&g, 5, 4); + graphe_supprimer_arete(&g, 5, 4); graphe_afficher(&g); + printf("Les sommets 1 et 7 %s\n", (graphe_voisins(&g, 1, 7) ? "sont voisins" : "ne sont pas voisins")); + printf("Ajoutons une arête 1-7\n"); + graphe_ajouter_arete(&g, 1, 7); + printf("Les sommets 1 et 7 %s\n", (graphe_voisins(&g, 1, 7) ? "sont voisins" : "ne sont pas voisins")); + graphe_afficher(&g); + printf("Le graphe %s le sommet 9, indice : %d\n", (graphe_contains(&g, 9) ? "contient" : "ne contient pas"), graphe_find(&g, 9)); + graphe_detruire(&g); return EXIT_SUCCESS; } diff --git a/pagerank/test/test-liste.c b/pagerank/test/test-liste.c new file mode 100644 index 0000000..0db18a1 --- /dev/null +++ b/pagerank/test/test-liste.c @@ -0,0 +1,29 @@ +#include +#include +#include "../src/liste_url.h" + + +int main() +{ + liste_url l; + creer_liste(&l, 1); + liste_add(&l, "www.google.com"); + liste_add(&l, "www.gogol.com"); + liste_add(&l, "file://C:\\Users\\Nicolas\\Homework"); + liste_add(&l, "lipn.univ-paris13.fr/"); + liste_add(&l, "https://lipn.univ-paris13.fr/accueil/presentation/le-laboratoire/"); + + + liste_afficher(&l); + + printf("La liste %s l'URL \"www.google.com\", indice : %d\n", (liste_contains(&l, "www.google.com") ? "contient" : "ne contient pas"), liste_find(&l, "www.google.com")); + + printf("Retirons la première URL, celle de google\n"); + + liste_remove(&l, "www.google.com"); + liste_afficher(&l); + printf("La liste %s l'URL \"www.google.com\", indice : %d\n", (liste_contains(&l, "www.google.com") ? "contient" : "ne contient pas"), liste_find(&l, "www.google.com")); + + liste_detruire(&l); + return EXIT_SUCCESS; +} -- GitLab From 09c4392b69923264a041d9ecbab24dce88776216 Mon Sep 17 00:00:00 2001 From: Nicolas Floquet Date: Mon, 22 Mar 2021 23:13:09 +0100 Subject: [PATCH 06/16] =?UTF-8?q?T=C3=A2che=201=20=C3=A0=20valider=20(page?= =?UTF-8?q?rank)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pagerank/src/graphe.c | 124 +++++++++++++++++-- pagerank/src/graphe.h | 10 ++ pagerank/src/liste_url.c | 11 +- pagerank/src/liste_url.h | 2 +- pagerank/src/pagerank.c | 225 +++++++++++++++++++++++++++++----- pagerank/src/pagerank.h | 69 ++++++++--- pagerank/test/Makefile | 3 +- pagerank/test/test-graphe.c | 18 +++ pagerank/test/test-liste.c | 2 + pagerank/test/test-pagerank.c | 81 ++++++++++++ 10 files changed, 484 insertions(+), 61 deletions(-) create mode 100644 pagerank/test/test-pagerank.c diff --git a/pagerank/src/graphe.c b/pagerank/src/graphe.c index b01e43f..ae0ae9b 100644 --- a/pagerank/src/graphe.c +++ b/pagerank/src/graphe.c @@ -164,7 +164,7 @@ void graphe_ajouter_arete(graphe* g, int i, int j) } -/** Supprime une arête entre les sommets i et j du graphe (ou j et i) +/** Supprime une arête entre les sommets i et j du graphe * @param g un pointeur vers un graphe alloué en mémoire * @param i un des sommets de l'arête * @param j un des sommets de l'arête @@ -184,7 +184,7 @@ void graphe_supprimer_arete(graphe* g, int i, int j) } else { - if((g->ligne[cpt] == i && g->col[cpt] == j) || (g->ligne[cpt] == j && g->col[cpt] == i)) + if(g->ligne[cpt] == i && g->col[cpt] == j) { flag = 1; g->ligne[cpt] = g->ligne[cpt+1]; @@ -346,36 +346,36 @@ void graphe_afficher(graphe* g) for(i = 0; i < g->premierVide; i++) { matrice[g->ligne[i] * lim + g->col[i]]++; - matrice[g->col[i] * lim + g->ligne[i]]++; + // pas dans les 2 sens matrice[g->col[i] * lim + g->ligne[i]]++; } /* matrice d'adjacence faite */ /* ligne indices colonnes */ printf("\t\t"); - for (w = 0 ; w < lim ; w++) + for(w = 0 ; w < lim ; w++) { printf("%d\t", w); } printf("\n"); printf("\t\t"); - for (w = 0 ; w < lim ; w++) + for(w = 0 ; w < lim ; w++) { printf("_\t"); } printf("\n"); /* lignes de la matrice */ - for (v = 0 ; v < lim ; v++) + for(v = 0 ; v < lim ; v++) { printf("%d\t|\t", v); - for (w = 0 ; w < lim ; w++) + for(w = 0 ; w < lim ; w++) { printf("%d\t", matrice[v * lim + w]); } printf("|\n"); } printf("\t\t"); - for (w = 0 ; w < lim ; w++) + for(w = 0 ; w < lim ; w++) { printf("_\t"); } @@ -398,12 +398,12 @@ void graphe_afficher_tableaux(graphe* g) int i; printf("\n======================"); printf("\nIndices\t\t"); - for (i = 0; i < graphe_get_max(g); i++) + for(i = 0; i < graphe_get_max(g); i++) { printf("| %2d ", i); } printf("\n\nlignes :\t"); - for (i = 0; i < graphe_get_max(g); i++) + for(i = 0; i < graphe_get_max(g); i++) { if(i < graphe_get_premier_vide(g)) { @@ -415,7 +415,7 @@ void graphe_afficher_tableaux(graphe* g) } } printf("\ncolonnes :\t"); - for (i = 0; i < graphe_get_max(g); i++) + for(i = 0; i < graphe_get_max(g); i++) { if(i < graphe_get_premier_vide(g)) { @@ -431,6 +431,108 @@ void graphe_afficher_tableaux(graphe* g) } +/** Convertit un graphe au format DOT dans un fichier + * dot -Tpdf fichier.dot -o fichier.pdf + * @param g un graphe alloué en mémoire + * @param nomFichier, le nom du fichier où l'on veut écrire le graphe + * @return 0 si le graphe a bien été écris au format DOT, + * -1 s'il y a eu une erreur d'ouverture du fichier, et -2 sinon + * O(n) + */ +int graphe_ecrire_dot(graphe* g, char* nomFichier) +{ + if(g) + { + int i, nbSommets = 0, n = graphe_get_premier_vide(g), sommetMax = graphe_get_plus_grand_sommet(g); + if(!n) + { + printf("Erreur premier vide = 0, graphe vide graphe_ecrire_dot\n"); + return -2; + } + /* + On utilise 2 tableaux pour avoir une liste des sommets dans le graphe. + Soit n = graphe_get_premier_vide(g), il y a au max 2n sommets différents + (Si tous les sommets dans le tableau des lignes sont distincts et pointent chacun vers un sommets distinct) + Donc c'est le nombre max de sommets dans le fichier DOT. + + Et les valeurs des sommets sont entre 0 et graphe_get_plus_grand_sommet(g) inclus + */ + + int* flagSommet = (int *) calloc(sizeof(int), sommetMax + 1); + /* + flagSommet[i] = + 0 : sommet pas dans le graphe + 1 : sommet dans le graphe, il faudra l'ajouter dans le fichier dot + Toutes les valeurs entières entre 0 et sommetMax inclus peuvent être dans le graphe + */ + if(!flagSommet) + { + printf("Erreur allocation flagSommet graphe_ecrire_dot\n"); + return -2; + } + int* listeSommets = (int *) calloc(sizeof(int), 2*n); + /* + listeSommets[i] : + -1 : sommet pas dans le graphe + >= 0 : sommet dans le graphe, il faudra l'ajouter dans le fichier dot + Il y a au max 2n sommets différents + */ + if(!listeSommets) + { + printf("Erreur allocation listeSommets graphe_ecrire_dot\n"); + free(flagSommet); + return -2; + } + + for(i = 0; i < 2*n; i++) + { + listeSommets[i]--; //-1 partout + } + FILE *f = fopen(nomFichier, "w"); + if (!f) + { + free(flagSommet); + free(listeSommets); + printf("Erreur ouverture fichier \"%s\"graphe_ecrire_dot\n", nomFichier); + return -1; + } + for(i = 0; i < n; i++) + { + if(!flagSommet[g->ligne[i]]) //g->ligne[i] valait 0, donc le sommet n'était pas découvert + { + flagSommet[g->ligne[i]] = 1; + listeSommets[nbSommets++] = g->ligne[i]; + } + if(!flagSommet[g->col[i]]) //g->col[i] valait 0, donc le sommet n'était pas découvert + { + flagSommet[g->col[i]] = 1; + listeSommets[nbSommets++] = g->col[i]; + } + } + + //Dans flagSommet, on a tous les flags indiquant si un sommet est dans le graphe ou non + //Dans listeSommets on a la liste des sommets distincts + fputs("graph {\n", f); + for(i = 0; i < nbSommets; i++) + { + fprintf(f, "\t%d;\n", listeSommets[i]); + } + fputs("\n", f); + for(i = 0; i < n; i++) + { + fprintf(f, "\t%d -- %d;\n", g->ligne[i], g->col[i]); + } + fputs("}\n", f); + free(flagSommet); + free(listeSommets); + fclose(f); + return 0; + } + printf("Erreur pagerank NULL graphe_ecrire_dot\n"); + return -2; +} + + /** Renvoie le maximum entre 2 entiers * @param x un entier * @param y un entier diff --git a/pagerank/src/graphe.h b/pagerank/src/graphe.h index ee77415..f7adac2 100644 --- a/pagerank/src/graphe.h +++ b/pagerank/src/graphe.h @@ -130,6 +130,16 @@ void graphe_afficher(graphe* g); void graphe_afficher_tableaux(graphe* g); +/** Convertit un graphe au format DOT dans un fichier + * @param g un graphe alloué en mémoire + * @param nomFichier, le nom du fichier où l'on veut écrire le graphe + * @return 0 si le graphe a bien été écris au format DOT, + * -1 s'il y a eu une erreur d'ouverture du fichier, et -2 sinon + * O(n) + */ +int graphe_ecrire_dot(graphe* g, char* nomFichier); + + /** Renvoie le maximum entre 2 entiers * @param x un entier * @param y un entier diff --git a/pagerank/src/liste_url.c b/pagerank/src/liste_url.c index dbf7df7..9f0333c 100644 --- a/pagerank/src/liste_url.c +++ b/pagerank/src/liste_url.c @@ -88,7 +88,7 @@ int liste_find(liste_url* l, char* s) /** Renvoie l'url à l'indice i dans la liste * @param l un pointeur vers une liste allouée en mémoire * @param i un entier - * @return l->urls[i] un entier si 0 <= i < liste_get_max(l), NULL sinon + * @return l->urls[i] une chaîne de caractères si 0 <= i < liste_get_max(l), NULL sinon * O(1) */ char* liste_get_i(liste_url* l, int i) @@ -148,7 +148,14 @@ void liste_remove(liste_url* l, char* s) if(!trouve && (!strcmp(s, liste_get_i(l, i)))) { free(liste_get_i(l, i)); - l->urls[i] = l->urls[i+1]; + if(i+1 < liste_get_max(l)) + { + l->urls[i] = l->urls[i+1]; + } + else + { + l->urls[i] = NULL; + } trouve = 1; } else if(trouve) diff --git a/pagerank/src/liste_url.h b/pagerank/src/liste_url.h index b18dd53..476bb56 100644 --- a/pagerank/src/liste_url.h +++ b/pagerank/src/liste_url.h @@ -56,7 +56,7 @@ int liste_find(liste_url* l, char* s); /** Renvoie l'url à l'indice i dans la liste * @param l un pointeur vers une liste allouée en mémoire * @param i un entier - * @return l->urls[i] un entier si 0 <= i < liste_get_max(l), NULL sinon + * @return l->urls[i] une chaîne de caractères si 0 <= i < liste_get_max(l), NULL sinon * O(1) */ char* liste_get_i(liste_url* l, int i); diff --git a/pagerank/src/pagerank.c b/pagerank/src/pagerank.c index 37c8087..1e32b66 100644 --- a/pagerank/src/pagerank.c +++ b/pagerank/src/pagerank.c @@ -1,6 +1,8 @@ #include #include #include "pagerank.h" +#include "graphe.h" +#include "liste_url.h" /** Fonction qui crée un pagerank pour n URLs qui est stocké à l'adresse donnée en argument, déjà allouée, * @param p un pagerank alloué en mémoire @@ -10,33 +12,32 @@ */ int creer_pagerank(pagerank* p, int n) { - int i; if(n <= 0) { printf("Erreur paramètre creer_pagerank, n <= 0\n"); return -1; } - if(!(p->g = (graphe) malloc(sizeof(graphe)))) + if(!(p->g = (graphe*) malloc(sizeof(graphe)))) { printf("Erreur allocation creer_pagerank, malloc p->g\n"); return -2; } - if(creer_graphe(&p->g, n)) + if(creer_graphe(p->g, n)) { free(p->g); printf("Erreur allocation creer_pagerank, creer_graphe\n"); return -2; } - if(!(p->l = (liste_url) malloc(sizeof(liste_url)))) + if(!(p->l = (liste_url*) malloc(sizeof(liste_url)))) { - graphe_detruire(&p->g); + graphe_detruire(p->g); free(p->g); printf("Erreur allocation creer_pagerank, malloc p->l\n"); return -2; } - if(creer_liste(&p->l, n)) + if(creer_liste(p->l, n)) { - graphe_detruire(&p->g); + graphe_detruire(p->g); free(p->g); free(p->l); printf("Erreur allocation creer_pagerank, creer_liste\n"); @@ -66,11 +67,41 @@ void pagerank_detruire(pagerank* p) free(p->l); p->l = NULL; } - free(p); } } +/** Donne l'indice d'une url est dans la liste d'un pagerank + * @param p un pagerank alloué en mémoire + * @param s une chaîne, l'URL dont on veut connaître l'indice dans la liste + * @return l'indice de l'URL si elle est dans la liste du pagerank et -1 sinon + * O(n) + */ +int pagerank_find_indice_URL(pagerank* p, char* s) +{ + if(p) + { + return liste_find(p->l, s); + } + return -1; +} + + +/** Renvoie l'url à l'indice i dans la liste d'un pagerank + * @param p un pagerank alloué en mémoire + * @param i un entier + * @return p->l->urls[i] une chaîne de caractères si 0 <= i < liste_get_max(l), NULL sinon + * O(1) + */ +char* pagerank_get_URL_i(pagerank* p, int i) +{ + if(p) + { + return liste_get_i(p->l, i); + } + return NULL; +} + /** Ajoute une URL à la première case vide dans la liste * @param p un pagerank alloué en mémoire * @param s une chaîne, l'URL à ajouter @@ -85,69 +116,201 @@ void pagerank_add_URL(pagerank* p, char* s) } -/** Retire une URL de la liste du pagerank +/** Retire une URL du pagerank en retirant le sommet de son graphe, et l'URL de sa liste * @param p un pagerank alloué en mémoire * @param s une chaîne, l'URL à retirer * O(n) */ void pagerank_remove_URL(pagerank* p, char* s) { - if(p && p->l) + if(p && p->l && p->g) { - liste_remove(p->l, s); + int x = liste_find(p->l, s); + if(x != -1) + { + liste_remove(p->l, s); + graphe_retirer_sommet(p->g, x); + } } } -/** Relie 2 URLs sous la forme d'une arête entre les sommets i et j du graphe du pagerank +/** Relie 2 URLs du pagerank * @param p un pagerank alloué en mémoire - * @param i un des sommets de l'arête - * @param j un des sommets de l'arête + * @param s1 une des URLs du pagerank + * @param s2 une des URLs du pagerank * O(n) */ -void pagerank_relier_URL(pagerank* p, int i, int j) +void pagerank_relier_URL(pagerank* p, char* s1, char* s2) { if(p && p->l && p->g) { - if(liste_contains(p->l, i) && liste_contains(p->l, j)) + printf("ici pour %s et %s\n", s1, s2); + if(liste_contains(p->l, s1) && liste_contains(p->l, s2)) { - graphe_ajouter_arete(p->g, i, j); + printf("la pour %s et %s\n", s1, s2); + graphe_ajouter_arete(p->g, liste_find(p->l, s1), liste_find(p->l, s2)); } } } -/** Delie 2 URLs en retirant une arête entre les sommets i et j du graphe du pagerank s'il y en a une +/** Delie 2 URLs en retirant une arête entre les sommets correspondant du graphe du pagerank s'il y en a une * @param p un pagerank alloué en mémoire - * @param i un des sommets de l'arête - * @param j un des sommets de l'arête + * @param s1 une des URLs du pagerank + * @param s2 une des URLs du pagerank * O(n) */ -void pagerank_delier_URL(pagerank* p, int i, int j) +void pagerank_delier_URL(pagerank* p, char* s1, char* s2) { if(p && p->l && p->g) { - if(liste_contains(p->l, i) && liste_contains(p->l, j)) + if(liste_contains(p->l, s1) && liste_contains(p->l, s2)) { - graphe_supprimer_arete(p->g, i, j); + graphe_supprimer_arete(p->g, liste_find(p->l, s1), liste_find(p->l, s2)); } } } -/** Retire une URL du pagerank en retirant le sommet de son graphe, et l'URL de sa liste +/** Indique si une URL dans le pagerank a un lien vers une autre URL * @param p un pagerank alloué en mémoire - * @param s une chaîne, l'URL à retirer + * @param s1 une chaîne, l'URL où peut être le lien qu'on cherche + * @param s2 une chaîne, l'URL cible + * @return 1 si il y a un lien vers s2 dans la page s1 et 0 sinon * O(n) */ -void pagerank_retirer_URL(pagerank* p, char* s) +int pagerank_link_to(pagerank* p, char* s1, char* s2) { - if(p && p->l && p->g) + if(p && s1 && s2) { - int x = liste_get_i(p->l, s); - if(x != -1) + int indice1 = pagerank_find_indice_URL(p, s1); + int indice2 = pagerank_find_indice_URL(p, s2); + return graphe_est_succ(p->g, indice1, indice2); + } + return 0; +} + + +/** Affiche le pagerank (le graphe et la liste) + * @param p un pagerank alloué en mémoire + * O(n) + */ +void pagerank_afficher(pagerank* p) +{ + if(p) + { + printf("Voici la liste du pagerank:\n\n"); + liste_afficher(p->l); + printf("Voici le graphe du pagerank sous la forme de ces tableaux (matrice creuse):\n\n"); + graphe_afficher_tableaux(p->g); + printf("Voici le graphe du pagerank sous la forme d'une matrice d'adjacence:\n\n"); + graphe_afficher(p->g); + } + else + { + printf("Le pagerank est NULL\n"); + } +} + + +/** Convertit le graphe d'un pagerank au format DOT dans un fichier + * On verra un graphe avec comme sommets les URLs + * dot -Tpdf fichier.dot -o fichier.pdf + * @param p un pagerank alloué en mémoire + * @param nomFichier, le nom du fichier où l'on veut écrire le graphe + * @return 0 si le graphe a bien été écris au format DOT, + * -1 s'il y a eu une erreur d'ouverture du fichier, et -2 sinon + * O(n) + */ +int pagerank_ecrire_dot(pagerank* p, char* nomFichier) +{ + if(p) + { + int i, nbSommets = 0, n = graphe_get_premier_vide(p->g), sommetMax = graphe_get_plus_grand_sommet(p->g); + if(!n) { - liste_remove(p->l, s); - graphe_retirer_sommet(p->p, x); + printf("Erreur premier vide = 0, graphe vide pagerank_ecrire_dot\n"); + return -2; + } + /* + On utilise 2 tableaux pour avoir une liste des sommets dans le graphe. + Soit n = graphe_get_premier_vide(g), il y a au max 2n sommets différents + (Si tous les sommets dans le tableau des lignes sont distincts et pointent chacun vers un sommet distinct) + Donc c'est le nombre max de sommets dans le fichier DOT. + + Et les valeurs des sommets sont entre 0 et graphe_get_plus_grand_sommet(g) inclus + */ + + int* flagSommet = (int *) calloc(sizeof(int), sommetMax + 1); + /* + flagSommet[i] = + 0 : sommet pas dans le graphe + 1 : sommet dans le graphe, il faudra l'ajouter dans le fichier dot + Toutes les valeurs entières entre 0 et sommetMax inclus peuvent être dans le graphe + */ + if(!flagSommet) + { + printf("Erreur allocation flagSommet pagerank_ecrire_dot\n"); + return -2; + } + int* listeSommets = (int *) calloc(sizeof(int), 2*n); + /* + listeSommets[i] : + -1 : sommet pas dans le graphe + >= 0 : sommet dans le graphe, il faudra l'ajouter dans le fichier dot + Il y a au max 2n sommets différents + */ + if(!listeSommets) + { + printf("Erreur allocation listeSommets pagerank_ecrire_dot\n"); + free(flagSommet); + return -2; + } + + for(i = 0; i < 2*n; i++) + { + listeSommets[i]--; //-1 partout + } + FILE *f = fopen(nomFichier, "w"); + if (!f) + { + free(flagSommet); + free(listeSommets); + printf("Erreur ouverture fichier \"%s\"pagerank_ecrire_dot\n", nomFichier); + return -1; + } + for(i = 0; i < n; i++) + { + if(!flagSommet[p->g->ligne[i]]) //g->ligne[i] valait 0, donc le sommet n'était pas découvert + { + flagSommet[p->g->ligne[i]] = 1; + listeSommets[nbSommets++] = p->g->ligne[i]; + } + if(!flagSommet[p->g->col[i]]) //g->col[i] valait 0, donc le sommet n'était pas découvert + { + flagSommet[p->g->col[i]] = 1; + listeSommets[nbSommets++] = p->g->col[i]; + } + } + + //Dans flagSommet, on a tous les flags indiquant si un sommet est dans le graphe ou non + //Dans listeSommets on a la liste des sommets distincts + fputs("graph {\n", f); + for(i = 0; i < nbSommets; i++) + { + fprintf(f, "\t\"%s\";\n", liste_get_i(p->l, listeSommets[i])); + } + fputs("\n", f); + for(i = 0; i < n; i++) + { + fprintf(f, "\t\"%s\" -- \"%s\";\n", liste_get_i(p->l, p->g->ligne[i]), liste_get_i(p->l, p->g->col[i])); } + fputs("}\n", f); + free(flagSommet); + free(listeSommets); + fclose(f); + return 0; } + printf("Erreur pagerank NULL pagerank_ecrire_dot\n"); + return -2; } diff --git a/pagerank/src/pagerank.h b/pagerank/src/pagerank.h index 057123f..c533cd9 100644 --- a/pagerank/src/pagerank.h +++ b/pagerank/src/pagerank.h @@ -1,9 +1,13 @@ #ifndef PAGERANK_H #define PAGERANK_H +#include "graphe.h" +#include "liste_url.h" + + struct s_pagerank { - graphe g; //Le graphe du pagerank - pagerank l; //La liste de toutes les URLs du pagerank + graphe* g; //Le graphe du pagerank + liste_url* l; //La liste de toutes les URLs du pagerank }; typedef struct s_pagerank pagerank; @@ -24,6 +28,24 @@ int creer_pagerank(pagerank* p, int n); void pagerank_detruire(pagerank* p); +/** Donne l'indice d'une url est dans la liste d'un pagerank + * @param p un pagerank alloué en mémoire + * @param s une chaîne, l'URL dont on veut connaître l'indice dans la liste + * @return l'indice de l'URL si elle est dans la liste du pagerank et -1 sinon + * O(n) + */ +int pagerank_find_indice_URL(pagerank* p, char* s); + + +/** Renvoie l'url à l'indice i dans la liste d'un pagerank + * @param p un pagerank alloué en mémoire + * @param i un entier + * @return p->l->urls[i] une chaîne de caractères si 0 <= i < liste_get_max(l), NULL sinon + * O(1) + */ +char* pagerank_get_URL_i(pagerank* p, int i); + + /** Ajoute une URL à la première case vide dans la liste * @param p un pagerank alloué en mémoire * @param s une chaîne, l'URL à ajouter @@ -32,7 +54,7 @@ void pagerank_detruire(pagerank* p); void pagerank_add_URL(pagerank* p, char* s); -/** Retire une URL de la liste du pagerank +/** Retire une URL du pagerank en retirant le sommet de son graphe, et l'URL de sa liste * @param p un pagerank alloué en mémoire * @param s une chaîne, l'URL à retirer * O(n) @@ -40,33 +62,50 @@ void pagerank_add_URL(pagerank* p, char* s); void pagerank_remove_URL(pagerank* p, char* s); -/** Relie 2 URLs sous la forme d'une arête entre les sommets i et j du graphe du pagerank +/** Relie 2 URLs du pagerank * @param p un pagerank alloué en mémoire - * @param i un des sommets de l'arête - * @param j un des sommets de l'arête + * @param s1 une des URLs du pagerank + * @param s2 une des URLs du pagerank * O(n) */ -void pagerank_relier_URL(pagerank* p, int i, int j); +void pagerank_relier_URL(pagerank* p, char* s1, char* s2); -/** Delie 2 URLs en retirant une arête entre les sommets i et j du graphe du pagerank s'il y en a une +/** Delie 2 URLs en retirant une arête entre les sommets correspondant du graphe du pagerank s'il y en a une * @param p un pagerank alloué en mémoire - * @param i un des sommets de l'arête - * @param j un des sommets de l'arête + * @param s1 une des URLs du pagerank + * @param s2 une des URLs du pagerank * O(n) */ -void pagerank_delier_URL(pagerank* p, int i, int j); +void pagerank_delier_URL(pagerank* p, char* s1, char* s2); -/** Retire une URL du pagerank en retirant le sommet de son graphe, et l'URL de sa liste +/** Indique si une URL dans le pagerank a un lien vers une autre URL + * @param p un pagerank alloué en mémoire + * @param s1 une chaîne, l'URL où peut être le lien qu'on cherche + * @param s2 une chaîne, l'URL cible + * @return 1 si il y a un lien vers s2 dans la page s1 et 0 sinon + * O(n) + */ +int pagerank_link_to(pagerank* p, char* s1, char* s2); + + +/** Affiche le pagerank (le graphe et la liste) * @param p un pagerank alloué en mémoire - * @param s une chaîne, l'URL à retirer * O(n) */ -void pagerank_retirer_URL(pagerank* p, int x); +void pagerank_afficher(pagerank* p); + +/** Convertit le graphe d'un pagerank au format DOT dans un fichier + * @param p un pagerank alloué en mémoire + * @param nomFichier, le nom du fichier où l'on veut écrire le graphe + * @return 0 si le graphe a bien été écris au format DOT, + * -1 s'il y a eu une erreur d'ouverture du fichier, et -2 sinon + * O(n) + */ +int pagerank_ecrire_dot(pagerank* p, char* nomFichier); //int pagerank isValid test indices -// est lié à #endif diff --git a/pagerank/test/Makefile b/pagerank/test/Makefile index 905bcc2..4aeb4da 100644 --- a/pagerank/test/Makefile +++ b/pagerank/test/Makefile @@ -1,13 +1,14 @@ CC= gcc CXXFLAGS= -Wall --pedantic -O3 -CPP_O_FILE = test-graphe.o test-liste.o +CPP_O_FILE = test-graphe.o test-liste.o test-pagerank.o LIB = -lm all: $(CPP_O_FILE) $(CC) $(CXXFLAGS) -o test-graphe.exe test-graphe.c ../src/graphe.c $(LIB) $(CC) $(CXXFLAGS) -o test-liste.exe test-liste.c ../src/liste_url.c $(LIB) + $(CC) $(CXXFLAGS) -o test-pagerank.exe test-pagerank.c ../src/pagerank.c ../src/graphe.c ../src/liste_url.c $(LIB) clean: rm -rf *.o *.exe diff --git a/pagerank/test/test-graphe.c b/pagerank/test/test-graphe.c index 7796804..c374bcc 100644 --- a/pagerank/test/test-graphe.c +++ b/pagerank/test/test-graphe.c @@ -2,11 +2,20 @@ #include #include "../src/graphe.h" +/* +dot -Tpdf graphe_1.dot -o graphe_1.pdf +dot -Tpdf graphe_2.dot -o graphe_2.pdf +dot -Tpdf graphe_3.dot -o graphe_3.pdf +*/ + #define NB_SOMMETS 7 int main() { graphe g; + char* fichier1 = "graphe_1.dot"; + char* fichier2 = "graphe_2.dot"; + char* fichier3 = "graphe_3.dot"; creer_graphe(&g, NB_SOMMETS); graphe_ajouter_arete(&g, 0, 1); graphe_afficher_tableaux(&g); @@ -34,10 +43,16 @@ int main() graphe_afficher(&g); printf("Le graphe %s le sommet 9, indice : %d\n", (graphe_contains(&g, 9) ? "contient" : "ne contient pas"), graphe_find(&g, 9)); + printf("On stocke le graphe tel qu'il est après tous les ajouts dans le fichier %s\n", fichier1); + graphe_ecrire_dot(&g, fichier1); + printf("Retirons le sommet 4 (un nouveau sommet 4 prendra sa place\n"); graphe_retirer_sommet(&g, 4); + printf("On stocke le graphe tel qu'il est après la suppression du sommet 4 dans le fichier %s\n", fichier2); + graphe_ecrire_dot(&g, fichier2); + printf("Retirons les arêtes 4-5, 1-3, et 5-4 (déjà retirée)\n"); graphe_supprimer_arete(&g, 4, 5); graphe_afficher(&g); @@ -53,6 +68,9 @@ int main() graphe_afficher(&g); printf("Le graphe %s le sommet 9, indice : %d\n", (graphe_contains(&g, 9) ? "contient" : "ne contient pas"), graphe_find(&g, 9)); + printf("On stocke le graphe tel qu'il est après des retraits et l'ajout du sommet 7 dans le fichier %s\n", fichier3); + graphe_ecrire_dot(&g, fichier3); + graphe_detruire(&g); return EXIT_SUCCESS; } diff --git a/pagerank/test/test-liste.c b/pagerank/test/test-liste.c index 0db18a1..cb735a2 100644 --- a/pagerank/test/test-liste.c +++ b/pagerank/test/test-liste.c @@ -16,6 +16,8 @@ int main() liste_afficher(&l); + printf("La première URL est %s\n", liste_get_i(&l, 0)); + printf("La liste %s l'URL \"www.google.com\", indice : %d\n", (liste_contains(&l, "www.google.com") ? "contient" : "ne contient pas"), liste_find(&l, "www.google.com")); printf("Retirons la première URL, celle de google\n"); diff --git a/pagerank/test/test-pagerank.c b/pagerank/test/test-pagerank.c new file mode 100644 index 0000000..554d996 --- /dev/null +++ b/pagerank/test/test-pagerank.c @@ -0,0 +1,81 @@ +#include +#include +#include "../src/pagerank.h" + +/* +dot -Tpdf pagerank_1.dot -o pagerank_1.pdf +dot -Tpdf pagerank_2.dot -o pagerank_2.pdf +dot -Tpdf pagerank_3.dot -o pagerank_3.pdf +*/ + +int main() +{ + pagerank p; + char* fichier1 = "pagerank_1.dot"; + char* fichier2 = "pagerank_2.dot"; + char* fichier3 = "pagerank_3.dot"; + + char* google = "www.google.com"; + char* fichierNico = "file://C:\\Users\\Nicolas\\Homework"; + char* lipn = "lipn.univ-paris13.fr/"; + char* lipnA3 = "https://lipn.univ-paris13.fr/accueil/equipe/a3/"; + char* lipnAOC = "https://lipn.univ-paris13.fr/accueil/equipe/aoc/"; + char* lipnPresentation = "https://lipn.univ-paris13.fr/accueil/presentation/le-laboratoire/"; + char* youtube = "https://www.youtube.com/"; + char* youtubeHistory = "https://www.youtube.com/feed/history"; + char* youtubeSubs = "https://www.youtube.com/feed/subscriptions"; + char* aRetirer = "/A/retirer"; + + + creer_pagerank(&p, 5); + pagerank_add_URL(&p, google); + pagerank_add_URL(&p, fichierNico); + pagerank_add_URL(&p, lipn); + pagerank_add_URL(&p, lipnA3); + pagerank_add_URL(&p, lipnAOC); + pagerank_add_URL(&p, lipnPresentation); + pagerank_add_URL(&p, youtube); + pagerank_add_URL(&p, youtubeHistory); + pagerank_add_URL(&p, youtubeSubs); + pagerank_add_URL(&p, aRetirer); + + pagerank_afficher(&p); + + printf("La première URL ajoutée est %s\n", pagerank_get_URL_i(&p, 0)); + printf("L'indice de l'URL du LIPN est %d\n", pagerank_find_indice_URL(&p, lipn)); + + pagerank_remove_URL(&p, aRetirer); + + pagerank_afficher(&p); + + pagerank_relier_URL(&p, google, youtube); + pagerank_relier_URL(&p, youtube, youtubeHistory); + pagerank_relier_URL(&p, youtube, youtubeSubs); + pagerank_relier_URL(&p, lipn, lipnA3); + pagerank_relier_URL(&p, lipn, lipnAOC); + pagerank_relier_URL(&p, lipn, lipnPresentation); + pagerank_relier_URL(&p, lipnPresentation, lipnA3); + pagerank_relier_URL(&p, lipnPresentation, lipnAOC); + pagerank_relier_URL(&p, fichierNico, google); + pagerank_afficher(&p); + + pagerank_ecrire_dot(&p, fichier1); + + printf("\"%s\" %s \"%s\"\n", fichierNico, google, ((pagerank_link_to(&p, fichierNico, google)) ? "a un lien vers" : "n'a pas de lien vers")); + + pagerank_delier_URL(&p, fichierNico, google); + + pagerank_ecrire_dot(&p, fichier2); + + printf("\"%s\" %s \"%s\"\n", fichierNico, google, ((pagerank_link_to(&p, fichierNico, google)) ? "a un lien vers" : "n'a pas de lien vers")); + + printf("Retirons maintenant \"%s\" du pagerank\n", google); + + pagerank_remove_URL(&p, google); + + pagerank_ecrire_dot(&p, fichier3); + pagerank_afficher(&p); + + pagerank_detruire(&p); + return EXIT_SUCCESS; +} -- GitLab From 73b25d68577433a61e827002b76f5ca22a4e5b9c Mon Sep 17 00:00:00 2001 From: Nicolas Floquet Date: Mon, 29 Mar 2021 00:43:02 +0200 Subject: [PATCH 07/16] graphe_pagerank_avec_assert_29_03_21 --- pagerank/Makefile | 12 +++++++ pagerank/README.md | 7 +++- pagerank/src/graphe.c | 15 ++++++++ pagerank/test/test-graphe.c | 69 +++++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 pagerank/Makefile diff --git a/pagerank/Makefile b/pagerank/Makefile new file mode 100644 index 0000000..8516972 --- /dev/null +++ b/pagerank/Makefile @@ -0,0 +1,12 @@ +CC= gcc +CXXFLAGS= -Wall --pedantic -O3 + +CPP_O_FILE = main-pagerank.o +LIB = -lm + + +all: $(CPP_O_FILE) + $(CC) $(CXXFLAGS) -o main-pagerank.exe main-pagerank.c ./src/pagerank.c ./src/graphe.c ./src/liste_url.c $(LIB) + +clean: + rm -rf *.o *.exe diff --git a/pagerank/README.md b/pagerank/README.md index 7d4f4e7..73b043d 100644 --- a/pagerank/README.md +++ b/pagerank/README.md @@ -1,7 +1,12 @@ Le répertoire src contient les sources du programme qui crée un graphe des pages web du lipn et en calcule le pagerank. -Le répertoire test cotient les tests unitaires qui vérifie que les fonctions +Le répertoire test contient les tests unitaires qui vérifie que les fonctions dans contenues dans le répertoire src jouent correctement leur rôle +Les bibliothèques requises sont celles de base en C, stdlib, stdio, string, time et assert. (.h) + +Pour compiler les fichiers de test, il faut se placer dans le répertoire test et entrer la commande make + +Le programme final, quand il sera fait se compilera en faisant make dans le répertoire pagerank diff --git a/pagerank/src/graphe.c b/pagerank/src/graphe.c index ae0ae9b..49174b4 100644 --- a/pagerank/src/graphe.c +++ b/pagerank/src/graphe.c @@ -1,5 +1,6 @@ #include #include +#include #include "graphe.h" @@ -38,6 +39,13 @@ int creer_graphe(graphe* g, int n) g->ligne[i] = -1; g->col[i] = -1; } + assert(g->premierVide >= 0); + assert(g->max > 0); + assert(g->max == n); + assert(g->ligne[0] == -1); + assert(g->ligne[0] == -1); + assert(g->ligne[g->max-1] == -1); + assert(g->ligne[g->max-1] == -1); return 0; } @@ -63,6 +71,7 @@ void graphe_detruire(graphe* g) */ int graphe_get_max(graphe* g) { + assert(g->max > 0); return g->max; } @@ -74,6 +83,8 @@ int graphe_get_max(graphe* g) */ int graphe_get_premier_vide(graphe* g) { + assert(g->premierVide >= 0); + assert(g->premierVide <= g->max); return g->premierVide; } @@ -105,6 +116,7 @@ int graphe_find(graphe* g, int u) { if(g->ligne[i] == u || g->col[i] == u) { + assert(g->ligne[i] == u || g->col[i] == u); return i; } } @@ -286,10 +298,12 @@ int graphe_voisins(graphe* g, int u, int v) { if(g->ligne[i] == u && g->col[i] == v) { + assert(g->ligne[i] == u && g->col[i] == v); return 1; } if(g->ligne[i] == v && g->col[i] == u) { + assert(g->ligne[i] == v && g->col[i] == u); return 1; } } @@ -318,6 +332,7 @@ int graphe_est_succ(graphe* g, int u, int v) { if(g->ligne[i] == u && g->col[i] == v) { + assert(g->ligne[i] == u && g->col[i] == v); return 1; } } diff --git a/pagerank/test/test-graphe.c b/pagerank/test/test-graphe.c index c374bcc..be169a1 100644 --- a/pagerank/test/test-graphe.c +++ b/pagerank/test/test-graphe.c @@ -1,5 +1,6 @@ #include #include +#include #include "../src/graphe.h" /* @@ -13,31 +14,96 @@ dot -Tpdf graphe_3.dot -o graphe_3.pdf int main() { graphe g; + char* fichier1 = "graphe_1.dot"; + assert(fichier1); char* fichier2 = "graphe_2.dot"; + assert(fichier2); char* fichier3 = "graphe_3.dot"; + assert(fichier3); + creer_graphe(&g, NB_SOMMETS); + assert(g.max > 0); + assert(g.premierVide == 0); + assert(g.ligne); + assert(g.col); + graphe_ajouter_arete(&g, 0, 1); + assert(g.ligne[0] == 0); + assert(g.col[0] == 1); + assert(g.premierVide == 1); + assert(graphe_get_plus_grand_sommet(&g) == 1); + graphe_afficher_tableaux(&g); graphe_ajouter_arete(&g, 0, 9); + assert(g.ligne[1] == 0); + assert(g.col[1] == 9); + assert(g.premierVide == 2); + assert(graphe_get_plus_grand_sommet(&g) == 9); + //graphe_afficher_tableaux(&g); graphe_ajouter_arete(&g, 1, 3); + assert(g.ligne[2] == 1); + assert(g.col[2] == 3); + assert(g.premierVide == 3); + assert(graphe_get_plus_grand_sommet(&g) == 9); + //graphe_afficher_tableaux(&g); graphe_ajouter_arete(&g, 1, 2); + assert(g.ligne[3] == 1); + assert(g.col[3] == 2); + assert(g.premierVide == 4); + assert(graphe_get_plus_grand_sommet(&g) == 9); + //graphe_afficher_tableaux(&g); graphe_ajouter_arete(&g, 1, 4); + assert(g.ligne[4] == 1); + assert(g.col[4] == 4); + assert(g.premierVide == 5); + assert(graphe_get_plus_grand_sommet(&g) == 9); + //graphe_afficher_tableaux(&g); graphe_ajouter_arete(&g, 2, 4); + assert(g.ligne[5] == 2); + assert(g.col[5] == 4); + assert(g.premierVide == 6); + assert(graphe_get_plus_grand_sommet(&g) == 9); + //graphe_afficher_tableaux(&g); graphe_ajouter_arete(&g, 3, 4); + assert(g.ligne[6] == 3); + assert(g.col[6] == 4); + assert(g.premierVide == 7); + assert(graphe_get_plus_grand_sommet(&g) == 9); + //graphe_afficher_tableaux(&g); graphe_ajouter_arete(&g, 3, 5); + assert(g.ligne[7] == 3); + assert(g.col[7] == 5); + assert(g.premierVide == 8); + assert(graphe_get_plus_grand_sommet(&g) == 9); + //graphe_afficher_tableaux(&g); graphe_ajouter_arete(&g, 4, 5); + assert(g.ligne[8] == 4); + assert(g.col[8] == 5); + assert(g.premierVide == 9); + assert(graphe_get_plus_grand_sommet(&g) == 9); + //graphe_afficher_tableaux(&g); graphe_ajouter_arete(&g, 4, 6); + assert(g.ligne[9] == 4); + assert(g.col[9] == 6); + assert(g.premierVide == 10); + assert(graphe_get_plus_grand_sommet(&g) == 9); + graphe_afficher_tableaux(&g); graphe_ajouter_arete(&g, 5, 6); + assert(g.ligne[10] == 5); + assert(g.col[10] == 6); + assert(g.premierVide == 11); + assert(graphe_get_plus_grand_sommet(&g) == 9); + graphe_afficher_tableaux(&g); graphe_afficher(&g); @@ -49,6 +115,7 @@ int main() printf("Retirons le sommet 4 (un nouveau sommet 4 prendra sa place\n"); graphe_retirer_sommet(&g, 4); + assert(graphe_get_plus_grand_sommet(&g) == 8); printf("On stocke le graphe tel qu'il est après la suppression du sommet 4 dans le fichier %s\n", fichier2); graphe_ecrire_dot(&g, fichier2); @@ -62,9 +129,11 @@ int main() graphe_afficher(&g); printf("Les sommets 1 et 7 %s\n", (graphe_voisins(&g, 1, 7) ? "sont voisins" : "ne sont pas voisins")); + assert(!graphe_voisins(&g, 1, 7)); printf("Ajoutons une arête 1-7\n"); graphe_ajouter_arete(&g, 1, 7); printf("Les sommets 1 et 7 %s\n", (graphe_voisins(&g, 1, 7) ? "sont voisins" : "ne sont pas voisins")); + assert(graphe_voisins(&g, 1, 7)); graphe_afficher(&g); printf("Le graphe %s le sommet 9, indice : %d\n", (graphe_contains(&g, 9) ? "contient" : "ne contient pas"), graphe_find(&g, 9)); -- GitLab From 7332b58661ce594d3cc2da9c7f5ec18ed33859b5 Mon Sep 17 00:00:00 2001 From: TP SDA Julien David Date: Sun, 28 Mar 2021 22:58:10 +0000 Subject: [PATCH 08/16] Delete test-liste.c --- pagerank/test/test-liste.c | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 pagerank/test/test-liste.c diff --git a/pagerank/test/test-liste.c b/pagerank/test/test-liste.c deleted file mode 100644 index cb735a2..0000000 --- a/pagerank/test/test-liste.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include "../src/liste_url.h" - - -int main() -{ - liste_url l; - creer_liste(&l, 1); - liste_add(&l, "www.google.com"); - liste_add(&l, "www.gogol.com"); - liste_add(&l, "file://C:\\Users\\Nicolas\\Homework"); - liste_add(&l, "lipn.univ-paris13.fr/"); - liste_add(&l, "https://lipn.univ-paris13.fr/accueil/presentation/le-laboratoire/"); - - - liste_afficher(&l); - - printf("La première URL est %s\n", liste_get_i(&l, 0)); - - printf("La liste %s l'URL \"www.google.com\", indice : %d\n", (liste_contains(&l, "www.google.com") ? "contient" : "ne contient pas"), liste_find(&l, "www.google.com")); - - printf("Retirons la première URL, celle de google\n"); - - liste_remove(&l, "www.google.com"); - liste_afficher(&l); - printf("La liste %s l'URL \"www.google.com\", indice : %d\n", (liste_contains(&l, "www.google.com") ? "contient" : "ne contient pas"), liste_find(&l, "www.google.com")); - - liste_detruire(&l); - return EXIT_SUCCESS; -} -- GitLab From 864c5f68a35103735da750d3181a8318d978fb66 Mon Sep 17 00:00:00 2001 From: TP SDA Julien David Date: Sun, 28 Mar 2021 22:58:33 +0000 Subject: [PATCH 09/16] Delete test-pagerank.c --- pagerank/test/test-pagerank.c | 81 ----------------------------------- 1 file changed, 81 deletions(-) delete mode 100644 pagerank/test/test-pagerank.c diff --git a/pagerank/test/test-pagerank.c b/pagerank/test/test-pagerank.c deleted file mode 100644 index 554d996..0000000 --- a/pagerank/test/test-pagerank.c +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include -#include "../src/pagerank.h" - -/* -dot -Tpdf pagerank_1.dot -o pagerank_1.pdf -dot -Tpdf pagerank_2.dot -o pagerank_2.pdf -dot -Tpdf pagerank_3.dot -o pagerank_3.pdf -*/ - -int main() -{ - pagerank p; - char* fichier1 = "pagerank_1.dot"; - char* fichier2 = "pagerank_2.dot"; - char* fichier3 = "pagerank_3.dot"; - - char* google = "www.google.com"; - char* fichierNico = "file://C:\\Users\\Nicolas\\Homework"; - char* lipn = "lipn.univ-paris13.fr/"; - char* lipnA3 = "https://lipn.univ-paris13.fr/accueil/equipe/a3/"; - char* lipnAOC = "https://lipn.univ-paris13.fr/accueil/equipe/aoc/"; - char* lipnPresentation = "https://lipn.univ-paris13.fr/accueil/presentation/le-laboratoire/"; - char* youtube = "https://www.youtube.com/"; - char* youtubeHistory = "https://www.youtube.com/feed/history"; - char* youtubeSubs = "https://www.youtube.com/feed/subscriptions"; - char* aRetirer = "/A/retirer"; - - - creer_pagerank(&p, 5); - pagerank_add_URL(&p, google); - pagerank_add_URL(&p, fichierNico); - pagerank_add_URL(&p, lipn); - pagerank_add_URL(&p, lipnA3); - pagerank_add_URL(&p, lipnAOC); - pagerank_add_URL(&p, lipnPresentation); - pagerank_add_URL(&p, youtube); - pagerank_add_URL(&p, youtubeHistory); - pagerank_add_URL(&p, youtubeSubs); - pagerank_add_URL(&p, aRetirer); - - pagerank_afficher(&p); - - printf("La première URL ajoutée est %s\n", pagerank_get_URL_i(&p, 0)); - printf("L'indice de l'URL du LIPN est %d\n", pagerank_find_indice_URL(&p, lipn)); - - pagerank_remove_URL(&p, aRetirer); - - pagerank_afficher(&p); - - pagerank_relier_URL(&p, google, youtube); - pagerank_relier_URL(&p, youtube, youtubeHistory); - pagerank_relier_URL(&p, youtube, youtubeSubs); - pagerank_relier_URL(&p, lipn, lipnA3); - pagerank_relier_URL(&p, lipn, lipnAOC); - pagerank_relier_URL(&p, lipn, lipnPresentation); - pagerank_relier_URL(&p, lipnPresentation, lipnA3); - pagerank_relier_URL(&p, lipnPresentation, lipnAOC); - pagerank_relier_URL(&p, fichierNico, google); - pagerank_afficher(&p); - - pagerank_ecrire_dot(&p, fichier1); - - printf("\"%s\" %s \"%s\"\n", fichierNico, google, ((pagerank_link_to(&p, fichierNico, google)) ? "a un lien vers" : "n'a pas de lien vers")); - - pagerank_delier_URL(&p, fichierNico, google); - - pagerank_ecrire_dot(&p, fichier2); - - printf("\"%s\" %s \"%s\"\n", fichierNico, google, ((pagerank_link_to(&p, fichierNico, google)) ? "a un lien vers" : "n'a pas de lien vers")); - - printf("Retirons maintenant \"%s\" du pagerank\n", google); - - pagerank_remove_URL(&p, google); - - pagerank_ecrire_dot(&p, fichier3); - pagerank_afficher(&p); - - pagerank_detruire(&p); - return EXIT_SUCCESS; -} -- GitLab From 1a0e6bbf7069b9590424b1217a91c9dc48a6ee01 Mon Sep 17 00:00:00 2001 From: TP SDA Julien David Date: Sun, 28 Mar 2021 22:58:51 +0000 Subject: [PATCH 10/16] Delete liste_url.c --- pagerank/src/liste_url.c | 223 --------------------------------------- 1 file changed, 223 deletions(-) delete mode 100644 pagerank/src/liste_url.c diff --git a/pagerank/src/liste_url.c b/pagerank/src/liste_url.c deleted file mode 100644 index 9f0333c..0000000 --- a/pagerank/src/liste_url.c +++ /dev/null @@ -1,223 +0,0 @@ -#include -#include -#include -#include "liste_url.h" - - -/** Fonction qui crée une liste d'url qui est stockée à l'adresse donnée en argument, déjà allouée, la liste aura déjà n cases pour stocker des URLs (c'est un tableau dynamique, sa taille pourra être amenée à augmenter) - * @param l une liste d'url allouée en mémoire - * @param n un entier strictement positif, la taille de la liste - * @return 0 si la liste a été créée et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation - * O(n) - */ -int creer_liste(liste_url* l, int n) -{ - if(n <= 0) - { - printf("Erreur paramètre creer_liste, n <= 0\n"); - return -1; - } - if(!(l->urls = (char**) calloc(sizeof(char*), n))) - { - printf("Erreur allocation creer_liste, l->urls\n"); - return -2; - } - l->max = n; - l->premierNULL = 0; - return 0; -} - - -/** Renvoie la taille maximale actuelle de la liste l - * @param l un pointeur vers une liste allouée en mémoire - * @return g->max un entier - * O(1) - */ -int liste_get_max(liste_url* l) -{ - return l->max; -} - - -/** Renvoie l'indice du premier NULL dans le liste - * @param l un pointeur vers une liste allouée en mémoire - * @return l->premierNULL un entier - * O(1) - */ -int liste_get_premier_NULL(liste_url* l) -{ - return l->premierNULL; -} - - -/** Indique si une url est dans la liste - * @param l un pointeur vers une liste allouée en mémoire - * @param s une chaîne, l'URL dont on veut savoir si elle est dans la liste - * @return 1 si l'URL est dans la liste et 0 sinon - * O(n) - */ -int liste_contains(liste_url* l, char* s) -{ - return (liste_find(l, s) != -1); -} - - -/** Donne l'indice d'une url est dans la liste - * @param l un pointeur vers une liste allouée en mémoire - * @param s une chaîne, l'URL dont on veut connaître l'indice dans la liste - * @return l'indice de l'URL si elle est dans la liste et -1 sinon - * O(n) - */ -int liste_find(liste_url* l, char* s) -{ - if(l && s) - { - int i; - for(i = 0; i < liste_get_premier_NULL(l); i++) - { - if(!strcmp(s, liste_get_i(l, i))) - { - return i; - } - } - } - return -1; -} - - -/** Renvoie l'url à l'indice i dans la liste - * @param l un pointeur vers une liste allouée en mémoire - * @param i un entier - * @return l->urls[i] une chaîne de caractères si 0 <= i < liste_get_max(l), NULL sinon - * O(1) - */ -char* liste_get_i(liste_url* l, int i) -{ - if(0 <= i && i < liste_get_max(l)) - { - return l->urls[i]; - } - return NULL; -} - - -/** Ajoute une url à la première case vide dans la liste - * @param l un pointeur vers une liste allouée en mémoire - * @param s une chaîne, l'URL à ajouter - * O(1) - */ -void liste_add(liste_url* l, char* s) -{ - if(l) - { - if(liste_get_premier_NULL(l) == liste_get_max(l)) - { //Réallocation si nécessaire, complexité amortie en temps linéaire - l->max *= 2; - char** nouvelleListe = (char**) calloc(sizeof(char*), liste_get_max(l)); - - for (int i = 0; i < liste_get_premier_NULL(l); i++) - { - nouvelleListe[i] = (char*) malloc(sizeof(char) * (strlen(l->urls[i]) + 1)); - strcpy(nouvelleListe[i], l->urls[i]); - free(l->urls[i]); - } - nouvelleListe[l->premierNULL] = (char*) calloc(sizeof(char), strlen(s)+1); - strcpy(nouvelleListe[l->premierNULL++], s); - free(l->urls); - l->urls = nouvelleListe; - return; - } - l->urls[l->premierNULL] = (char*) calloc(sizeof(char), strlen(s)+1); - strcpy(l->urls[l->premierNULL++], s); - } -} - - -/** Retire une url de la liste - * @param l un pointeur vers une liste allouée en mémoire - * @param s une chaîne, l'URL à retirer - * O(n) - */ -void liste_remove(liste_url* l, char* s) -{ - if(l && s) - { - int i, trouve = 0; - for(i = 0; i < liste_get_premier_NULL(l); i++) - { - if(!trouve && (!strcmp(s, liste_get_i(l, i)))) - { - free(liste_get_i(l, i)); - if(i+1 < liste_get_max(l)) - { - l->urls[i] = l->urls[i+1]; - } - else - { - l->urls[i] = NULL; - } - trouve = 1; - } - else if(trouve) - { - if(i+1 < liste_get_max(l)) - { - l->urls[i] = l->urls[i+1]; - } - else - { - l->urls[i] = NULL; - } - } - } - l->premierNULL--; - } -} - - -/** Libère la mémoire allouée dans une liste et toutes les chaînes contenues dedans - * @param l une liste d'url allouée en mémoire - * O(n) - */ -void liste_detruire(liste_url* l) -{ - if(l) - { - int i; - for(i = 0; i < liste_get_premier_NULL(l); i++) - { - free(l->urls[i]); - l->urls[i] = NULL; - } - free(l->urls); - } -} - - -/** Affiche la liste d'URLs - * @param l un pointeur vers une liste allouée en mémoire - * O(n) - */ -void liste_afficher(liste_url* l) -{ - if(l) - { - int i, n = liste_get_max(l); - printf("i\t|\tURLs:\n"); - for(i = 0; i < n; i++) - { - if(i < liste_get_premier_NULL(l)) - { - printf("%d \t|\t\"%s\"\n", i, liste_get_i(l, i)); - } - else - { - printf("%d \t|\tNULL\n", i); - } - } - } - else - { - printf("La liste est NULL\n"); - } -} -- GitLab From 225257e0af891e288483ab0644249cd1de0177ea Mon Sep 17 00:00:00 2001 From: TP SDA Julien David Date: Sun, 28 Mar 2021 22:58:57 +0000 Subject: [PATCH 11/16] Delete liste_url.h --- pagerank/src/liste_url.h | 95 ---------------------------------------- 1 file changed, 95 deletions(-) delete mode 100644 pagerank/src/liste_url.h diff --git a/pagerank/src/liste_url.h b/pagerank/src/liste_url.h deleted file mode 100644 index 476bb56..0000000 --- a/pagerank/src/liste_url.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef LISTE_URL_H -#define LISTE_URL_H - - -struct s_liste_url { - int max; // Longueur de la liste allouée - int premierNULL; // Indice de la première chaîne NULL - char** urls; // Les urls de la liste -}; -typedef struct s_liste_url liste_url; - - -/** Fonction qui crée une liste d'url qui est stockée à l'adresse donnée en argument, déjà allouée, la liste aura déjà n cases pour stocker des URLs (c'est un tableau dynamique, sa taille pourra être amenée à augmenter) - * @param l une liste d'url allouée en mémoire - * @param n un entier strictement positif, la taille de la liste - * @return 0 si la liste a été créée et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation - * O(n) - */ -int creer_liste(liste_url* l, int n); - - -/** Renvoie la taille maximale actuelle de la liste l - * @param l un pointeur vers une liste allouée en mémoire - * @return g->max un entier - * O(1) - */ -int liste_get_max(liste_url* l); - - -/** Renvoie l'indice du premier NULL dans le liste - * @param l un pointeur vers une liste allouée en mémoire - * @return l->premierNULL un entier - * O(1) - */ -int liste_get_premier_NULL(liste_url* l); - - -/** Indique si une url est dans la liste - * @param l un pointeur vers une liste allouée en mémoire - * @param s une chaîne, l'URL dont on veut savoir si elle est dans la liste - * @return 1 si l'URL est dans la liste et 0 sinon - * O(n) - */ -int liste_contains(liste_url* l, char* s); - - -/** Donne l'indice d'une url est dans la liste - * @param l un pointeur vers une liste allouée en mémoire - * @param s une chaîne, l'URL dont on veut connaître l'indice dans la liste - * @return l'indice de l'URL si elle est dans la liste et -1 sinon - * O(n) - */ -int liste_find(liste_url* l, char* s); - - -/** Renvoie l'url à l'indice i dans la liste - * @param l un pointeur vers une liste allouée en mémoire - * @param i un entier - * @return l->urls[i] une chaîne de caractères si 0 <= i < liste_get_max(l), NULL sinon - * O(1) - */ -char* liste_get_i(liste_url* l, int i); - - -/** Ajoute une url à la première case vide dans la liste - * @param l un pointeur vers une liste allouée en mémoire - * @param s une chaîne, l'URL à ajouter - * O(1) - */ -void liste_add(liste_url* l, char* s); - - -/** Retire une url de la liste - * @param l un pointeur vers une liste allouée en mémoire - * @param s une chaîne, l'URL à retirer - * O(n) - */ -void liste_remove(liste_url* l, char* s); - - - -/** Libère la mémoire allouée dans une liste et toutes les chaînes contenues dedans - * @param l une liste d'url allouée en mémoire - * O(n) - */ -void liste_detruire(liste_url* l); - - -/** Affiche la liste d'URLs - * @param l un pointeur vers une liste allouée en mémoire - * O(n) - */ -void liste_afficher(liste_url* l); - -#endif -- GitLab From 6e240df7acc250026d80581eafa048bbbaf87de6 Mon Sep 17 00:00:00 2001 From: TP SDA Julien David Date: Sun, 28 Mar 2021 22:59:02 +0000 Subject: [PATCH 12/16] Delete pagerank.c --- pagerank/src/pagerank.c | 316 ---------------------------------------- 1 file changed, 316 deletions(-) delete mode 100644 pagerank/src/pagerank.c diff --git a/pagerank/src/pagerank.c b/pagerank/src/pagerank.c deleted file mode 100644 index 1e32b66..0000000 --- a/pagerank/src/pagerank.c +++ /dev/null @@ -1,316 +0,0 @@ -#include -#include -#include "pagerank.h" -#include "graphe.h" -#include "liste_url.h" - -/** Fonction qui crée un pagerank pour n URLs qui est stocké à l'adresse donnée en argument, déjà allouée, - * @param p un pagerank alloué en mémoire - * @param n un entier strictement positif, la taille du graphe et de la liste du pagerank - * @return 0 si la liste a été créée et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation - * O(n) - */ -int creer_pagerank(pagerank* p, int n) -{ - if(n <= 0) - { - printf("Erreur paramètre creer_pagerank, n <= 0\n"); - return -1; - } - if(!(p->g = (graphe*) malloc(sizeof(graphe)))) - { - printf("Erreur allocation creer_pagerank, malloc p->g\n"); - return -2; - } - if(creer_graphe(p->g, n)) - { - free(p->g); - printf("Erreur allocation creer_pagerank, creer_graphe\n"); - return -2; - } - if(!(p->l = (liste_url*) malloc(sizeof(liste_url)))) - { - graphe_detruire(p->g); - free(p->g); - printf("Erreur allocation creer_pagerank, malloc p->l\n"); - return -2; - } - if(creer_liste(p->l, n)) - { - graphe_detruire(p->g); - free(p->g); - free(p->l); - printf("Erreur allocation creer_pagerank, creer_liste\n"); - return -2; - } - return 0; -} - - -/** Libère la mémoire allouée dans un pagerank - * @param p un pagerank alloué en mémoire - * O(n) - */ -void pagerank_detruire(pagerank* p) -{ - if(p) - { - if(p->g) - { - graphe_detruire(p->g); - free(p->g); - p->g = NULL; - } - if(p->l) - { - liste_detruire(p->l); - free(p->l); - p->l = NULL; - } - } -} - - -/** Donne l'indice d'une url est dans la liste d'un pagerank - * @param p un pagerank alloué en mémoire - * @param s une chaîne, l'URL dont on veut connaître l'indice dans la liste - * @return l'indice de l'URL si elle est dans la liste du pagerank et -1 sinon - * O(n) - */ -int pagerank_find_indice_URL(pagerank* p, char* s) -{ - if(p) - { - return liste_find(p->l, s); - } - return -1; -} - - -/** Renvoie l'url à l'indice i dans la liste d'un pagerank - * @param p un pagerank alloué en mémoire - * @param i un entier - * @return p->l->urls[i] une chaîne de caractères si 0 <= i < liste_get_max(l), NULL sinon - * O(1) - */ -char* pagerank_get_URL_i(pagerank* p, int i) -{ - if(p) - { - return liste_get_i(p->l, i); - } - return NULL; -} - -/** Ajoute une URL à la première case vide dans la liste - * @param p un pagerank alloué en mémoire - * @param s une chaîne, l'URL à ajouter - * O(1) - */ -void pagerank_add_URL(pagerank* p, char* s) -{ - if(p && p->l) - { - liste_add(p->l, s); - } -} - - -/** Retire une URL du pagerank en retirant le sommet de son graphe, et l'URL de sa liste - * @param p un pagerank alloué en mémoire - * @param s une chaîne, l'URL à retirer - * O(n) - */ -void pagerank_remove_URL(pagerank* p, char* s) -{ - if(p && p->l && p->g) - { - int x = liste_find(p->l, s); - if(x != -1) - { - liste_remove(p->l, s); - graphe_retirer_sommet(p->g, x); - } - } -} - -/** Relie 2 URLs du pagerank - * @param p un pagerank alloué en mémoire - * @param s1 une des URLs du pagerank - * @param s2 une des URLs du pagerank - * O(n) - */ -void pagerank_relier_URL(pagerank* p, char* s1, char* s2) -{ - if(p && p->l && p->g) - { - printf("ici pour %s et %s\n", s1, s2); - if(liste_contains(p->l, s1) && liste_contains(p->l, s2)) - { - printf("la pour %s et %s\n", s1, s2); - graphe_ajouter_arete(p->g, liste_find(p->l, s1), liste_find(p->l, s2)); - } - } -} - - -/** Delie 2 URLs en retirant une arête entre les sommets correspondant du graphe du pagerank s'il y en a une - * @param p un pagerank alloué en mémoire - * @param s1 une des URLs du pagerank - * @param s2 une des URLs du pagerank - * O(n) - */ -void pagerank_delier_URL(pagerank* p, char* s1, char* s2) -{ - if(p && p->l && p->g) - { - if(liste_contains(p->l, s1) && liste_contains(p->l, s2)) - { - graphe_supprimer_arete(p->g, liste_find(p->l, s1), liste_find(p->l, s2)); - } - } -} - - -/** Indique si une URL dans le pagerank a un lien vers une autre URL - * @param p un pagerank alloué en mémoire - * @param s1 une chaîne, l'URL où peut être le lien qu'on cherche - * @param s2 une chaîne, l'URL cible - * @return 1 si il y a un lien vers s2 dans la page s1 et 0 sinon - * O(n) - */ -int pagerank_link_to(pagerank* p, char* s1, char* s2) -{ - if(p && s1 && s2) - { - int indice1 = pagerank_find_indice_URL(p, s1); - int indice2 = pagerank_find_indice_URL(p, s2); - return graphe_est_succ(p->g, indice1, indice2); - } - return 0; -} - - -/** Affiche le pagerank (le graphe et la liste) - * @param p un pagerank alloué en mémoire - * O(n) - */ -void pagerank_afficher(pagerank* p) -{ - if(p) - { - printf("Voici la liste du pagerank:\n\n"); - liste_afficher(p->l); - printf("Voici le graphe du pagerank sous la forme de ces tableaux (matrice creuse):\n\n"); - graphe_afficher_tableaux(p->g); - printf("Voici le graphe du pagerank sous la forme d'une matrice d'adjacence:\n\n"); - graphe_afficher(p->g); - } - else - { - printf("Le pagerank est NULL\n"); - } -} - - -/** Convertit le graphe d'un pagerank au format DOT dans un fichier - * On verra un graphe avec comme sommets les URLs - * dot -Tpdf fichier.dot -o fichier.pdf - * @param p un pagerank alloué en mémoire - * @param nomFichier, le nom du fichier où l'on veut écrire le graphe - * @return 0 si le graphe a bien été écris au format DOT, - * -1 s'il y a eu une erreur d'ouverture du fichier, et -2 sinon - * O(n) - */ -int pagerank_ecrire_dot(pagerank* p, char* nomFichier) -{ - if(p) - { - int i, nbSommets = 0, n = graphe_get_premier_vide(p->g), sommetMax = graphe_get_plus_grand_sommet(p->g); - if(!n) - { - printf("Erreur premier vide = 0, graphe vide pagerank_ecrire_dot\n"); - return -2; - } - /* - On utilise 2 tableaux pour avoir une liste des sommets dans le graphe. - Soit n = graphe_get_premier_vide(g), il y a au max 2n sommets différents - (Si tous les sommets dans le tableau des lignes sont distincts et pointent chacun vers un sommet distinct) - Donc c'est le nombre max de sommets dans le fichier DOT. - - Et les valeurs des sommets sont entre 0 et graphe_get_plus_grand_sommet(g) inclus - */ - - int* flagSommet = (int *) calloc(sizeof(int), sommetMax + 1); - /* - flagSommet[i] = - 0 : sommet pas dans le graphe - 1 : sommet dans le graphe, il faudra l'ajouter dans le fichier dot - Toutes les valeurs entières entre 0 et sommetMax inclus peuvent être dans le graphe - */ - if(!flagSommet) - { - printf("Erreur allocation flagSommet pagerank_ecrire_dot\n"); - return -2; - } - int* listeSommets = (int *) calloc(sizeof(int), 2*n); - /* - listeSommets[i] : - -1 : sommet pas dans le graphe - >= 0 : sommet dans le graphe, il faudra l'ajouter dans le fichier dot - Il y a au max 2n sommets différents - */ - if(!listeSommets) - { - printf("Erreur allocation listeSommets pagerank_ecrire_dot\n"); - free(flagSommet); - return -2; - } - - for(i = 0; i < 2*n; i++) - { - listeSommets[i]--; //-1 partout - } - FILE *f = fopen(nomFichier, "w"); - if (!f) - { - free(flagSommet); - free(listeSommets); - printf("Erreur ouverture fichier \"%s\"pagerank_ecrire_dot\n", nomFichier); - return -1; - } - for(i = 0; i < n; i++) - { - if(!flagSommet[p->g->ligne[i]]) //g->ligne[i] valait 0, donc le sommet n'était pas découvert - { - flagSommet[p->g->ligne[i]] = 1; - listeSommets[nbSommets++] = p->g->ligne[i]; - } - if(!flagSommet[p->g->col[i]]) //g->col[i] valait 0, donc le sommet n'était pas découvert - { - flagSommet[p->g->col[i]] = 1; - listeSommets[nbSommets++] = p->g->col[i]; - } - } - - //Dans flagSommet, on a tous les flags indiquant si un sommet est dans le graphe ou non - //Dans listeSommets on a la liste des sommets distincts - fputs("graph {\n", f); - for(i = 0; i < nbSommets; i++) - { - fprintf(f, "\t\"%s\";\n", liste_get_i(p->l, listeSommets[i])); - } - fputs("\n", f); - for(i = 0; i < n; i++) - { - fprintf(f, "\t\"%s\" -- \"%s\";\n", liste_get_i(p->l, p->g->ligne[i]), liste_get_i(p->l, p->g->col[i])); - } - fputs("}\n", f); - free(flagSommet); - free(listeSommets); - fclose(f); - return 0; - } - printf("Erreur pagerank NULL pagerank_ecrire_dot\n"); - return -2; -} -- GitLab From d890a4f1d12291b5adab9cf9e90bc92c1d22928b Mon Sep 17 00:00:00 2001 From: TP SDA Julien David Date: Sun, 28 Mar 2021 22:59:08 +0000 Subject: [PATCH 13/16] Delete pagerank.h --- pagerank/src/pagerank.h | 111 ---------------------------------------- 1 file changed, 111 deletions(-) delete mode 100644 pagerank/src/pagerank.h diff --git a/pagerank/src/pagerank.h b/pagerank/src/pagerank.h deleted file mode 100644 index c533cd9..0000000 --- a/pagerank/src/pagerank.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef PAGERANK_H -#define PAGERANK_H - -#include "graphe.h" -#include "liste_url.h" - - -struct s_pagerank { - graphe* g; //Le graphe du pagerank - liste_url* l; //La liste de toutes les URLs du pagerank -}; -typedef struct s_pagerank pagerank; - - -/** Fonction qui crée un pagerank pour n URLs qui est stocké à l'adresse donnée en argument, déjà allouée, - * @param p un pagerank alloué en mémoire - * @param n un entier strictement positif, la taille du graphe et de la liste du pagerank - * @return 0 si la liste a été créée et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation - * O(n) - */ -int creer_pagerank(pagerank* p, int n); - - -/** Libère la mémoire allouée dans un pagerank - * @param p un pagerank alloué en mémoire - * O(n) - */ -void pagerank_detruire(pagerank* p); - - -/** Donne l'indice d'une url est dans la liste d'un pagerank - * @param p un pagerank alloué en mémoire - * @param s une chaîne, l'URL dont on veut connaître l'indice dans la liste - * @return l'indice de l'URL si elle est dans la liste du pagerank et -1 sinon - * O(n) - */ -int pagerank_find_indice_URL(pagerank* p, char* s); - - -/** Renvoie l'url à l'indice i dans la liste d'un pagerank - * @param p un pagerank alloué en mémoire - * @param i un entier - * @return p->l->urls[i] une chaîne de caractères si 0 <= i < liste_get_max(l), NULL sinon - * O(1) - */ -char* pagerank_get_URL_i(pagerank* p, int i); - - -/** Ajoute une URL à la première case vide dans la liste - * @param p un pagerank alloué en mémoire - * @param s une chaîne, l'URL à ajouter - * O(1) - */ -void pagerank_add_URL(pagerank* p, char* s); - - -/** Retire une URL du pagerank en retirant le sommet de son graphe, et l'URL de sa liste - * @param p un pagerank alloué en mémoire - * @param s une chaîne, l'URL à retirer - * O(n) - */ -void pagerank_remove_URL(pagerank* p, char* s); - - -/** Relie 2 URLs du pagerank - * @param p un pagerank alloué en mémoire - * @param s1 une des URLs du pagerank - * @param s2 une des URLs du pagerank - * O(n) - */ -void pagerank_relier_URL(pagerank* p, char* s1, char* s2); - - -/** Delie 2 URLs en retirant une arête entre les sommets correspondant du graphe du pagerank s'il y en a une - * @param p un pagerank alloué en mémoire - * @param s1 une des URLs du pagerank - * @param s2 une des URLs du pagerank - * O(n) - */ -void pagerank_delier_URL(pagerank* p, char* s1, char* s2); - - -/** Indique si une URL dans le pagerank a un lien vers une autre URL - * @param p un pagerank alloué en mémoire - * @param s1 une chaîne, l'URL où peut être le lien qu'on cherche - * @param s2 une chaîne, l'URL cible - * @return 1 si il y a un lien vers s2 dans la page s1 et 0 sinon - * O(n) - */ -int pagerank_link_to(pagerank* p, char* s1, char* s2); - - -/** Affiche le pagerank (le graphe et la liste) - * @param p un pagerank alloué en mémoire - * O(n) - */ -void pagerank_afficher(pagerank* p); - - -/** Convertit le graphe d'un pagerank au format DOT dans un fichier - * @param p un pagerank alloué en mémoire - * @param nomFichier, le nom du fichier où l'on veut écrire le graphe - * @return 0 si le graphe a bien été écris au format DOT, - * -1 s'il y a eu une erreur d'ouverture du fichier, et -2 sinon - * O(n) - */ -int pagerank_ecrire_dot(pagerank* p, char* nomFichier); - -//int pagerank isValid test indices - -#endif -- GitLab From 4bebfbe35ced8d38f3ed34d0471e22d99f17dbf6 Mon Sep 17 00:00:00 2001 From: Nicolas Floquet Date: Tue, 30 Mar 2021 00:24:53 +0200 Subject: [PATCH 14/16] Commit liste_url avec assert --- pagerank/src/liste_url.c | 21 +++++++++ pagerank/test/test-liste.c | 15 +++++++ pagerank/test/test-pagerank.c | 81 ----------------------------------- 3 files changed, 36 insertions(+), 81 deletions(-) delete mode 100644 pagerank/test/test-pagerank.c diff --git a/pagerank/src/liste_url.c b/pagerank/src/liste_url.c index 9f0333c..cd13040 100644 --- a/pagerank/src/liste_url.c +++ b/pagerank/src/liste_url.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "liste_url.h" @@ -24,6 +25,12 @@ int creer_liste(liste_url* l, int n) } l->max = n; l->premierNULL = 0; + assert(l->max > 0); + assert(l->max == n); + assert(l->premierNULL == 0); + assert(l->premierNULL == 0); + assert(l->urls[0] == NULL); + assert(l->urls[l->max - 1] == NULL); return 0; } @@ -35,6 +42,7 @@ int creer_liste(liste_url* l, int n) */ int liste_get_max(liste_url* l) { + assert(l->max > 0); return l->max; } @@ -46,6 +54,8 @@ int liste_get_max(liste_url* l) */ int liste_get_premier_NULL(liste_url* l) { + assert(l->premierNULL >= 0); + assert(l->premierNULL <= l->max); return l->premierNULL; } @@ -77,6 +87,10 @@ int liste_find(liste_url* l, char* s) { if(!strcmp(s, liste_get_i(l, i))) { + assert(!strcmp(s, l->urls[i])); + assert(i >= 0); + assert(i < l->premierNULL); + assert(i < l->max); return i; } } @@ -95,6 +109,8 @@ char* liste_get_i(liste_url* l, int i) { if(0 <= i && i < liste_get_max(l)) { + assert(i >= 0); + assert(i < l->max); return l->urls[i]; } return NULL; @@ -129,6 +145,7 @@ void liste_add(liste_url* l, char* s) } l->urls[l->premierNULL] = (char*) calloc(sizeof(char), strlen(s)+1); strcpy(l->urls[l->premierNULL++], s); + assert(!strcmp(l->urls[l->premierNULL - 1], s)); } } @@ -142,6 +159,8 @@ void liste_remove(liste_url* l, char* s) { if(l && s) { + int assertAncienneTaille = liste_get_premier_NULL(l); + int assertNouvelleTaille; int i, trouve = 0; for(i = 0; i < liste_get_premier_NULL(l); i++) { @@ -171,6 +190,8 @@ void liste_remove(liste_url* l, char* s) } } l->premierNULL--; + assertNouvelleTaille = liste_get_premier_NULL(l); + assert(trouve || (assertAncienneTaille == assertNouvelleTaille)); } } diff --git a/pagerank/test/test-liste.c b/pagerank/test/test-liste.c index cb735a2..32a212f 100644 --- a/pagerank/test/test-liste.c +++ b/pagerank/test/test-liste.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include "../src/liste_url.h" @@ -8,10 +10,19 @@ int main() liste_url l; creer_liste(&l, 1); liste_add(&l, "www.google.com"); + assert(!strcmp(l.urls[0], "www.google.com")); + liste_add(&l, "www.gogol.com"); + assert(!strcmp(l.urls[1], "www.gogol.com")); + liste_add(&l, "file://C:\\Users\\Nicolas\\Homework"); + assert(!strcmp(l.urls[2], "file://C:\\Users\\Nicolas\\Homework")); + liste_add(&l, "lipn.univ-paris13.fr/"); + assert(!strcmp(l.urls[3], "lipn.univ-paris13.fr/")); + liste_add(&l, "https://lipn.univ-paris13.fr/accueil/presentation/le-laboratoire/"); + assert(!strcmp(l.urls[4], "https://lipn.univ-paris13.fr/accueil/presentation/le-laboratoire/")); liste_afficher(&l); @@ -19,12 +30,16 @@ int main() printf("La première URL est %s\n", liste_get_i(&l, 0)); printf("La liste %s l'URL \"www.google.com\", indice : %d\n", (liste_contains(&l, "www.google.com") ? "contient" : "ne contient pas"), liste_find(&l, "www.google.com")); + assert(liste_contains(&l, "www.google.com")); printf("Retirons la première URL, celle de google\n"); liste_remove(&l, "www.google.com"); + assert(strcmp(l.urls[0], "www.google.com")); //strcmp != 0 => chaînes différentes (inférieures ou supérieures) + liste_afficher(&l); printf("La liste %s l'URL \"www.google.com\", indice : %d\n", (liste_contains(&l, "www.google.com") ? "contient" : "ne contient pas"), liste_find(&l, "www.google.com")); + assert(!liste_contains(&l, "www.google.com")); liste_detruire(&l); return EXIT_SUCCESS; diff --git a/pagerank/test/test-pagerank.c b/pagerank/test/test-pagerank.c deleted file mode 100644 index 554d996..0000000 --- a/pagerank/test/test-pagerank.c +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include -#include "../src/pagerank.h" - -/* -dot -Tpdf pagerank_1.dot -o pagerank_1.pdf -dot -Tpdf pagerank_2.dot -o pagerank_2.pdf -dot -Tpdf pagerank_3.dot -o pagerank_3.pdf -*/ - -int main() -{ - pagerank p; - char* fichier1 = "pagerank_1.dot"; - char* fichier2 = "pagerank_2.dot"; - char* fichier3 = "pagerank_3.dot"; - - char* google = "www.google.com"; - char* fichierNico = "file://C:\\Users\\Nicolas\\Homework"; - char* lipn = "lipn.univ-paris13.fr/"; - char* lipnA3 = "https://lipn.univ-paris13.fr/accueil/equipe/a3/"; - char* lipnAOC = "https://lipn.univ-paris13.fr/accueil/equipe/aoc/"; - char* lipnPresentation = "https://lipn.univ-paris13.fr/accueil/presentation/le-laboratoire/"; - char* youtube = "https://www.youtube.com/"; - char* youtubeHistory = "https://www.youtube.com/feed/history"; - char* youtubeSubs = "https://www.youtube.com/feed/subscriptions"; - char* aRetirer = "/A/retirer"; - - - creer_pagerank(&p, 5); - pagerank_add_URL(&p, google); - pagerank_add_URL(&p, fichierNico); - pagerank_add_URL(&p, lipn); - pagerank_add_URL(&p, lipnA3); - pagerank_add_URL(&p, lipnAOC); - pagerank_add_URL(&p, lipnPresentation); - pagerank_add_URL(&p, youtube); - pagerank_add_URL(&p, youtubeHistory); - pagerank_add_URL(&p, youtubeSubs); - pagerank_add_URL(&p, aRetirer); - - pagerank_afficher(&p); - - printf("La première URL ajoutée est %s\n", pagerank_get_URL_i(&p, 0)); - printf("L'indice de l'URL du LIPN est %d\n", pagerank_find_indice_URL(&p, lipn)); - - pagerank_remove_URL(&p, aRetirer); - - pagerank_afficher(&p); - - pagerank_relier_URL(&p, google, youtube); - pagerank_relier_URL(&p, youtube, youtubeHistory); - pagerank_relier_URL(&p, youtube, youtubeSubs); - pagerank_relier_URL(&p, lipn, lipnA3); - pagerank_relier_URL(&p, lipn, lipnAOC); - pagerank_relier_URL(&p, lipn, lipnPresentation); - pagerank_relier_URL(&p, lipnPresentation, lipnA3); - pagerank_relier_URL(&p, lipnPresentation, lipnAOC); - pagerank_relier_URL(&p, fichierNico, google); - pagerank_afficher(&p); - - pagerank_ecrire_dot(&p, fichier1); - - printf("\"%s\" %s \"%s\"\n", fichierNico, google, ((pagerank_link_to(&p, fichierNico, google)) ? "a un lien vers" : "n'a pas de lien vers")); - - pagerank_delier_URL(&p, fichierNico, google); - - pagerank_ecrire_dot(&p, fichier2); - - printf("\"%s\" %s \"%s\"\n", fichierNico, google, ((pagerank_link_to(&p, fichierNico, google)) ? "a un lien vers" : "n'a pas de lien vers")); - - printf("Retirons maintenant \"%s\" du pagerank\n", google); - - pagerank_remove_URL(&p, google); - - pagerank_ecrire_dot(&p, fichier3); - pagerank_afficher(&p); - - pagerank_detruire(&p); - return EXIT_SUCCESS; -} -- GitLab From f7a9eac15d458c2119084eb3a4d547caac47dd18 Mon Sep 17 00:00:00 2001 From: Nicolas Floquet Date: Tue, 30 Mar 2021 23:53:10 +0200 Subject: [PATCH 15/16] Pagerank graphe.c refait --- pagerank/src/graphe.c | 275 +++++++++++++----------------------------- 1 file changed, 85 insertions(+), 190 deletions(-) diff --git a/pagerank/src/graphe.c b/pagerank/src/graphe.c index 49174b4..8975643 100644 --- a/pagerank/src/graphe.c +++ b/pagerank/src/graphe.c @@ -1,6 +1,5 @@ #include #include -#include #include "graphe.h" @@ -12,40 +11,27 @@ * @return 0 si le graphe a été créé et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation * O(n) */ -int creer_graphe(graphe* g, int n) -{ +int creer_graphe(graphe* g, int n) { int i; - if(n <= 0) - { + if(n <= 0) { printf("Erreur paramètre creer_graphe, n <= 0\n"); return -1; } - if(!(g->ligne = (int*) malloc(sizeof(int) * n))) - { + if(!(g->ligne = (int*) malloc(sizeof(int) * n))) { printf("Erreur allocation creer_graphe, g->ligne\n"); return -2; } - if(!(g->col = (int*) malloc(sizeof(int) * n))) - { + if(!(g->col = (int*) malloc(sizeof(int) * n))) { printf("Erreur allocation creer_graphe, g->col\n"); free(g->ligne); return -2; } g->max = n; g->premierVide = 0; - for(i = 0; i < n; i++) - { - //printf("%d\n", i); + for(i = 0; i < n; i++) { g->ligne[i] = -1; g->col[i] = -1; } - assert(g->premierVide >= 0); - assert(g->max > 0); - assert(g->max == n); - assert(g->ligne[0] == -1); - assert(g->ligne[0] == -1); - assert(g->ligne[g->max-1] == -1); - assert(g->ligne[g->max-1] == -1); return 0; } @@ -54,10 +40,8 @@ int creer_graphe(graphe* g, int n) /** Libère la mémoire allouée dans un graphe, mais pas le graphe lui même (le pointeur donné en paramètre reste à libérer * @param g un pointeur vers un graphe alloué en mémoire */ -void graphe_detruire(graphe* g) -{ - if(g) - { +void graphe_detruire(graphe* g) { + if(g) { free(g->ligne); free(g->col); } @@ -69,9 +53,7 @@ void graphe_detruire(graphe* g) * @return g->max un entier * O(1) */ -int graphe_get_max(graphe* g) -{ - assert(g->max > 0); +int graphe_get_max(graphe* g) { return g->max; } @@ -81,10 +63,7 @@ int graphe_get_max(graphe* g) * @return g->premierVide un entier * O(1) */ -int graphe_get_premier_vide(graphe* g) -{ - assert(g->premierVide >= 0); - assert(g->premierVide <= g->max); +int graphe_get_premier_vide(graphe* g) { return g->premierVide; } @@ -95,8 +74,7 @@ int graphe_get_premier_vide(graphe* g) * @return 1 si le sommet est dans le graphe et 0 sinon * O(n) */ -int graphe_contains(graphe* g, int u) -{ +int graphe_contains(graphe* g, int u) { return (graphe_find(g, u) != -1); } @@ -107,16 +85,11 @@ int graphe_contains(graphe* g, int u) * @return l'indice de le sommet si il est dans le graphe et -1 sinon * O(n) */ -int graphe_find(graphe* g, int u) -{ - if(g && u >= 0 && u <= graphe_get_plus_grand_sommet(g)) - { +int graphe_find(graphe* g, int u) { + if(g && u >= 0 && u <= graphe_get_plus_grand_sommet(g)) { int i; - for(i = 0; i < graphe_get_premier_vide(g); i++) - { - if(g->ligne[i] == u || g->col[i] == u) - { - assert(g->ligne[i] == u || g->col[i] == u); + for(i = 0; i < graphe_get_premier_vide(g); i++) { + if(g->ligne[i] == u || g->col[i] == u) { return i; } } @@ -130,16 +103,12 @@ int graphe_find(graphe* g, int u) * @return un entier * O(n) */ -int graphe_get_plus_grand_sommet(graphe* g) -{ +int graphe_get_plus_grand_sommet(graphe* g) { int i, tmp, res = -1; - if(g) - { - for(i = 0; i < graphe_get_max(g); i++) - { + if(g) { + for(i = 0; i < graphe_get_max(g); i++) { tmp = max(g->ligne[i], g->col[i]); - if(tmp > res) - { + if(tmp > res) { res = tmp; } } @@ -153,17 +122,13 @@ int graphe_get_plus_grand_sommet(graphe* g) * @param i un des sommets de l'arête * @param j un des sommets de l'arête */ -void graphe_ajouter_arete(graphe* g, int i, int j) -{ - if(g) - { - if(graphe_get_premier_vide(g) == graphe_get_max(g)) - { +void graphe_ajouter_arete(graphe* g, int i, int j) { + if(g) { + if(graphe_get_premier_vide(g) == graphe_get_max(g)) { g->max *= 2; g->ligne = realloc(g->ligne, g->max * sizeof(int)); g->col = realloc(g->col, g->max * sizeof(int)); - for(int i = graphe_get_premier_vide(g); i < graphe_get_max(g); i++) - { + for(int i = graphe_get_premier_vide(g); i < graphe_get_max(g); i++) { g->ligne[i] = -1; g->col[i] = -1; } @@ -172,7 +137,6 @@ void graphe_ajouter_arete(graphe* g, int i, int j) g->col[graphe_get_premier_vide(g)] = j; g->premierVide++; } - //printf("graphe_ajouter_arete dans un graphe vide\n"); } @@ -182,34 +146,24 @@ void graphe_ajouter_arete(graphe* g, int i, int j) * @param j un des sommets de l'arête * O(n) */ -void graphe_supprimer_arete(graphe* g, int i, int j) -{ - if(g) - { +void graphe_supprimer_arete(graphe* g, int i, int j) { + if(g) { int cpt, flag = 0; - for(cpt = 0; cpt < graphe_get_premier_vide(g); cpt++) - { - if(flag) - { //On a trouvé l'arête et on l'a enlevée, donc maintenant il suffit de décaler le reste d'une case à gauche + for(cpt = 0; cpt < graphe_get_premier_vide(g); cpt++) { + if(flag) { //On a trouvé l'arête et on l'a enlevée, donc maintenant il suffit de décaler le reste d'une case à gauche g->ligne[cpt] = g->ligne[cpt+1]; g->col[cpt] = g->col[cpt+1]; } - else - { - if(g->ligne[cpt] == i && g->col[cpt] == j) - { - flag = 1; - g->ligne[cpt] = g->ligne[cpt+1]; - g->col[cpt] = g->col[cpt+1]; - } + else if(g->ligne[cpt] == i && g->col[cpt] == j) { + flag = 1; + g->ligne[cpt] = g->ligne[cpt+1]; + g->col[cpt] = g->col[cpt+1]; } } - if(flag) - { + if(flag) { g->premierVide--; } } - //printf("graphe_supprimer_arete dans un graphe vide\n"); } @@ -219,39 +173,29 @@ void graphe_supprimer_arete(graphe* g, int i, int j) * @param x le sommet à retirer * O(n) */ -void graphe_retirer_sommet(graphe* g, int x) -{ - if(g) - { +void graphe_retirer_sommet(graphe* g, int x) { + if(g) { int n = graphe_get_plus_grand_sommet(g), i; - if(x >= 0 && x < n) - { + if(x >= 0 && x < n) { int nbCasesVides = 0, *casesVides = (int*) calloc(sizeof(int), graphe_get_max(g)); - if(!casesVides) - { + if(!casesVides) { printf("Erreur allocation graphe_retirer_sommet (tableau casesVides)\n"); return; } - for(i=0; i < graphe_get_max(g); i++) - { + for(i=0; i < graphe_get_max(g); i++) { casesVides[i]--; } - for(i=0; i < graphe_get_max(g); i++) - { - if(g->ligne[i] == x || g->col[i] == x) - { //Une arête part de x, ou arrive en x, on retire le sommet donc tout part + for(i=0; i < graphe_get_max(g); i++) { + if(g->ligne[i] == x || g->col[i] == x) { //Une arête part de x, ou arrive en x, on retire le sommet donc tout part g->ligne[i] = -1; g->col[i] = -1; casesVides[nbCasesVides++] = i; } - else - { // Rien n'est supprimé, mais les indices des sommets > x sont décrémentés - if(g->ligne[i] > x) - { + else { // Rien n'est supprimé, mais les indices des sommets > x sont décrémentés + if(g->ligne[i] > x) { g->ligne[i]--; } - if(g->col[i] > x) - { + if(g->col[i] > x) { g->col[i]--; } } @@ -260,10 +204,8 @@ void graphe_retirer_sommet(graphe* g, int x) //Maintenant on a aucune trace du sommet x, mais plein de (-1 -1) où il était (ATTENTION ON PEUT ENCORE VOIR DES SOMMETS X, MAIS CE SONT LES ANCIENS SOMMETS X+1, CECI N'EST PAS UN BUG, NE PAS DÉBUGGER) //Il faut retasser tout ça - for(i = graphe_get_max(g) - 1; i >= 0 && nbCasesVides; i--) - { - if(g->ligne[i] != -1) - { //Pas une case vide, donc on peut l'échanger avec une case vide + for(i = graphe_get_max(g) - 1; i >= 0 && nbCasesVides; i--) { + if(g->ligne[i] != -1) { //Pas une case vide, donc on peut l'échanger avec une case vide g->ligne[casesVides[nbCasesVides-1]] = g->ligne[i]; g->col[casesVides[nbCasesVides-1]] = g->col[i]; nbCasesVides--; @@ -273,9 +215,7 @@ void graphe_retirer_sommet(graphe* g, int x) } free(casesVides); } - //printf("graphe_retirer_sommet hors limites [0; n-1]\n"); } - //printf("graphe_retirer_sommet dans un graphe vide\n"); } @@ -286,24 +226,16 @@ void graphe_retirer_sommet(graphe* g, int x) * @return 1 si les sommets sont adjacents et 0 sinon * O(n) */ -int graphe_voisins(graphe* g, int u, int v) -{ - if(g) - { +int graphe_voisins(graphe* g, int u, int v) { + if(g) { int max = graphe_get_plus_grand_sommet(g); - if(u >= 0 && v >= 0 && u <= max && v <= max) - { + if(u >= 0 && v >= 0 && u <= max && v <= max) { int i; - for(i = 0; i < graphe_get_premier_vide(g); i++) - { - if(g->ligne[i] == u && g->col[i] == v) - { - assert(g->ligne[i] == u && g->col[i] == v); + for(i = 0; i < graphe_get_premier_vide(g); i++) { + if(g->ligne[i] == u && g->col[i] == v) { return 1; } - if(g->ligne[i] == v && g->col[i] == u) - { - assert(g->ligne[i] == v && g->col[i] == u); + if(g->ligne[i] == v && g->col[i] == u) { return 1; } } @@ -320,19 +252,13 @@ int graphe_voisins(graphe* g, int u, int v) * @return 1 si v est un successeur de u et 0 sinon * O(n) */ -int graphe_est_succ(graphe* g, int u, int v) -{ - if(g) - { +int graphe_est_succ(graphe* g, int u, int v) { + if(g) { int max = graphe_get_plus_grand_sommet(g); - if(u >= 0 && v >= 0 && u <= max && v <= max) - { + if(u >= 0 && v >= 0 && u <= max && v <= max) { int i; - for(i = 0; i < graphe_get_premier_vide(g); i++) - { - if(g->ligne[i] == u && g->col[i] == v) - { - assert(g->ligne[i] == u && g->col[i] == v); + for(i = 0; i < graphe_get_premier_vide(g); i++) { + if(g->ligne[i] == u && g->col[i] == v) { return 1; } } @@ -346,59 +272,49 @@ int graphe_est_succ(graphe* g, int u, int v) * @param g un pointeur vers un graphe alloué en mémoire * O(n) */ -void graphe_afficher(graphe* g) -{ - if(g) - { +void graphe_afficher(graphe* g) { + if(g) { printf("Graphe à %d arêtes\n", graphe_get_premier_vide(g)); int lim = graphe_get_plus_grand_sommet(g)+1, i, v, w; int* matrice = (int*) calloc(sizeof(int), lim * lim); - if(!matrice) - { + if(!matrice) { printf("Erreur allocation graphe_afficher \n"); return; } - for(i = 0; i < g->premierVide; i++) - { + for(i = 0; i < g->premierVide; i++) { matrice[g->ligne[i] * lim + g->col[i]]++; // pas dans les 2 sens matrice[g->col[i] * lim + g->ligne[i]]++; } /* matrice d'adjacence faite */ /* ligne indices colonnes */ printf("\t\t"); - for(w = 0 ; w < lim ; w++) - { + for(w = 0 ; w < lim ; w++) { printf("%d\t", w); } printf("\n"); printf("\t\t"); - for(w = 0 ; w < lim ; w++) - { + for(w = 0 ; w < lim ; w++) { printf("_\t"); } printf("\n"); /* lignes de la matrice */ - for(v = 0 ; v < lim ; v++) - { + for(v = 0 ; v < lim ; v++) { printf("%d\t|\t", v); - for(w = 0 ; w < lim ; w++) - { + for(w = 0 ; w < lim ; w++) { printf("%d\t", matrice[v * lim + w]); } printf("|\n"); } printf("\t\t"); - for(w = 0 ; w < lim ; w++) - { + for(w = 0 ; w < lim ; w++) { printf("_\t"); } printf("\n"); free(matrice); } - else - { + else { printf("Erreur graphe_afficher Le graphe est NULL\n"); } } @@ -408,36 +324,28 @@ void graphe_afficher(graphe* g) * @param g un pointeur vers un graphe alloué en mémoire * O(n) */ -void graphe_afficher_tableaux(graphe* g) -{ +void graphe_afficher_tableaux(graphe* g) { int i; printf("\n======================"); printf("\nIndices\t\t"); - for(i = 0; i < graphe_get_max(g); i++) - { + for(i = 0; i < graphe_get_max(g); i++) { printf("| %2d ", i); } printf("\n\nlignes :\t"); - for(i = 0; i < graphe_get_max(g); i++) - { - if(i < graphe_get_premier_vide(g)) - { + for(i = 0; i < graphe_get_max(g); i++) { + if(i < graphe_get_premier_vide(g)) { printf("| %2d ", g->ligne[i]); } - else - { //Il ne devrait y avoir que des (-1) + else { //Il ne devrait y avoir que des (-1) printf("| (%d) ", g->ligne[i]); } } printf("\ncolonnes :\t"); - for(i = 0; i < graphe_get_max(g); i++) - { - if(i < graphe_get_premier_vide(g)) - { + for(i = 0; i < graphe_get_max(g); i++) { + if(i < graphe_get_premier_vide(g)) { printf("| %2d ", g->col[i]); } - else - { //Il ne devrait y avoir que des (-1) + else { //Il ne devrait y avoir que des (-1) printf("| (%d) ", g->col[i]); } } @@ -454,13 +362,10 @@ void graphe_afficher_tableaux(graphe* g) * -1 s'il y a eu une erreur d'ouverture du fichier, et -2 sinon * O(n) */ -int graphe_ecrire_dot(graphe* g, char* nomFichier) -{ - if(g) - { +int graphe_ecrire_dot(graphe* g, char* nomFichier) { + if(g) { int i, nbSommets = 0, n = graphe_get_premier_vide(g), sommetMax = graphe_get_plus_grand_sommet(g); - if(!n) - { + if(!n) { printf("Erreur premier vide = 0, graphe vide graphe_ecrire_dot\n"); return -2; } @@ -480,8 +385,7 @@ int graphe_ecrire_dot(graphe* g, char* nomFichier) 1 : sommet dans le graphe, il faudra l'ajouter dans le fichier dot Toutes les valeurs entières entre 0 et sommetMax inclus peuvent être dans le graphe */ - if(!flagSommet) - { + if(!flagSommet) { printf("Erreur allocation flagSommet graphe_ecrire_dot\n"); return -2; } @@ -492,34 +396,28 @@ int graphe_ecrire_dot(graphe* g, char* nomFichier) >= 0 : sommet dans le graphe, il faudra l'ajouter dans le fichier dot Il y a au max 2n sommets différents */ - if(!listeSommets) - { + if(!listeSommets) { printf("Erreur allocation listeSommets graphe_ecrire_dot\n"); free(flagSommet); return -2; } - for(i = 0; i < 2*n; i++) - { + for(i = 0; i < 2*n; i++) { listeSommets[i]--; //-1 partout } FILE *f = fopen(nomFichier, "w"); - if (!f) - { + if (!f) { free(flagSommet); free(listeSommets); printf("Erreur ouverture fichier \"%s\"graphe_ecrire_dot\n", nomFichier); return -1; } - for(i = 0; i < n; i++) - { - if(!flagSommet[g->ligne[i]]) //g->ligne[i] valait 0, donc le sommet n'était pas découvert - { + for(i = 0; i < n; i++) { + if(!flagSommet[g->ligne[i]]) { //g->ligne[i] valait 0, donc le sommet n'était pas découvert flagSommet[g->ligne[i]] = 1; listeSommets[nbSommets++] = g->ligne[i]; } - if(!flagSommet[g->col[i]]) //g->col[i] valait 0, donc le sommet n'était pas découvert - { + if(!flagSommet[g->col[i]]) { //g->col[i] valait 0, donc le sommet n'était pas découvert flagSommet[g->col[i]] = 1; listeSommets[nbSommets++] = g->col[i]; } @@ -528,13 +426,11 @@ int graphe_ecrire_dot(graphe* g, char* nomFichier) //Dans flagSommet, on a tous les flags indiquant si un sommet est dans le graphe ou non //Dans listeSommets on a la liste des sommets distincts fputs("graph {\n", f); - for(i = 0; i < nbSommets; i++) - { + for(i = 0; i < nbSommets; i++) { fprintf(f, "\t%d;\n", listeSommets[i]); } fputs("\n", f); - for(i = 0; i < n; i++) - { + for(i = 0; i < n; i++) { fprintf(f, "\t%d -- %d;\n", g->ligne[i], g->col[i]); } fputs("}\n", f); @@ -554,7 +450,6 @@ int graphe_ecrire_dot(graphe* g, char* nomFichier) * @return un entier, le plus grand des 2 paramètres * O(1) */ -int max(int x, int y) -{ +int max(int x, int y) { return (x > y) ? x : y; } -- GitLab From 53de159adb9659777d214ebd7f0ff4eaba8ce50d Mon Sep 17 00:00:00 2001 From: Nicolas Floquet Date: Tue, 30 Mar 2021 23:57:48 +0200 Subject: [PATCH 16/16] Pagerank liste_url.c refait --- pagerank/src/liste_url.c | 123 +++++++++++---------------------------- 1 file changed, 34 insertions(+), 89 deletions(-) diff --git a/pagerank/src/liste_url.c b/pagerank/src/liste_url.c index cd13040..1ee2e20 100644 --- a/pagerank/src/liste_url.c +++ b/pagerank/src/liste_url.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "liste_url.h" @@ -11,26 +10,17 @@ * @return 0 si la liste a été créée et -1 si n <= 0 et -2 s'il y a eu une erreur d'allocation * O(n) */ -int creer_liste(liste_url* l, int n) -{ - if(n <= 0) - { +int creer_liste(liste_url* l, int n) { + if(n <= 0) { printf("Erreur paramètre creer_liste, n <= 0\n"); return -1; } - if(!(l->urls = (char**) calloc(sizeof(char*), n))) - { + if(!(l->urls = (char**) calloc(sizeof(char*), n))) { printf("Erreur allocation creer_liste, l->urls\n"); return -2; } l->max = n; l->premierNULL = 0; - assert(l->max > 0); - assert(l->max == n); - assert(l->premierNULL == 0); - assert(l->premierNULL == 0); - assert(l->urls[0] == NULL); - assert(l->urls[l->max - 1] == NULL); return 0; } @@ -40,9 +30,7 @@ int creer_liste(liste_url* l, int n) * @return g->max un entier * O(1) */ -int liste_get_max(liste_url* l) -{ - assert(l->max > 0); +int liste_get_max(liste_url* l) { return l->max; } @@ -52,10 +40,7 @@ int liste_get_max(liste_url* l) * @return l->premierNULL un entier * O(1) */ -int liste_get_premier_NULL(liste_url* l) -{ - assert(l->premierNULL >= 0); - assert(l->premierNULL <= l->max); +int liste_get_premier_NULL(liste_url* l) { return l->premierNULL; } @@ -66,8 +51,7 @@ int liste_get_premier_NULL(liste_url* l) * @return 1 si l'URL est dans la liste et 0 sinon * O(n) */ -int liste_contains(liste_url* l, char* s) -{ +int liste_contains(liste_url* l, char* s) { return (liste_find(l, s) != -1); } @@ -78,19 +62,11 @@ int liste_contains(liste_url* l, char* s) * @return l'indice de l'URL si elle est dans la liste et -1 sinon * O(n) */ -int liste_find(liste_url* l, char* s) -{ - if(l && s) - { +int liste_find(liste_url* l, char* s) { + if(l && s) { int i; - for(i = 0; i < liste_get_premier_NULL(l); i++) - { - if(!strcmp(s, liste_get_i(l, i))) - { - assert(!strcmp(s, l->urls[i])); - assert(i >= 0); - assert(i < l->premierNULL); - assert(i < l->max); + for(i = 0; i < liste_get_premier_NULL(l); i++) { + if(!strcmp(s, liste_get_i(l, i))) { return i; } } @@ -105,12 +81,8 @@ int liste_find(liste_url* l, char* s) * @return l->urls[i] une chaîne de caractères si 0 <= i < liste_get_max(l), NULL sinon * O(1) */ -char* liste_get_i(liste_url* l, int i) -{ - if(0 <= i && i < liste_get_max(l)) - { - assert(i >= 0); - assert(i < l->max); +char* liste_get_i(liste_url* l, int i) { + if(0 <= i && i < liste_get_max(l)) { return l->urls[i]; } return NULL; @@ -122,17 +94,13 @@ char* liste_get_i(liste_url* l, int i) * @param s une chaîne, l'URL à ajouter * O(1) */ -void liste_add(liste_url* l, char* s) -{ - if(l) - { - if(liste_get_premier_NULL(l) == liste_get_max(l)) - { //Réallocation si nécessaire, complexité amortie en temps linéaire +void liste_add(liste_url* l, char* s) { + if(l) { + if(liste_get_premier_NULL(l) == liste_get_max(l)) { //Réallocation si nécessaire, complexité amortie en temps linéaire l->max *= 2; char** nouvelleListe = (char**) calloc(sizeof(char*), liste_get_max(l)); - for (int i = 0; i < liste_get_premier_NULL(l); i++) - { + for (int i = 0; i < liste_get_premier_NULL(l); i++) { nouvelleListe[i] = (char*) malloc(sizeof(char) * (strlen(l->urls[i]) + 1)); strcpy(nouvelleListe[i], l->urls[i]); free(l->urls[i]); @@ -145,7 +113,6 @@ void liste_add(liste_url* l, char* s) } l->urls[l->premierNULL] = (char*) calloc(sizeof(char), strlen(s)+1); strcpy(l->urls[l->premierNULL++], s); - assert(!strcmp(l->urls[l->premierNULL - 1], s)); } } @@ -155,43 +122,30 @@ void liste_add(liste_url* l, char* s) * @param s une chaîne, l'URL à retirer * O(n) */ -void liste_remove(liste_url* l, char* s) -{ - if(l && s) - { - int assertAncienneTaille = liste_get_premier_NULL(l); - int assertNouvelleTaille; +void liste_remove(liste_url* l, char* s) { + if(l && s) { int i, trouve = 0; - for(i = 0; i < liste_get_premier_NULL(l); i++) - { - if(!trouve && (!strcmp(s, liste_get_i(l, i)))) - { + for(i = 0; i < liste_get_premier_NULL(l); i++) { + if(!trouve && (!strcmp(s, liste_get_i(l, i)))) { free(liste_get_i(l, i)); - if(i+1 < liste_get_max(l)) - { + if(i+1 < liste_get_max(l)) { l->urls[i] = l->urls[i+1]; } - else - { + else { l->urls[i] = NULL; } trouve = 1; } - else if(trouve) - { - if(i+1 < liste_get_max(l)) - { + else if(trouve) { + if(i+1 < liste_get_max(l)) { l->urls[i] = l->urls[i+1]; } - else - { + else { l->urls[i] = NULL; } } } l->premierNULL--; - assertNouvelleTaille = liste_get_premier_NULL(l); - assert(trouve || (assertAncienneTaille == assertNouvelleTaille)); } } @@ -200,13 +154,10 @@ void liste_remove(liste_url* l, char* s) * @param l une liste d'url allouée en mémoire * O(n) */ -void liste_detruire(liste_url* l) -{ - if(l) - { +void liste_detruire(liste_url* l) { + if(l) { int i; - for(i = 0; i < liste_get_premier_NULL(l); i++) - { + for(i = 0; i < liste_get_premier_NULL(l); i++) { free(l->urls[i]); l->urls[i] = NULL; } @@ -219,26 +170,20 @@ void liste_detruire(liste_url* l) * @param l un pointeur vers une liste allouée en mémoire * O(n) */ -void liste_afficher(liste_url* l) -{ - if(l) - { +void liste_afficher(liste_url* l) { + if(l) { int i, n = liste_get_max(l); printf("i\t|\tURLs:\n"); - for(i = 0; i < n; i++) - { - if(i < liste_get_premier_NULL(l)) - { + for(i = 0; i < n; i++) { + if(i < liste_get_premier_NULL(l)) { printf("%d \t|\t\"%s\"\n", i, liste_get_i(l, i)); } - else - { + else { printf("%d \t|\tNULL\n", i); } } } - else - { + else { printf("La liste est NULL\n"); } } -- GitLab