diff --git a/Makefile b/Makefile index 492fddf376b92b93390529f5de460efabc5d356d..4c47334a9289017e992095e1b082cb132ab9d70e 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ TP1: TP1.o file.o TP2: TP2.o struct_tp2.o $(CC) $(OPTIONS) -o $@ $^ $(MATH) -g -TP3: TP3.o plotout.o +TP3: TP3.o plotout.o file.o $(CC) $(OPTIONS) -o $@ $^ $(MATH) -g TP4: TP4.o diff --git a/TP1 b/TP1 index b6d00fefb1ec8b3b30bb4af7a13066bb9eac6402..122f217d6fcaf97f4b177fd9e7e99deaf2116a7f 100755 Binary files a/TP1 and b/TP1 differ diff --git a/TP2 b/TP2 index 8c90ef31e5334fcce47f26e929f863d6d82585a1..9099ac9b2dbc979d06b03ab0134fdc79ab8fa6fe 100755 Binary files a/TP2 and b/TP2 differ diff --git a/TP3 b/TP3 index 2c865c5723dcb9cea539ca0d5767943ff098fea6..98db9dcd6f1a44675eb4af731a5a225a19aa83c8 100755 Binary files a/TP3 and b/TP3 differ diff --git a/TP3.c b/TP3.c index 7f94b4aac53952a0c2e475b568db57edb2511d30..ad59b6eb42d63fce9a215d498e3906f293843b42 100644 --- a/TP3.c +++ b/TP3.c @@ -1,5 +1,6 @@ #include "./implems.c" #include "./plotout.h" +#include "./file.h" #include <stdio.h> #include <stdlib.h> #include <limits.h> @@ -109,6 +110,256 @@ int pagerank(edgelist *g, long double *distr_res, long double alpha, unsigned lo } +// fonction réalisant nb_iter itérations de personalized power pagerank +// distr_res doit être malloc de taille g-> +// p0 doit être un vecteur de probabilités de taille g->n dont la somme est 1 +int pers_pagerank(edgelist *g, long double *distr_res, long double *p0, long double alpha, unsigned long nb_iter) { + unsigned long i, j; + unsigned long *out_deg; + long double *prob_t = distr_res; + long double *prob_t1; + long double *swap_pointeur; + out_deg = (unsigned long*) malloc((g->n)*sizeof(unsigned long)); + prob_t1 = (long double*) malloc((g->n)*sizeof(long double)); + + + + // calcul les degrés sortants + calc_out_deg(g, out_deg); + + + // initialisation des probas + for (i = 0; i < g->n; i += 1) { + prob_t[i] = 1./((long double) (g->n)); + } + + + // itérations de PageRank + for (i = 0; i < nb_iter; i += 1) { + // mise à zero de prob_t1 + for (j = 0; j < g->n; j += 1) { + prob_t1[j] = 0; + } + + // itération sur les arêtes pour chaque quantité + for (j = 0; j < g->e; j += 1) { + prob_t1[g->edges[j].t] += (1 - alpha)*(prob_t[g->edges[j].s]/out_deg[g->edges[j].s]); + } + + // ajout du poids alpha en plus (pondéré par P0) /!\ remise à n pour le poid de P0 + for (j = 0; j < g->n; j +=1) { + prob_t1[j] += alpha*p0[j]; // renvoie une proportion alpha sur p0 + // prob_t1[j] += alpha*(1./((long double) (g->n))); // renvoie une proportion alpha dans le reste du tableau + } + + // renormalisation du vecteur (avec poid pondéré par P0) /!\ remise à n pour le poid de p0 + long double v = 0; + for (j = 0; j < g->n; j += 1) { + v += prob_t1[j]; + } + long double vprim = (1-v)/((long double) (g->n)); + v = (1-v); + for (j = 0; j < g->n; j += 1) { + // prob_t1[j] += v*p0[j]; // normalise uniquement sur les composantes de P0 + prob_t1[j] += vprim; // normalise sur la totalité du vecteur + } + // échange des pointeurs pour prochaine itération + swap_pointeur = prob_t; + prob_t = prob_t1; + prob_t1 = swap_pointeur; + } + // si nombre impair d'itération, copie du résultat final dans le bon tableau + if (nb_iter%2 == 1) { + for (i = 0; i < g->n; i += 1) { + distr_res[i] = prob_t[i]; + } + free(prob_t); + } + else { + free(prob_t1); + } + free(out_deg); + return 0; +} + + + +// fonction déterminant quels noeuds sont dans la catégorie donnée +// requires + // node_res est un tableau de taille g->n + // filepath est le chemin vers le fichier d'association noeud ID -> category ID +// ensures + // node_res contient 1 si le noeud est dans la catégorie demandée, 0 sinon + +int mark_in_cat(edgelist *g, unsigned long *node_res, char *filepath, char *filecatdir, unsigned long cat_wanted) { + // parcour en largeur pour trouver les sous catégories de échec + adjlist *cat_graph; + cat_graph = al_readedgelist(filecatdir); + mkadjlist(cat_graph); + + // fait un BFS + // ################################ + file_t F = new_file(cat_graph->n); + int *marked = (int *)malloc((cat_graph->n) * sizeof(int)); + for (unsigned long i = 0; i < cat_graph->n; i++) + { + marked[i] = -1; + } + enfile(F, cat_wanted); + marked[cat_wanted] = 0; + unsigned long tmp = cat_wanted; + while (!is_empty(F)) + { + tmp = defile(F); + // printf("%li %li %li %li\n", tmp, marked[tmp], cat_graph->cd[tmp], cat_graph->cd[tmp+1]); + for (unsigned long i = cat_graph->cd[tmp]; i < cat_graph->cd[tmp + 1]; i++) + { + if (marked[cat_graph->adj[i]] == -1) + { + if (enfile(F, cat_graph->adj[i]) == 1) + { + marked[cat_graph->adj[i]] = marked[tmp] + 1; + } + else + { + printf("\n\nPile trop petite !\n\n"); + } + } + } + } + unsigned long no_marque = 0; + for (unsigned long i = 0; i < cat_graph->n; i++) + { + if (marked[i] == -1 && cat_graph->cd[0] != 0) + { + no_marque++; + } + } + // ################################ + + + + // trouve les noeuds qui ont été marqués + int count_cat = 0; + for (unsigned long i = 0; i < cat_graph->n; i += 1) { + if (marked[i] != -1) { + count_cat += 1; + } + } + + printf("cat : %lu related nb : %i/%lu\n", cat_wanted, count_cat, cat_graph->n); + + + + free_adjlist(cat_graph); + // --------------------------------------------------------------------- + // --------------------------------marked != -1 si subcat de wanted_cat--- + // --------------------------------------------------------------------- + + + + + // mise à zero du tableau resultat + for (unsigned long i = 0; i < g->n; i += 1) { + node_res[i] = 0; + } + + unsigned long node_ID, cat_ID; + char test_end; + + // lis le fichier d'entrée + FILE *file = fopen(filepath, "r"); + char line[1000]; + // ignore les premières lignes de commentaire + while(fgets(line, sizeof line, file) && *line == '#') {} + + // lit les entrées + while(fscanf(file, "%lu%c", &node_ID, &test_end) == 2) { + // printf("node start : %lu\n", node_ID); + if (test_end != '\n') { + while(fscanf(file, "%lu%c", &cat_ID, &test_end)==2) { + // printf("lié à %lu\n", cat_ID); + if (marked[cat_ID] != -1) { + // printf("ouais !\n"); + node_res[node_ID] = 1; + } + if (test_end == '\n') {break;} + } + } + } + + + + free(marked); + return 0; +} + + +// trouve les subcatégories de la catégorie passée en paramètre +int find_sub_cat(char *filecatdir, unsigned long cat_wanted) { + adjlist *cat_graph; + cat_graph = al_readedgelist(filecatdir); + mkadjlist(cat_graph); + + // fait un BFS + // ################################ + file_t F = new_file(cat_graph->n); + int *marked = (int *)malloc((cat_graph->n) * sizeof(int)); + for (unsigned long i = 0; i < cat_graph->n; i++) + { + marked[i] = -1; + } + enfile(F, cat_wanted); + marked[cat_wanted] = 0; + unsigned long tmp = cat_wanted; + while (!is_empty(F)) + { + tmp = defile(F); + // printf("%li %li %li %li\n", tmp, marked[tmp], cat_graph->cd[tmp], cat_graph->cd[tmp+1]); + for (unsigned long i = cat_graph->cd[tmp]; i < cat_graph->cd[tmp + 1]; i++) + { + if (marked[cat_graph->adj[i]] == -1) + { + if (enfile(F, cat_graph->adj[i]) == 1) + { + marked[cat_graph->adj[i]] = marked[tmp] + 1; + } + else + { + printf("\n\nPile trop petite !\n\n"); + } + } + } + } + unsigned long no_marque = 0; + for (unsigned long i = 0; i < cat_graph->n; i++) + { + if (marked[i] == -1 && cat_graph->cd[0] != 0) + { + no_marque++; + } + } + // ################################ + + + + // trouve les noeuds qui ont été marqués + int count_cat = 0; + for (unsigned long i = 0; i < cat_graph->n; i += 1) { + if (marked[i] != -1) { + count_cat += 1; + } + } + + printf("cat : %lu related nb : %i/%lu\n", cat_wanted, count_cat, cat_graph->n); + + + + free(marked); + free_adjlist(cat_graph); + return 1; +} + void debug_print_tabl(long double *tab) { @@ -214,75 +465,157 @@ int main(int argc, char **argv) { // printf("- Overall time = %I64dh%I64dm%I64ds\n",(t2-t1)/3600,((t2-t1)%3600)/60,((t2-t1)%60)); + + + + + // fonctions du TP3 + // long double *p_distrib; + // unsigned long *highest; + // unsigned long *lowest; + // p_distrib = (long double*) malloc((g->n)*sizeof(long double)); + // highest = (unsigned long*) malloc(5*sizeof(unsigned long)); + // lowest = (unsigned long*) malloc(5*sizeof(unsigned long)); + + + // pagerank(g, p_distrib, 0.15, 70); + + + // find_5(g, p_distrib, lowest, highest); + + + + + + // //TABLEAUX pour les CORRELATIONS + + // long double *p_15 = p_distrib; + // long double *p_1; + // long double *p_2; + // long double *p_5; + // long double *p_9; + // unsigned long *out_deg; + // unsigned long *in_deg; + + // p_1 = (long double*) malloc((g->n)*sizeof(long double)); + // p_2 = (long double*) malloc((g->n)*sizeof(long double)); + // p_5 = (long double*) malloc((g->n)*sizeof(long double)); + // p_9 = (long double*) malloc((g->n)*sizeof(long double)); + // out_deg = (unsigned long*) malloc((g->n)*sizeof(unsigned long)); + // in_deg = (unsigned long*) malloc((g->n)*sizeof(unsigned long)); + + // printf("out_deg processing...\n"); + // calc_out_deg(g, out_deg); + // printf("in_deg processing...\n"); + // calc_in_deg(g, in_deg); + // printf("pagerank 0.1 processing...\n"); + // pagerank(g, p_1, 0.1, 70); + // printf("pagerank 0.2 processing...\n"); + // pagerank(g, p_2, 0.2, 70); + // printf("pagerank 0.5 processing...\n"); + // pagerank(g, p_5, 0.5, 70); + // printf("pagerank 0.9 processing...\n"); + // pagerank(g, p_9, 0.9, 70); + + + // printf("output plots ...\n"); + // plot_out_2D_ld_ul("1.csv", g->n, p_15, in_deg); + // plot_out_2D_ld_ul("2.csv", g->n, p_15, out_deg); + // plot_out_2D_ld_ld("3.csv", g->n, p_15, p_1); + // plot_out_2D_ld_ld("4.csv", g->n, p_15, p_2); + // plot_out_2D_ld_ld("5.csv", g->n, p_15, p_5); + // plot_out_2D_ld_ld("6.csv", g->n, p_15, p_9); + + + // free(p_1); + // free(p_2); + // free(p_5); + // free(p_9); + // free(p_15); + + + + + + + + + + // personalized PAGERANK + + // ################# DATA ############## + // ID of category chess : 691713 + // ID of page Magnus carlsen : 442682 + // ID of category boxing : 738624 + // ##################################### + + long double *p_distrib; - unsigned long *highest; - unsigned long *lowest; + long double *p0_magnus; + unsigned long *nodes; + unsigned long *nodes_2; p_distrib = (long double*) malloc((g->n)*sizeof(long double)); - highest = (unsigned long*) malloc(5*sizeof(unsigned long)); - lowest = (unsigned long*) malloc(5*sizeof(unsigned long)); + nodes = (unsigned long*) malloc((g->n)*sizeof(unsigned long)); + nodes_2 = (unsigned long*) malloc((g->n)*sizeof(unsigned long)); + + printf("finding nodes related to chess category...\n"); + mark_in_cat(g, nodes, "../alr21--pageCategList--enwiki--20071018.txt", "../alr21--categDAG--dirLinks--enwiki-20071018.txt", 691713); + + - pagerank(g, p_distrib, 0.15, 70); - find_5(g, p_distrib, lowest, highest); + // ROOTED PAGERANK of MAGNUS CARLSEN + p0_magnus = (long double*) malloc((g->n)*sizeof(long double)); + for (unsigned long i = 0; i < g->n; i += 1) { + p0_magnus[i] = 0; + } + p0_magnus[442682] = 1; //page magnus carlsen + printf("computing rooted pagerank of Magnus Carlsen...\n"); + pers_pagerank(g, p_distrib, p0_magnus, 0.55, 50); + plot_out_2D_ld_ul("magnus.csv", g->n, p_distrib, nodes); - // TABLEAUX pour les CORRELATIONS - long double *p_15 = p_distrib; - long double *p_1; - long double *p_2; - long double *p_5; - long double *p_9; - unsigned long *out_deg; - unsigned long *in_deg; - p_1 = (long double*) malloc((g->n)*sizeof(long double)); - p_2 = (long double*) malloc((g->n)*sizeof(long double)); - p_5 = (long double*) malloc((g->n)*sizeof(long double)); - p_9 = (long double*) malloc((g->n)*sizeof(long double)); - out_deg = (unsigned long*) malloc((g->n)*sizeof(unsigned long)); - in_deg = (unsigned long*) malloc((g->n)*sizeof(unsigned long)); - printf("out_deg processing...\n"); - calc_out_deg(g, out_deg); - printf("in_deg processing...\n"); - calc_in_deg(g, in_deg); - printf("pagerank 0.1 processing...\n"); - pagerank(g, p_1, 0.1, 70); - printf("pagerank 0.2 processing...\n"); - pagerank(g, p_2, 0.2, 70); - printf("pagerank 0.5 processing...\n"); - pagerank(g, p_5, 0.5, 70); - printf("pagerank 0.9 processing...\n"); - pagerank(g, p_9, 0.9, 70); - - - printf("output plots ...\n"); - plot_out_2D_ld_ul("1.csv", g->n, p_15, in_deg); - plot_out_2D_ld_ul("2.csv", g->n, p_15, out_deg); - plot_out_2D_ld_ld("3.csv", g->n, p_15, p_1); - plot_out_2D_ld_ld("4.csv", g->n, p_15, p_2); - plot_out_2D_ld_ld("5.csv", g->n, p_15, p_5); - plot_out_2D_ld_ld("6.csv", g->n, p_15, p_9); - - // long double last = p_distrib[0]; - // for(unsigned long i =0; i < g->n; i +=1) { - // if (last != p_distrib[i]) { - // printf("|%Le|\n", p_distrib[i]); - // } - // } - - free(p_1); - free(p_2); - free(p_5); - free(p_9); - free(p_15); + + + + // restart vector for chess && boxing + printf("finding nodes related to boxing category...\n"); + mark_in_cat(g, nodes_2, "../alr21--pageCategList--enwiki--20071018.txt", "../alr21--categDAG--dirLinks--enwiki-20071018.txt", 738624); + + printf("construct of the chess/boxing restart vector ...\n"); + long double *p0_chess_box = p0_magnus; + unsigned long count = 0; + for (unsigned long i = 0; i < g->n; i += 1) { + count += nodes[i] + nodes_2[i]; + p0_chess_box[i] = nodes[i] + nodes_2[i]; + } + for (unsigned long i = 0; i < g->n; i += 1) { + p0_chess_box[i] = p0_chess_box[i]/count; + } + + printf("computing personalized pagerank of chess and box...\n"); + pers_pagerank(g, p_distrib, p0_chess_box, 0.15, 50); + + for (unsigned long i = 0; i < g->n; i += 1) { + if (nodes[i] == 1 || nodes_2[i] == 1) { + nodes[i] = 1; + } + } + + plot_out_2D_ld_ul("chessbox.csv", g->n, p_distrib, nodes); + + + free(nodes); + free(p_distrib); return 0; } \ No newline at end of file diff --git a/chessbox.csv b/chessbox.csv new file mode 100644 index 0000000000000000000000000000000000000000..78c1fd5ee7b05b55ae83614f490467c289a24e77 Binary files /dev/null and b/chessbox.csv differ diff --git a/magnus.csv b/magnus.csv new file mode 100644 index 0000000000000000000000000000000000000000..6035dffd4d9fd6603e795d0b9c73bc061f8bbe28 Binary files /dev/null and b/magnus.csv differ diff --git a/plotout.h b/plotout.h index 1df89a41b32d4b1b72611ece2e71ce09ee0cf634..252aaea6f180ae34831b08707983da3613704404 100644 --- a/plotout.h +++ b/plotout.h @@ -10,5 +10,4 @@ int plot_out_2D_ld_ul(char* name, unsigned long size, long double *x, unsigned l int plot_out_2D_ld_ld(char* name, unsigned long size, long double *x, long double *y); - #endif \ No newline at end of file diff --git a/trace_graphe.py b/trace_graphe.py index ab82dab241717d8a93a330d3cef18f5891bf82aa..cebdcb324995a021787f621e082b4b17f07e60b2 100644 --- a/trace_graphe.py +++ b/trace_graphe.py @@ -21,21 +21,18 @@ data = pd.read_csv("../plots/1.csv", sep=",") #plot des données -plt.scatter(data['x'], data['y']) +#plt.scatter(data['x'], data['y']) +plt.plot(data['x'], data['y'], 'o') #plot de la régression linéaire m, b = np.polyfit(data['x'], data['y'], 1) -plt.plot(data['x'], m*data['x']+b, color = "red") - - +plt.plot(data['x'], m*data['x']+b, 'r.') -plt.xlim(0,0.0025) -plt.ylim(0,250000) +plt.xscale("log") +plt.yscale("log") +#plt.xlim(0, 0.0025) +plt.ylim(1, 200000) - - -plt.xscale("linear") -plt.yscale("linear") #valeurs d'échelle : {"linear", "log", "symlog", "logit", ...} plt.title("degré entrant en fonction de pagerank") @@ -43,6 +40,9 @@ plt.xlabel("pagerank (α = 0.15)") plt.ylabel("degré entrant") +plt.savefig("1.png", dpi=100, format = 'png') + + plt.show() @@ -52,13 +52,26 @@ plt.show() # PLOT 2 ########################## data = pd.read_csv("../plots/2.csv", sep=",") -plt.scatter(data['x'], data['y']) + + +#plt.scatter(data['x'], data['y']) +plt.plot(data['x'], data['y'], 'o') + +#plot de la régression linéaire +m, b = np.polyfit(data['x'], data['y'], 1) +plt.plot(data['x'], m*data['x']+b, 'r.') + +plt.xscale("log") +plt.yscale("log") plt.title("degré sortant en fonction de pagerank") plt.xlabel("pagerank (α = 0.15)") plt.ylabel("degré sortant") -plt.xlim(0,0.0035) +#plt.xlim(0,0.0020) + + +plt.savefig("2.png", dpi=100, format = 'png') @@ -69,15 +82,24 @@ plt.show() # PLOT 3 ########################## data = pd.read_csv("../plots/3.csv", sep=",") -plt.scatter(data['x'], data['y']) + + +plt.plot(data['x'], data['y'], 'o') + +#plot de la régression linéaire +m, b = np.polyfit(data['x'], data['y'], 1) +plt.plot(data['x'], m*data['x']+b, 'r.', markersize=10) + +plt.xscale("log") +plt.yscale("log") plt.title("pagerank (α = 0.15) vs pagerank (α = 0.1)") plt.xlabel("pagerank (α = 0.15)") plt.ylabel("pagerank (α = 0.1)") -plt.xlim(0,0.0035) -plt.ylim(0,0.005) +plt.savefig("3.png", dpi=100, format = 'png') + plt.show() @@ -86,15 +108,24 @@ plt.show() # PLOT 4 ########################## data = pd.read_csv("../plots/4.csv", sep=",") + + plt.scatter(data['x'], data['y']) +#plot de la régression linéaire +m, b = np.polyfit(data['x'], data['y'], 1) +#plt.plot(data['x'], m*data['x']+b, 'r.') + +plt.xscale("log") +plt.yscale("log") + plt.title("pagerank (α = 0.15) vs pagerank (α = 0.2)") plt.xlabel("pagerank (α = 0.15)") plt.ylabel("pagerank (α = 0.2)") -plt.xlim(0,0.0035) -plt.ylim(0,0.005) +plt.savefig("4.png", dpi=100, format = 'png') + plt.show() @@ -103,13 +134,22 @@ plt.show() # PLOT 5 ########################## data = pd.read_csv("../plots/5.csv", sep=",") + + plt.scatter(data['x'], data['y']) +#plot de la régression linéaire +m, b = np.polyfit(data['x'], data['y'], 1) +#plt.plot(data['x'], m*data['x']+b, 'r.') + +plt.xscale("log") +plt.yscale("log") + plt.title("pagerank (α = 0.15) vs pagerank (α = 0.5)") plt.xlabel("pagerank (α = 0.15)") plt.ylabel("pagerank (α = 0.5)") -plt.xlim(0,0.0035) -plt.ylim(0,0.0025) + +plt.savefig("5.png", dpi=100, format = 'png') @@ -120,14 +160,127 @@ plt.show() # PLOT 6 ########################## data = pd.read_csv("../plots/6.csv", sep=",") + + plt.scatter(data['x'], data['y']) + +#plot de la régression linéaire +m, b = np.polyfit(data['x'], data['y'], 1) +#plt.plot(data['x'], m*data['x']+b, 'r.') + +plt.xscale("log") +plt.yscale("log") + + plt.title("pagerank (α = 0.15) vs pagerank (α = 0.9)") plt.xlabel("pagerank (α = 0.15)") plt.ylabel("pagerank (α = 0.9)") -plt.xlim(0,0.0035) -plt.ylim(0,0.0005) + +plt.savefig("6.png", dpi=100, format = 'png') + +plt.show() + + + + + + + + + + + + + + +########################## +# MAGNUS plot +########################## + + +data_magnus = pd.read_csv("./magnus.csv", sep = ",") +work = data_magnus.sort_values(by = 'x', ascending = False) +ord_pagerank = list(work['x']) +ord_incat = list(work['y']) + +fig, axs = plt.subplots(2, sharex=True) +fig.suptitle('Corrélation entre la proximité aux noeuds et les catégories') +axs[0].plot(range(len(ord_pagerank)), ord_pagerank) + +axs[0].set_xscale("log") +axs[0].set_yscale("log") + + +summed_incat = [] +sum = 0 +for i in range(len(ord_incat)): + sum += ord_incat[i] + summed_incat.append(sum) + + + + + +axs[1].plot(range(len(summed_incat)), summed_incat) +axs[1].set_xscale("log") +axs[1].set_yscale("linear") +axs[0].axvline(x = 2000000, color = "black", linestyle='--') +axs[1].axvline(x = 2000000, color = "black", linestyle='--') + + +axs[1].set_xlabel("Rang du noeud") +axs[0].set_ylabel("Proximité au noeud \"magnus carlsen\"") +axs[1].set_ylabel("Nombre de noeuds dans les sous-catégories de \"échec\"") + + +plt.show() + + + + + +########################## +# CHESS & BOX plot +########################## + + +data_magnus = pd.read_csv("./chessbox.csv", sep = ",") +work = data_magnus.sort_values(by = 'x', ascending = False) +ord_pagerank = list(work['x']) +ord_incat = list(work['y']) + +fig, axs = plt.subplots(2, sharex=True) +fig.suptitle('Personalized pagerank avec un vecteur p0 orienté échec ou box') +axs[0].plot(range(len(ord_pagerank)), ord_pagerank) + +axs[0].set_xscale("log") +axs[0].set_yscale("log") + + +summed_incat = [] +sum = 0 +for i in range(len(ord_incat)): + sum += ord_incat[i] + summed_incat.append(sum) + + + + + +axs[1].plot(range(len(summed_incat)), summed_incat) +axs[1].set_xscale("log") +axs[1].set_yscale("linear") +axs[0].axvline(x = 2000000, color = "black", linestyle='--') +axs[1].axvline(x = 2000000, color = "black", linestyle='--') + + +axs[1].set_xlabel("Rang du noeud") +axs[0].set_ylabel("Valeur du pagerank") +axs[1].set_ylabel("Nombre de noeuds dans les sous-catégories de \"échec\" et \"box\"") + + +plt.show() -plt.show() \ No newline at end of file