Files
graphe/main.c
Tiago Batista Cardoso 2d3865079d lol
2026-02-28 22:41:19 +01:00

206 lines
4.2 KiB
C

#include "algorithms.h"
#include "benchmark.h"
#include "structs.h"
#include "render.h"
#include <SDL2/SDL.h>
#include <stdlib.h>
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
static void print_usage(const char *prog)
{
fprintf(stderr,
"Usage:\n"
" %s -fig1|-fig2|-fig3|-fig4|-fig5\n"
" %s -b\n"
" %s <n> <p> <q> <clique|louvain|cbla>\n\n"
"Options:\n"
" -fig1 preset: n=20, p=0.9, q=0.25\n"
" -fig2 preset: n=50, p=0.7, q=0.15\n"
" -fig3 preset: n=100, p=0.5, q=0.05\n"
" -fig4 preset: n=200, p=0.2, q=0.02\n"
" -fig5 preset: n=500, p=0.01, q=0.00025\n"
" -b run benchmark\n"
" n number of nodes\n"
" p intra-group edge probability\n"
" q inter-group edge probability\n"
" algo clique | louvain | cbla\n",
prog, prog, prog);
}
typedef struct {
int n;
double p;
double q;
int seed;
int k;
VISUALIZATION_TYPE algo;
} run_config_t;
static int parse_algo(const char *s, VISUALIZATION_TYPE *out)
{
if (strcmp(s, "clique") == 0) {
*out = CLIQUE;
return 1;
} else if (strcmp(s, "louvain") == 0) {
*out = LOUVAIN;
return 1;
} else if (strcmp(s, "cbla") == 0) {
*out = CBLA;
return 1;
}
return 0;
}
static int parse_fig(const char *arg, run_config_t *cfg)
{
if (strcmp(arg, "-fig1") == 0) {
cfg->n = 20;
cfg->p = 1.0;
cfg->q = 0.04;
cfg->k = 3;
cfg->seed = 122;
cfg->algo = CLIQUE;
return 1;
} else if (strcmp(arg, "-fig2") == 0) {
cfg->n = 20;
cfg->q = 1.0;
cfg->p = 0.04;
cfg->k = 3;
cfg->seed = 122;
cfg->algo = CLIQUE;
return 1;
} else if (strcmp(arg, "-fig3") == 0) {
cfg->n = 20;
cfg->p = 0.04;
cfg->q = 0.04;
cfg->k = 3;
cfg->seed = 122;
cfg->algo = CLIQUE;
return 1;
} else if (strcmp(arg, "-fig4") == 0) {
cfg->n = 20;
cfg->p = 0.8;
cfg->q = 0.10;
cfg->k = 0;
cfg->seed = 122;
cfg->algo = LOUVAIN;
return 1;
} else if (strcmp(arg, "-fig5") == 0) {
cfg->n = 20;
cfg->p = 0.8;
cfg->q = 0.10;
cfg->k = 3;
cfg->seed = 122;
cfg->algo = CBLA;
return 1;
}
return 0;
}
static void run_sdl(run_config_t *cfg)
{
printf("[main] generating graph n=%d p=%.4f q=%.6f\n", cfg->n, cfg->p,
cfg->q);
graph_t *graph = generate_graph(cfg->n, cfg->p, cfg->q, cfg->seed);
if (!graph) {
fprintf(stderr, "[main] generate_graph failed\n");
return;
}
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fprintf(stderr, "SDL_Init: %s\n", SDL_GetError());
free_graph(graph);
return;
}
SDL_Window *window =
SDL_CreateWindow("Graph Visualizer", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH,
WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
SDL_Renderer *renderer = SDL_CreateRenderer(
window, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
render_graph(renderer, graph, cfg->algo, cfg->k);
// Event loop
SDL_Event e;
int running = 1;
while (running) {
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT)
running = 0;
if (e.type == SDL_KEYDOWN &&
e.key.keysym.sym == SDLK_ESCAPE)
running = 0;
// Re-render on window resize
if (e.type == SDL_WINDOWEVENT &&
e.window.event == SDL_WINDOWEVENT_RESIZED)
render_graph(renderer, graph, cfg->algo,
cfg->k);
}
SDL_Delay(16);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
free_graph(graph);
}
int main(int argc, char *argv[])
{
if (argc < 2) {
print_usage(argv[0]);
return 1;
}
if (strcmp(argv[1], "-b") == 0) {
run_benchmark();
return 0;
}
run_config_t cfg = {
.n = 0, .p = 0, .q = 0, .seed = 42, .algo = CLIQUE
};
if (parse_fig(argv[1], &cfg)) {
// optionally override algo: ./graphe -fig3 louvain
if (argc >= 3 && !parse_algo(argv[2], &cfg.algo)) {
fprintf(stderr, "[main] unknown algo '%s'\n", argv[2]);
print_usage(argv[0]);
return 1;
}
run_sdl(&cfg);
return 0;
}
if (argc < 5) {
print_usage(argv[0]);
return 1;
}
cfg.n = atoi(argv[1]);
cfg.p = atof(argv[2]);
cfg.q = atof(argv[3]);
if (cfg.n <= 0 || cfg.p < 0 || cfg.p > 1 || cfg.q < 0 || cfg.q > 1) {
fprintf(stderr,
"[main] invalid arguments: n must be > 0, p and q in [0,1]\n");
return 1;
}
if (!parse_algo(argv[4], &cfg.algo)) {
fprintf(stderr, "[main] unknown algo '%s'\n", argv[4]);
print_usage(argv[0]);
return 1;
}
run_sdl(&cfg);
return 0;
return 0;
}