195 lines
4.0 KiB
C
195 lines
4.0 KiB
C
#include "structs.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
node_t *create_node(int id)
|
|
{
|
|
node_t *new_node = malloc(sizeof(node_t));
|
|
new_node->id = id;
|
|
new_node->next = NULL;
|
|
|
|
return new_node;
|
|
}
|
|
|
|
graph_t *create_graph(int n, double p, double q)
|
|
{
|
|
graph_t *new_graph = malloc(sizeof(graph_t));
|
|
|
|
new_graph->n = n;
|
|
new_graph->p = p;
|
|
new_graph->q = q;
|
|
new_graph->adj_lists = malloc(n * sizeof(node_t *));
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
new_graph->adj_lists[i] = NULL;
|
|
}
|
|
|
|
return new_graph;
|
|
}
|
|
|
|
void add_edge(graph_t *graph, int src, int dest)
|
|
{
|
|
// Guard against self-loops and out-of-bounds
|
|
if (src == dest)
|
|
return;
|
|
if (src < 0 || src >= graph->n) {
|
|
printf("[add_edge] src %d out of bounds!\n", src);
|
|
return;
|
|
}
|
|
if (dest < 0 || dest >= graph->n) {
|
|
printf("[add_edge] dest %d out of bounds!\n", dest);
|
|
return;
|
|
}
|
|
|
|
// src -> dest
|
|
node_t *new_node = create_node(dest);
|
|
new_node->next = graph->adj_lists[src];
|
|
graph->adj_lists[src] = new_node;
|
|
// dest -> src
|
|
new_node = create_node(src);
|
|
new_node->next = graph->adj_lists[dest];
|
|
graph->adj_lists[dest] = new_node;
|
|
}
|
|
|
|
int has_edge(const graph_t *graph, int u, int v)
|
|
{
|
|
node_t *n = graph->adj_lists[u];
|
|
while (n) {
|
|
if (n->id == v)
|
|
return 1;
|
|
n = n->next;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
graph_t *basic_graph()
|
|
{
|
|
clock_t start, end;
|
|
double cpu_time_used;
|
|
|
|
printf("[basic_graph()] creating basic graph...\n");
|
|
start = clock();
|
|
|
|
graph_t *basic = create_graph(6, 0, 0);
|
|
|
|
add_edge(basic, 0, 1);
|
|
add_edge(basic, 0, 2);
|
|
add_edge(basic, 1, 3);
|
|
add_edge(basic, 1, 4);
|
|
add_edge(basic, 2, 5);
|
|
add_edge(basic, 4, 5);
|
|
|
|
end = clock();
|
|
cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
|
|
printf("[basic_graph()] done (%f s)\n", cpu_time_used);
|
|
|
|
return basic;
|
|
}
|
|
|
|
graph_t *generate_graph(int n, double p, double q, int seed)
|
|
{
|
|
clock_t start, end;
|
|
double cpu_time_used;
|
|
|
|
printf("[generate_graph()] generating graph...\n");
|
|
start = clock();
|
|
|
|
graph_t *result = create_graph(n, p, q);
|
|
int remaining = n;
|
|
|
|
srand(seed);
|
|
|
|
// Calcul des repartitions aleatoires
|
|
int n1 = rand() % (remaining + 1);
|
|
remaining -= n1;
|
|
|
|
int n2 = rand() % (remaining + 1);
|
|
remaining -= n2;
|
|
|
|
int n3 = rand() % (remaining + 1);
|
|
remaining -= n3;
|
|
|
|
int n4 = remaining;
|
|
|
|
printf("[generate_graph()] computed repartitions : \nn1 : %d\nn2 : %d\nn3 : %d\nn4 : %d\n",
|
|
n1, n2, n3, n4);
|
|
|
|
int lots[] = { n1, n2, n3, n4 };
|
|
// Precompute the starting offset of each group
|
|
int offsets[4];
|
|
offsets[0] = 0;
|
|
for (int i = 1; i < 4; i++)
|
|
offsets[i] = offsets[i - 1] + lots[i - 1];
|
|
|
|
// Intra-group edges (probability p)
|
|
for (int i = 0; i < 4; i++) {
|
|
for (int j = 0; j < lots[i]; j++) {
|
|
for (int k = j + 1; k < lots[i]; k++) {
|
|
if ((double)rand() / RAND_MAX < p) {
|
|
add_edge(result, offsets[i] + j,
|
|
offsets[i] + k);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Inter-group edges (probability q)
|
|
for (int i = 0; i < 4; i++) {
|
|
for (int j = 0; j < lots[i]; j++) {
|
|
for (int k = i + 1; k < 4;
|
|
k++) { // k > i to avoid duplicate edges
|
|
for (int l = 0; l < lots[k]; l++) {
|
|
if ((double)rand() / RAND_MAX < q) {
|
|
add_edge(result, offsets[i] + j,
|
|
offsets[k] + l);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
end = clock();
|
|
cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
|
|
printf("[generate_graph()] done (%f s)\n", cpu_time_used);
|
|
return result;
|
|
}
|
|
|
|
// Fonction pour afficher le graphe
|
|
void displayGraph(graph_t *graph)
|
|
{
|
|
for (int i = 0; i < graph->n; i++) {
|
|
node_t *adj_list = graph->adj_lists[i];
|
|
printf("\nVertex %d: ", i);
|
|
while (adj_list) {
|
|
printf("-> %d ", adj_list->id);
|
|
adj_list = adj_list->next;
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
void free_graph(graph_t *graph)
|
|
{
|
|
clock_t start, end;
|
|
double cpu_time_used;
|
|
|
|
printf("[free_graph()] freeing graph...\n");
|
|
start = clock();
|
|
|
|
for (int i = 0; i < graph->n; i++) {
|
|
node_t *adj_list = graph->adj_lists[i];
|
|
while (adj_list != NULL) {
|
|
node_t *temp = adj_list;
|
|
adj_list = adj_list->next;
|
|
free(temp);
|
|
}
|
|
}
|
|
free(graph->adj_lists);
|
|
free(graph);
|
|
|
|
end = clock();
|
|
cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
|
|
printf("[free_graph()] done (%f s)\n", cpu_time_used);
|
|
}
|