Skip to content
Extraits de code Groupes Projets
Valider ac2faf8c rédigé par Louis Fourcade's avatar Louis Fourcade
Parcourir les fichiers

correction triangles

parent c1733cc8
Branches
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -17,7 +17,7 @@ $(EXECUTABLE): main.o
$(CC) $(OPTIONS) -o $@ $^ $(MATH) -g
main.o: adjarray.c
main.o: implems.c
%.o: %.c
$(CC) $(OPTIONS) -c $^ -g
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <time.h>//to estimate the runing time
#define NLINKS 100000000 //maximum number of edges for memory allocation, will increase if needed
typedef struct {
unsigned long s;
unsigned long t;
} edge;
//edge list structure:
typedef struct {
unsigned long n;//number of nodes
unsigned long e;//number of edges
edge *edges;//list of edges
} edgelist;
//adj list structure:
typedef struct {
unsigned long n;//number of nodes
unsigned long e;//number of edges
edge *edges;//list of edges
bool *mat;//adjacency matrix
} adjmatrix;
//adj array structure:
typedef struct {
unsigned long n;//number of nodes
unsigned long e;//number of edges
edge *edges;//list of edges
unsigned long *cd;//cumulative degree cd[0]=0 length=n+1
unsigned long *adj;//concatenated lists of neighbors of all nodes
} adjlist;
//compute the maximum of three unsigned long
inline unsigned long max3(unsigned long a,unsigned long b,unsigned long c){
a=(a>b) ? a : b;
return (a>c) ? a : c;
}
//reading the edgelist from file
edgelist* el_readedgelist(char* input){
unsigned long e1=NLINKS;
FILE *file=fopen(input,"r");
edgelist *g=malloc(sizeof(edgelist));
g->n=0;
g->e=0;
g->edges=malloc(e1*sizeof(edge));//allocate some RAM to store edges
char line[1000];
while (fgets(line, sizeof line, file)) {
// ignore les commentaires #
if (*line == '#') {continue;}
// récupère les données
if (sscanf(line, "%lu %lu", &(g->edges[g->e].s), &(g->edges[g->e].t))==2) {
g->n=max3(g->n,g->edges[g->e].s,g->edges[g->e].t);
if (++(g->e)==e1) {//increase allocated RAM if needed
e1+=NLINKS;
g->edges=realloc(g->edges,e1*sizeof(edge));
}
}
}
fclose(file);
g->n++;
g->edges=realloc(g->edges,g->e*sizeof(edge));
return g;
}
//reading the edgelist from file
adjmatrix* am_readedgelist(char* input){
unsigned long e1=NLINKS;
FILE *file=fopen(input,"r");
adjmatrix *g=malloc(sizeof(adjmatrix));
g->n=0;
g->e=0;
g->edges=malloc(e1*sizeof(edge));//allocate some RAM to store edges
char line[1000];
while (fgets(line, sizeof line, file)) {
// ignore les commentaires #
if (*line == '#') {continue;}
// récupère les données
if (sscanf(line, "%lu %lu", &(g->edges[g->e].s), &(g->edges[g->e].t))==2) {
g->n=max3(g->n,g->edges[g->e].s,g->edges[g->e].t);
if (++(g->e)==e1) {//increase allocated RAM if needed
e1+=NLINKS;
g->edges=realloc(g->edges,e1*sizeof(edge));
}
}
}
fclose(file);
g->n++;
g->edges=realloc(g->edges,g->e*sizeof(edge));
return g;
}
//reading the edgelist from file
adjlist* al_readedgelist(char* input){
unsigned long e1=NLINKS;
FILE *file=fopen(input,"r");
adjlist *g=malloc(sizeof(adjlist));
g->n=0;
g->e=0;
g->edges=malloc(e1*sizeof(edge));//allocate some RAM to store edges
char line[1000];
while (fgets(line, sizeof line, file)) {
// ignore les commentaires #
if (*line == '#') {continue;}
// récupère les données
if (sscanf(line, "%lu %lu", &(g->edges[g->e].s), &(g->edges[g->e].t))==2) {
g->n=max3(g->n,g->edges[g->e].s,g->edges[g->e].t);
if (++(g->e)==e1) {//increase allocated RAM if needed
e1+=NLINKS;
g->edges=realloc(g->edges,e1*sizeof(edge));
}
}
}
fclose(file);
g->n++;
g->edges=realloc(g->edges,g->e*sizeof(edge));
return g;
}
//building the adjacency matrix
void mkmatrix(adjmatrix* g){
unsigned long i,u,v;
g->mat=calloc(g->n*g->n,sizeof(bool));
for (i=0;i<g->e;i++){
u=g->edges[i].s;
v=g->edges[i].t;
g->mat[u+g->n*v]=1;
g->mat[v+g->n*u]=1;
}
}
//building the adjacency array
void mkadjlist(adjlist* g){
unsigned long i,u,v;
unsigned long *d=calloc(g->n,sizeof(unsigned long));
for (i=0;i<g->e;i++) {
d[g->edges[i].s]++;
d[g->edges[i].t]++;
}
g->cd=malloc((g->n+1)*sizeof(unsigned long));
g->cd[0]=0;
for (i=1;i<g->n+1;i++) {
g->cd[i]=g->cd[i-1]+d[i-1];
d[i-1]=0;
}
g->adj=malloc(2*g->e*sizeof(unsigned long));
for (i=0;i<g->e;i++) {
u=g->edges[i].s;
v=g->edges[i].t;
g->adj[ g->cd[u] + d[u]++ ]=v;
g->adj[ g->cd[v] + d[v]++ ]=u;
}
free(d);
//free(g->edges);
}
//freeing memory
void free_edgelist(edgelist *g){
free(g->edges);
free(g);
}
void free_adjmatrix(adjmatrix *g){
free(g->edges);
free(g->mat);
free(g);
}
void free_adjlist(adjlist *g){
free(g->edges);
free(g->cd);
free(g->adj);
free(g);
}
#include "adjarray.c"
#include "implems.c"
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
......@@ -8,6 +8,118 @@
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// Triangle
// structure de triangles (contient trois noeuds)
typedef struct {
unsigned long a;
unsigned long b;
unsigned long c;
} triangle;
// compte le nombre de trianges dans le graphe
// itère sur chaque arêtes
// - récupère les voisins de chaques cotés
// - si les deux sommets ont un voisin plus grand, en commun, on ajoute un triangle
int count_triangles(adjlist* g) {
printf("fonction de compte des triangles\n");
int res_nb_tri = 0;
// itère sur les arêts
for (unsigned long e = 0; e < g->e; e++) {
// récupère les deux voisins
unsigned long v1 = g->edges[e].s;
unsigned long v2 = g->edges[e].t;
// récupère la liste des voisins ainsi que leurs nombres pour v1 et pour v2
unsigned long v1_neigh_start;
unsigned long v2_neigh_start;
unsigned long v1_neigh_end;
unsigned long v2_neigh_end;
v1_neigh_start = g->cd[v1];
v2_neigh_start = g->cd[v2];
v1_neigh_end = g->cd[v1+1];
v2_neigh_end = g->cd[v2+1];
// on peut améliorer cette recherche si on considère les liste des voisins triées
// ajoute un triangle si sommet plus grand en commun
for (unsigned long i = 0; i < v1_neigh_end - v1_neigh_start; i++) {
for (unsigned long j = 0; j < v2_neigh_end - v2_neigh_start; j++) {
unsigned long vois_1 = g->adj[i + v1_neigh_start];
unsigned long vois_2 = g->adj[j + v2_neigh_start];
if (vois_1 == vois_2) {
if (vois_1 > v1 && vois_1 > v2) {
res_nb_tri += 1;
}
}
}
}
}
return res_nb_tri;
}
// compte le nombre de trianges dans le graphe
// itère sur chaque arêtes
// - récupère les voisins de chaques cotés
// - si les deux sommets ont un voisin plus petit en commun, on ajoute un triangle
int count_triangles_opt(adjlist* g) {
printf("fonction de compte des triangles\n");
int res_nb_tri = 0;
// itère sur les arêts
for (unsigned long e = 0; e < g->e; e++) {
// récupère les deux voisins
unsigned long v1 = g->edges[e].s;
unsigned long v2 = g->edges[e].t;
// récupère la liste des voisins ainsi que leurs nombres pour v1 et pour v2
unsigned long v1_neigh_start;
unsigned long v2_neigh_start;
unsigned long v1_neigh_end;
unsigned long v2_neigh_end;
v1_neigh_start = g->cd[v1];
v2_neigh_start = g->cd[v2];
v1_neigh_end = g->cd[v1+1];
v2_neigh_end = g->cd[v2+1];
unsigned long i = v1_neigh_start;
unsigned long j = v2_neigh_start;
// version opt, suppose que les voisins sont triés par ordre croissants
while(g->adj[i] < v1 && i < v1_neigh_end) {
j = v2_neigh_start;
while(g->adj[j] < v2 && j < v2_neigh_end) {
if (g->adj[i] == g->adj[j]) {
res_nb_tri += 1;
}
j += 1;
}
i += 1;
}
}
return res_nb_tri;
}
int count_triange_std(adjlist* g) {
int res = 0;
//itère sur les arêtes vers des noeuds plus petits
unsigned long v1, v2, i;
v1 = 0;
i = 0;
while (g->adj[i] < v1) {
i ++;
}
return res;
}
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
......@@ -15,10 +127,12 @@ int main(int argc,char** argv){
adjlist* g;
time_t t1,t2;
// PARSING
t1=time(NULL);
printf("Reading edgelist from file %s\n",argv[1]);
g=readedgelist(argv[1]);
g=al_readedgelist(argv[1]);
printf("Number of nodes: %lu\n",g->n);
printf("Number of edges: %lu\n",g->e);
......@@ -26,11 +140,26 @@ int main(int argc,char** argv){
printf("Building the adjacency list\n");
mkadjlist(g);
free_adjlist(g);
t2=time(NULL);
printf("- Overall time = %ldh%ldm%lds\n",(t2-t1)/3600,((t2-t1)%3600)/60,((t2-t1)%60));
// TRIANGLES
printf("\n\ncalcul du nombre de triangles\n");
t1 = time(NULL);
printf("%i triangles trouvés opt\n", count_triangles_opt(g));
t2 = time(NULL);
printf("- Overall time = %ldh%ldm%lds\n",(t2-t1)/3600,((t2-t1)%3600)/60,((t2-t1)%60));
free_adjlist(g);
return 0;
}
\ No newline at end of file
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter