/* Projet d'algorithmique et programmation 2013-2014 (cours de C.Matthieu et J.Stern) Alex AUVOLAT, Mendes OULAMARA Sujet : Algorithme de Bron-Kerbosch pour Maximum-Clique (cf maxclique.pdf) */ #include #include "sets.h" #include "graph.h" /* max_clique calculates the maximum clique in a graph. Arguments : - g : the graph where the clique is looked for - k : the clique we are currently examining - c : the graph nodes we can potentially add to the clique - a : the nodes we can actually add to the clique - mc : a pointer to the set containing the maximum clique found until now Returns nothing (result is in *mc). */ void max_clique_a(const graph g, set k, set c, set *mc) { if (is_set_empty(c)) { if (set_size(k) > set_size(*mc)) { delete_set(*mc); *mc = copy_set(k); printf("Found new max clique: "); dump_set(*mc); fflush(stdout); } } else { set cc = copy_set(c); while (!(is_set_empty(cc))) { int x = elt_of_set(cc); set_remove_ip(x, cc); set k2 = set_add(x, k); set c2 = set_inter(c, graph_neighbours(g, x)); max_clique_a(g,k2, c2, mc); delete_set(k2); delete_set(c2); } delete_set(cc); } } void max_clique_b(const graph g, set k, set c, set a, set *mc) { if (is_set_empty(c)) { if (set_size(k) > set_size(*mc)) { delete_set(*mc); *mc = copy_set(k); printf("Found new max clique: "); dump_set(*mc); fflush(stdout); } } else { set at = copy_set a; while (!(is_set_empty(a2))) { int x = elt_of_set(at); set_remove_ip(x, at); set k2 = set_add(x, k); set c2 = set_inter(c, graph_neighbours(g, x)); set a2 = set_inter(at, graph_neighbours(g, x)); max_clique_a(g,k2, c2, a2, mc); delete_set(k2); delete_set(c2); delete_set(a2); } delete_set(at); } } // Driver void usage(char *pname) { printf("\nUsage:\n\t%s [options] []\n\n", pname); printf("Available options:\n"); printf("\n -d\n\tRead input in DIMACS format\n"); printf("\n -o \n\tDump graph in graphwiz .dot format\n"); printf("\n -h, --help\n\tShow this help page\n"); exit(1); } int main(int argc, char **argv) { int i; int dimacs = 0; char *filename = "-"; char *dump = NULL; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-d")) { dimacs = 1; } else if (!strcmp(argv[i], "-o")) { if (++i == argc) usage(argv[0]); dump = argv[i]; } else if (argv[i][0] == '-') { usage(argv[0]); } else { filename = argv[i]; } } FILE *f = stdin; if (strcmp(filename, "-")) { f = fopen(filename, "r"); if (f == NULL) { fprintf(stderr, "Error: could not open file %s\n", filename); return 1; } } graph g = (dimacs ? load_graph_dimacs(f) : load_graph(f)); if (g == NULL) { fprintf(stderr, "Error loading file %s\n", filename); return 1; } fclose(f); if (dump != NULL) { f = fopen(dump, "w"); if (f == NULL) { fprintf(stderr, "Error: could not open file %s for writing\n", dump); return 1; } dump_graphviz(g, f); fclose(f); } // do stuff with graph set max_clique = empty_set(g->N); set init_s = full_set(g->N); set init_k = empty_set(g->N); max_clique_a(g, init_k, init_s, &max_clique); printf("Max clique: "); dump_set(max_clique); delete_graph(g); return 0; }