Files
c-automates-giiiiive/Aloyse et Vincent/graphs.c
2024-12-16 02:48:28 +01:00

127 lines
4.2 KiB
C

/********************************************/
/* 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;
}