/********************************************/ /* Structures pour stocker les machines */ /* Ensuite spécialisées pour NFA,DFA,Cayley */ /********************************************/ #include "graphs.h" /*****************************/ /*+ Création et suppression +*/ /*****************************/ lgraph *create_lgraph_noedges(const uint nb_vertices, const uint size_alpha) { lgraph *graph = malloc(sizeof(lgraph)); if(graph == NULL){ fprintf(stderr, "Erreur d'allocation de mémoire\n"); exit(EXIT_FAILURE); } graph->size_graph = nb_vertices; graph->size_alpha = size_alpha; if(nb_vertices == 0 || size_alpha == 0) { graph->edges = NULL; return graph; } graph->edges = malloc(nb_vertices * sizeof(dequeue **)); if(graph->edges == NULL){ fprintf(stderr, "Erreur d'allocation de mémoire\n"); exit(EXIT_FAILURE); } for(uint i = 0; i < nb_vertices; i++){ graph->edges[i] = malloc(size_alpha * sizeof(dequeue *)); if(graph->edges[i] == NULL){ fprintf(stderr, "Erreur d'allocation de mémoire\n"); exit(EXIT_FAILURE); } for(uint j = 0; j < size_alpha; j++){ graph->edges[i][j] = create_dequeue(); } } return graph; } void delete_lgraph(lgraph *thegraph) { free(thegraph->edges); free(thegraph); } /**************************************/ /*+ Fusion disjointe de deux graphes +*/ /**************************************/ // ReSharper disable twice CppParameterMayBeConstPtrOrRef lgraph *merge_lgraphs(lgraph *graph1, lgraph *graph2) { if(graph1->size_alpha != graph2->size_alpha){ return NULL; } lgraph *merge = create_lgraph_noedges(graph1->size_graph + graph2->size_graph, graph1->size_alpha); for(uint i = 0; i < graph1->size_graph; i++){ // ReSharper disable once CppDFANullDereference merge->edges[i] = graph1->edges[i]; } const uint l = graph1->size_graph; for(uint i = 0; i < graph2->size_graph; i++){ // ReSharper disable once CppDFANullDereference merge->edges[i + l] = graph2->edges[i]; } return merge; } /*****************************************************************/ /*+ Récupération des sommets adjacents à un ensemble de sommets +*/ /*****************************************************************/ dequeue *lgraph_reachable(lgraph *g, dequeue *deq, const uint letter) { dequeue *reach = create_dequeue(); //on stocke la taille de la liste pour éviter de la recalculer const uint s = size_dequeue(deq); for(uint i = 0; i < s; i++) { dequeue *temp = g->edges[lefread_dequeue(deq, i)][letter]; //on insère (trié) les sommets atteignables dans la liste merge_sorted_dequeue(reach, temp); delete_dequeue(temp); } return reach; } /********************************************************/ /*+ Récupération d'une liste d'arêtes pour l'affichage +*/ /********************************************************/ stack *lgraph_to_multi_edges(lgraph *thegraph){ multi_edge *tab[thegraph->size_graph * thegraph->size_graph]; //on va créer une multi_edge pour chaque couple de sommet for(uint i = 0; i < thegraph->size_graph; i++) { for(uint j = 0; j < thegraph->size_graph; j++) { multi_edge *edges = malloc(sizeof(multi_edge)); edges->in = i; edges->out = j; edges->lab = create_dequeue(); tab[i * thegraph->size_graph + j] = edges; } } //on remplit les labels des milti_edges for(uint i = 0; i < thegraph->size_graph; i++) { //on parcourt les sommets for(uint j = 0; j < thegraph->size_alpha; j++) { //on parcourt les lettres dequeue *temp = thegraph->edges[i][j]; const uint s = size_dequeue(temp); for(uint k = 0; k < s; k++) { //on parcourt les sommets atteignables insert_dequeue(tab[i * thegraph->size_graph + lefread_dequeue(temp, k)]->lab, j); } } } //on réccupère les multi_edges non vides et on libère les autres stack *result = create_stack(); for(uint i = 0; i < thegraph->size_graph; i++) { for(uint j = 0; j < thegraph->size_graph; j++) { dequeue *temp = tab[i * thegraph->size_graph + j]->lab; //on récupère le multi_edge de chaque couple if(!isempty_dequeue(temp)){ push(tab[i * thegraph->size_graph + j], result); } else { delete_dequeue(temp); } } } return result; }