#include "algorithms.h" #include "benchmark.h" #include "structs.h" #include "render.h" #include #include #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\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; }