Skip to content
Extraits de code Groupes Projets
Sélectionner une révision Git
  • b4cc4691ddb20563e57d5a21767be4107ce66547
  • master par défaut protégée
2 résultats

TP4_q4.c

Blame
  • TP4_q4.c 7,46 Kio
    #include "./implems.c"
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    void aff_tab(unsigned long *t, int size)
    {
    	for (int i = 0; i < size; i++)
    	{
    		printf("%li ", t[i]);
    	}
    	printf("\n");
    }
    
    // génère un nombre aléatoire sur 4 octets
    unsigned long randlu()
    {
    	unsigned long res = 0;
    	unsigned long tmp1 = rand() & 0x0F;
    	unsigned long tmp2 = rand() & 0x0F;
    	unsigned long tmp3 = rand() & 0x0F;
    	unsigned long tmp4 = rand() & 0x0F;
    
    	tmp2 = tmp2 << 8;
    	tmp3 = tmp3 << 16;
    	tmp4 = tmp4 << 24;
    
    	res = res | tmp1;
    	res = res | tmp2;
    	res = res | tmp3;
    	res = res | tmp4;
    
    	return res;
    }
    
    // génère un nombre aléatoire sur 4 octets entre min et max inclue
    unsigned long randlu_from(unsigned long min, unsigned long max)
    {
    	unsigned long range = (max - min);
    	return min + (randlu() % (range + 1));
    }
    
    void Fisher_Yates(unsigned long *tab, unsigned long size)
    {
    	unsigned long tmp;
    	unsigned long rdm;
    	for (unsigned long i = size - 1; i > 0; i--)
    	{
    		rdm = randlu_from(0, i);
    		tmp = tab[i];
    		tab[i] = tab[rdm];
    		tab[rdm] = tmp;
    	}
    }
    
    void ajuste_label_1(adjlist *g, unsigned long *label, unsigned long *label_count, unsigned long node, unsigned long commu)
    {
    	label[node] = commu;
    	unsigned long size_commu = 1;
    	unsigned long nb = 1;
    	unsigned long best = 0;
    
    	for (unsigned long i = 0; i < g->n; i++)
    	{
    		label_count[i] = 0;
    	}
    
    	for (unsigned long i = g->cd[node]; i < g->cd[node + 1]; i++)
    	{
    		if (label[g->adj[i]] == 0)
    		{
    			label_count[g->adj[i]]++;
    		}
    	}
    
    	int in_progress = 1;
    
    	while (in_progress)
    	{
    		in_progress = 0;
    		nb = 1;
    		best = label_count[0];
    
    		for (unsigned long i = 1; i < g->n; i++)
    		{
    			if (label_count[i] > best)
    			{
    				best = label_count[i];
    				nb = 1;
    			}
    			else if (label_count[i] == best)
    			{
    				nb++;
    			}
    		}
    
    		if (best >= size_commu / 2)
    		{
    			in_progress = 1;
    			unsigned long chosen = randlu_from(1, nb);
    			unsigned long i = 0;
    
    			while (i < g->n && chosen > 0)
    			{
    				if (label_count[i] == best)
    				{
    					chosen--;
    					if (chosen == 0)
    					{
    						label[i] = commu;
    						size_commu++;
    						for (unsigned long j = g->cd[i]; j < g->cd[i + 1]; j++)
    						{
    							if (label[g->adj[j]] == 0)
    							{
    								label_count[g->adj[j]]++;
    							}
    						}
    					}
    				}
    				i++;
    			}
    			if (chosen != 0)
    			{
    				printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n");
    			}
    		}
    	}
    }
    
    int ajuste_label_2(adjlist *g, unsigned long *label, unsigned long *label_count, unsigned long node)
    {
    
    	for (unsigned long i = 0; i < g->n; i++)
    	{
    		label_count[i] = 0;
    	}
    
    	for (unsigned long i = g->cd[node]; i < g->cd[node + 1]; i++)
    	{
    		label_count[label[g->adj[i]]]++;
    	}
    
    	unsigned long best = 0;
    
    	for (unsigned long i = 1; i < g->n; i++)
    	{
    		if (label_count[i] > label_count[best])
    		{
    			best = i;
    		}
    	}
    
    	if (label[node] == best)
    	{
    		return 0;
    	}
    	
    
    	if (label_count[best] > (g->cd[node + 1] - g->cd[node]) / 2)
    	{
    		label[node] = best;
    		return 1;
    	}
    
    	return 0;
    }
    
    unsigned long *label_propagation(adjlist *g)
    {
    	unsigned long *ordre = (unsigned long *)malloc(sizeof(unsigned long) * g->n);
    	unsigned long *label = (unsigned long *)malloc(sizeof(unsigned long) * g->n);
    	unsigned long *label_count = (unsigned long *)malloc(sizeof(unsigned long) * g->n);
    
    	unsigned long nb_commu = 0;
    
    	for (unsigned long i = 0; i < g->n; i++)
    	{
    		ordre[i] = i;
    		label[i] = 0;
    	}
    
    	Fisher_Yates(ordre, g->n);
    	for (unsigned long i = 0; i < g->n; i++)
    	{
    		if (label[i] == 0)
    		{
    			nb_commu++;
    			ajuste_label_1(g, label, label_count, ordre[i], nb_commu);
    		}
    	}
    
    	int in_progress = 1;
    
    	while (in_progress)
    	{
    		in_progress = 0;
    		Fisher_Yates(ordre, g->n);
    		for (unsigned long i = 0; i < g->n; i++)
    		{
    			in_progress = in_progress | ajuste_label_2(g, label, label_count, ordre[i]);
    		}
    	}
    
    	free(ordre);
    	free(label_count);
    	return label;
    }
    
    // -----------------------------------------------------------------------------------------------------------------------------------------
    
    // renvoie le nombre de label et les renommes
    unsigned long simplifie_label(unsigned long *label, unsigned long size)
    {
    	unsigned long c = 0;
    	unsigned long smallest = size;
    	unsigned long in_progress = 1;
    	while (in_progress)
    	{
    		in_progress = 0;
    		smallest = size;
    		for (unsigned long i = 0; i < size; i++)
    		{
    			if (label[i] >= c && label[i] < smallest)
    			{
    				smallest = label[i];
    				in_progress = 1;
    			}
    		}
    		for (unsigned long i = 0; i < size; i++)
    		{
    			if (label[i] == smallest)
    			{
    				label[i] = c;
    			}
    		}
    		c++;
    	}
    	return c - 1;
    }
    
    void output_graphe(adjlist *g, unsigned long *label, char *filename)
    {
    	FILE *ptr;
    	unsigned long tmp_nb_node;
    
    	tmp_nb_node = g->n;
    
    	ptr = fopen(filename, "w");
    
    	//définition des noeuds
    	fprintf(ptr, "graph D {\n");
    	//noeuds
    	for (unsigned long k = 0; k < tmp_nb_node; k++)
    	{
    		fprintf(ptr, "%li [", k);
    		switch (label[k])
    		{
    		case 0:
    			fprintf(ptr, "color=red");
    			break;
    		case 1:
    			fprintf(ptr, "color=blue");
    			break;
    		case 2:
    			fprintf(ptr, "color=green");
    			break;
    		case 3:
    			fprintf(ptr, "color=yellow");
    			break;
    		case 4:
    			fprintf(ptr, "color=black");
    			break;
    		case 5:
    			fprintf(ptr, "color=brown");
    			break;
    		case 6:
    			fprintf(ptr, "color=orange");
    			break;
    		case 7:
    			fprintf(ptr, "color=grey");
    			break;
    		case 8:
    			fprintf(ptr, "color=magenta");
    			break;
    		case 9:
    			fprintf(ptr, "color=aqua");
    			break;
    		case 10:
    			fprintf(ptr, "color=lime");
    			break;
    
    		default:
    			fprintf(ptr, "color=white");
    			break;
    		}
    
    		fprintf(ptr, "]\n");
    	}
    
    	for (unsigned long k = 0; k < tmp_nb_node; k++)
    	{
    		for (unsigned long i = g->cd[k]; i < g->cd[k + 1]; i++)
    		{
    			if (g->adj[i] > k)
    			{
    				fprintf(ptr, "%li -- %li\n", k, g->adj[i]);
    			}
    		}
    	}
    	fprintf(ptr, "}");
    	fclose(ptr);
    	return;
    }
    
    // -----------------------------------------------------------------------------------------------------------------------------------------
    
    int main(int argc, char **argv)
    {
    	if (argc < 2)
    	{
    		printf("un argument est attendu\n");
    		return 1;
    	}
    
    	adjlist *g;
    	time_t t1, t2, t3, t4;
    
    	// PARSING
    	t1 = time(NULL);
    
    	printf("Reading edgelist from file %s\n", argv[1]);
    	g = al_readedgelist(argv[1]);
    	t3 = time(NULL);
    #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
    	printf("- edge list time = %I64dh%I64dm%I64ds\n", (t3 - t1) / 3600, ((t3 - t1) % 3600) / 60, ((t3 - t1) % 60));
    #else
    	printf("- edge list time = %ldh%ldm%lds\n", (t3 - t1) / 3600, ((t3 - t1) % 3600) / 60, ((t3 - t1) % 60));
    #endif
    
    	printf("Number of nodes: %lu\n", g->n);
    	printf("Number of edges: %lu\n", g->e);
    
    	printf("Building the adjacency list\n");
    	mkadjlist(g);
    
    	t2 = time(NULL);
    
    #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
    	printf("- Overall time = %I64dh%I64dm%I64ds\n", (t2 - t1) / 3600, ((t2 - t1) % 3600) / 60, ((t2 - t1) % 60));
    #else
    	printf("- Overall time = %ldh%ldm%lds\n", (t2 - t1) / 3600, ((t2 - t1) % 3600) / 60, ((t2 - t1) % 60));
    #endif
    
    	// srand(time(NULL));
    
    	unsigned long *res = label_propagation(g);
    
    	t4 = time(NULL);
    
    #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
    	printf("- label_propagation time = %I64dh%I64dm%I64ds\n", (t4 - t2) / 3600, ((t4 - t2) % 3600) / 60, ((t4 - t2) % 60));
    #else
    	printf("- label_propagation time = %ldh%ldm%lds\n", (t4 - t2) / 3600, ((t4 - t2) % 3600) / 60, ((t4 - t2) % 60));
    #endif
    
    	unsigned long nb = simplifie_label(res, g->n);
    	printf("%li label different\n", nb);
    	output_graphe(g, res, "toto.dot");
    
    	printf("run {dot -Tpng -o out.png toto.dot} pour avoir une visualisation de la solution\n");
    
    	free(res);
    	free_adjlist(g);
    	return 0;
    }