void grapheAjouteArc(tGraphe graphe, tArc arc) { tNumeroSommet orig, dest; tNomSommet nom_orig, nom_dest; orig = arc.orig; dest = arc.dest; /* On teste si l'arc existe déjà ou pas */ if (grapheExisteArcEntre(graphe, orig, dest)) { grapheRecupNomSommet(graphe, orig, nom_orig); grapheRecupNomSommet(graphe, dest, nom_dest); halt("Un arc existe deja entre les sommets %s (numero %d) " "et %s (numero %d)\n", nom_orig, orig, nom_dest, dest); } /* la matrice d'adjacence */ graphe->matriceAdjacence[orig][dest] = arc.val; if (!grapheEstOriente(graphe)) { graphe->matriceAdjacence[dest][orig] = arc.val; } if (grapheEstOriente(graphe)) { /* ajout dans les successeurs */ tableauEntiersAjoute(& (graphe->tableSuccesseurs[orig]), dest); /* ajout dans les prédécesseurs */ tableauEntiersAjoute(& (graphe->tablePredecesseurs[dest]), orig); } /* Même si l'arbre est orienté, on remplit la table des voisins. Toutefois, si l'arc est orienté, on vérifie que l'arc inverse n'existe pas déjà , car dans ce cas les voisins sont déjà placés. */ if ( ! ( grapheEstOriente(graphe) && grapheExisteArcEntre(graphe,dest,orig) ) ) { tableauEntiersAjoute(& (graphe->tableVoisins[orig]), dest); /* si l'arc va du sommet vers lui même, on n'ajoute pas de voisin */ if (orig!=dest) tableauEntiersAjoute(& (graphe->tableVoisins[dest]), orig); } /* Mise à jour de la table des arcs */ tableauArcsAjoute(& (graphe->tableArcs), arc); }
void graphe_visu_color(tGraphe graphe,tTabCouleurs tab_couleur, char *outfile) { FILE *fic; char commande[80]; char dotfile[80]; /* le fichier dot pour cr´eer le ps */ char psfile[80]; int ret; int nArcs = grapheNbArcs(graphe); int nSommets = grapheNbSommets (graphe); int estOriente = grapheEstOriente(graphe); char *delimiter; tNomSommet orig ; tNomSommet dest; static char* char_colors[3]; tArc arc; char_colors[0] = "red"; char_colors[1] = "blue"; char_colors[2] = "green"; /* on va créer un fichier pour graphviz, dans le fichier "outfile".dot */ strcpy(dotfile, outfile); strcpy(psfile, outfile); strcat(dotfile, ".dot"); strcat(psfile, ".ps"); fic = fopen(dotfile, "w"); if (fic==NULL) { halt ("Ouverture du fichier %s en ´ecriture impossible\n", dotfile); } estOriente ? fprintf(fic, "digraph {\n"): fprintf(fic, "graph {\n"); delimiter = estOriente ? "->" : "--"; /* Ecrit tous les sommets du graphe */ for (int i = 0; i < nSommets; i++) { grapheRecupNomSommet(graphe, i, orig); fprintf(fic, "%s [color=%s];\n", orig, char_colors[tab_couleur[i]]); } /* Ajoute les liaisons du graphe */ for(int i = 0; i< nArcs; i++){ arc = grapheRecupArcNumero(graphe, i); grapheRecupNomSommet(graphe, arc.orig, orig); grapheRecupNomSommet(graphe, arc.dest, dest); fprintf(fic, "%s %s %s;\n", orig,delimiter, dest); } /* On ferme le graphe */ fprintf(fic, "}\n"); fclose(fic); sprintf(commande, "dot -Tps %s -o %s ", dotfile, psfile); ret = system(commande); if (WEXITSTATUS(ret)){ halt("La commande suivante a ´echou´e\n%s\n", commande); } }
void graphe2visuCouleurs(tGraphe graphe, char *outfile, tTabCouleurs tabCouleurs) { FILE *fic; char commande[80]; char dotfile[80]; /* le fichier dot pour cr´eer le ps */ int ret, i, j; char isdigraph, *isdigraph2, *color; tNomSommet actuel, prochain, sommet; /* on va cr´eer un fichier pour graphviz, dans le fichier "outfile".dot */ strcpy(dotfile, outfile); strcat(dotfile, ".dot"); fic = fopen(dotfile, "w"); if (fic==NULL) halt ("Ouverture du fichier %s en ´ecriture impossible\n", dotfile); isdigraph = '-'; isdigraph2 = "graph {"; if(grapheEstOriente(graphe)) { isdigraph = '>'; isdigraph2 = "digraph {"; } fprintf(fic, "%s\n", isdigraph2 ); for(i = 0; i<=grapheNbSommets(graphe) - 1; i++) { grapheRecupNomSommet(graphe, i, sommet); if(tabCouleurs[i] == ROUGE) { color = "red"; }else if(tabCouleurs[i] == BLEU) { color = "blue"; }else if(tabCouleurs[i] == VERT) { color = "green"; } fprintf(fic, "%s [color=%s]\n", sommet, color); } for(i = 0; i <= grapheNbArcs(graphe) - 1; i++) { grapheRecupNomSommet(graphe, grapheRecupArcNumero(graphe, i).orig, actuel); grapheRecupNomSommet(graphe, grapheRecupArcNumero(graphe, i).dest, prochain); fprintf(fic, " %s -%c %s\n", actuel, isdigraph, prochain); } fprintf(fic, "}\n"); fclose(fic); sprintf(commande, "dot -Tps %s -o %s", dotfile, outfile); ret = system(commande); if (WEXITSTATUS(ret)) halt("La commande suivante a ´echou´e\n%s\n", commande); }
tNumeroSommet graphePredecesseurSommetNumero(tGraphe graphe, tNumeroSommet sommet, int numero) { int nbPredecesseurs; auxVerifieNumeroSommet(graphe, sommet); if (!grapheEstOriente(graphe)) halt("Fonction reservee aux graphes orientes"); nbPredecesseurs = graphe->tablePredecesseurs[sommet].nb; if ( (numero<0) || (numero>=nbPredecesseurs) ) { halt("Numero de successeur incorrect (%d) pour le sommet numero %d", numero, sommet); } return graphe->tablePredecesseurs[sommet].tab[numero]; }
void grapheAleatoire(tGraphe graphe, int nbSommets, int estOriente, double probaArc) { tNumeroSommet i,j,debut; double prob; tNomSommet nom; tArc arc; /* On vide le graphe */ auxResetGraphe(graphe); if ( (nbSommets<=0) || (nbSommets>MAX_SOMMETS) ) halt("nombre de sommets incorrect : %d\n", nbSommets); if ( (estOriente!=0)&&(estOriente!=1)) halt("estOriente doit valoir 0 ou 1"); if ( (probaArc<0.0) || (probaArc>1.0) ) halt("La probabilite doit etre entre 0.0 et 1.0"); graphe->estOriente = estOriente; /* on ajoute les sommets */ for(i=0;i<nbSommets;i++) { sprintf(nom, "S%d", i); grapheAjouteSommet(graphe, nom); } /* on ajoute les arcs */ for(i=0;i<nbSommets;i++) { if (grapheEstOriente(graphe)) debut=0; else debut=i; for(j=debut;j<nbSommets;j++) { /* on tire une proba */ prob = ((float)rand()) / RAND_MAX; if (prob<=probaArc) { arc.orig = i; arc.dest = j; arc.val = 0.5 + (10-0.5) * (float)(rand()) / RAND_MAX; grapheAjouteArc(graphe, arc); } } } }
void parcourLarg(tGraphe graphe, tNomSommet som) { int nb_sommets; tNumeroSommet current; //tNomSommet destination; nb_sommets = grapheNbSommets(graphe); numerosParcourus = (tNumeroSommet*)malloc(nb_sommets*sizeof(tNumeroSommet)); numerosEnfiles = (tNumeroSommet*)malloc(nb_sommets*sizeof(tNumeroSommet)); current = grapheChercheSommetParNom(graphe, som); enfiler(current); while(!fileEstVide()){ int i, nb_successeurs; tNomSommet sommet; current = numerosEnfiles[enfilesIndex++]; grapheRecupNomSommet (graphe, current, sommet); printf(" %s ",sommet); if (grapheEstOriente(graphe)) { nb_successeurs = grapheNbSuccesseursSommet(graphe,current); for ( i = 0 ; i < nb_successeurs ; i++ ){ enfiler(grapheSuccesseurSommetNumero(graphe,current,i)); } } else { nb_successeurs = grapheNbVoisinsSommet(graphe,current); for ( i = 0 ; i < nb_successeurs ; i++ ){ enfiler(grapheVoisinSommetNumero(graphe,current,i)); } } } printf("\n"); free(numerosParcourus); free(numerosEnfiles); }
int grapheNbPredecesseursSommet(tGraphe graphe, tNumeroSommet sommet) { auxVerifieNumeroSommet(graphe, sommet); if (!grapheEstOriente(graphe)) halt("Fonction reservee aux graphes orientes"); return graphe->tablePredecesseurs[sommet].nb; }
/* Affichage */ void grapheAffiche(tGraphe graphe) { tNomSommet nom; tNumeroSommet i, j, successeur, predecesseur; tValeurArc val; tArc arc; /* Affiche la liste des sommets et leur nom */ printf("Type de l'arbre : "); if (grapheEstOriente(graphe)) printf("orientee"); else printf("non orientee"); printf("\n\n"); printf("Nombre de sommets : %d\n\n", grapheNbSommets(graphe)); printf("Liste des sommets avec leurs numeros:\n"); for(i=0; i < grapheNbSommets(graphe);i++) { grapheRecupNomSommet(graphe, i, nom); printf("- %d : %s\n", i, nom); } printf("\n"); /* Matrice d'adjacence */ printf("Matrice d'adjacence :\n"); printf("%2s", ""); for(i=0; i < grapheNbSommets(graphe);i++) { printf("%7d", i); } printf("\n"); for(i=0; i < grapheNbSommets(graphe);i++) { printf("%3d ", i); for(j=0; j < grapheNbSommets(graphe);j++) { if (grapheExisteArcEntre(graphe,i,j)) { val = grapheRecupValeurArc(graphe,i,j); printf("%6.2f ", val);} else printf(" "); } printf("\n"); } printf("\n"); /* Affiche les voisins, successeurs, prédecesseurs */ if (grapheEstOriente(graphe)) { /* affichage des successeurs */ printf("Liste des successeurs :\n"); for(i=0; i < grapheNbSommets(graphe);i++) { grapheRecupNomSommet(graphe, i, nom); printf("%s : ", nom); for(j=0; j<grapheNbSuccesseursSommet(graphe, i); j++) { successeur = grapheSuccesseurSommetNumero(graphe, i, j); grapheRecupNomSommet(graphe, successeur, nom); printf("%s=%.2f ", nom, grapheRecupValeurArc(graphe, i, successeur)); } printf("\n"); } /* affichage des prédécesseurs */ printf("\nListe des predecesseurs :\n"); for(i=0; i < grapheNbSommets(graphe);i++) { grapheRecupNomSommet(graphe, i, nom); printf("%s : ", nom); for(j=0; j<grapheNbPredecesseursSommet(graphe, i); j++) { predecesseur = graphePredecesseurSommetNumero(graphe, i, j); grapheRecupNomSommet(graphe, predecesseur, nom); printf("%s=%.2f ", nom, grapheRecupValeurArc(graphe, predecesseur, i)); } printf("\n"); } } else { /* le graphe n'est pas orienté */ printf("Liste des voisins :\n"); for(i=0; i < grapheNbSommets(graphe);i++) { grapheRecupNomSommet(graphe, i, nom); printf("%s : ", nom); for(j=0; j<grapheNbVoisinsSommet(graphe, i); j++) { successeur = grapheVoisinSommetNumero(graphe, i, j); grapheRecupNomSommet(graphe, successeur, nom); printf("%s=%.2f ", nom, grapheRecupValeurArc(graphe, i, successeur)); } printf("\n"); } } printf("\n"); /* Affiche la liste des arcs */ printf("Liste des arcs :\n"); for(i=0; i < grapheNbArcs(graphe); i++) { arc = grapheRecupArcNumero(graphe, i); grapheRecupNomSommet(graphe, arc.orig, nom); printf("%s", nom); if (grapheEstOriente(graphe)) printf(" -> "); else printf(" -- "); grapheRecupNomSommet(graphe, arc.dest, nom); printf("%s ",nom); printf(" = %.2f\n", arc.val); } }
void graphe2visu(tGraphe graphe, char *outfile, tTabCouleurs tabCouleurs) { FILE *fic; char commande[80]; char dotfile[80]; /* le fichier dot pour créer le ps */ int ret; int i; int is_oriente = 0; int nb_arcs; int nb_sommets; tNomSommet nom_sommet1; tNomSommet nom_sommet2; tNomSommet nom_sommet3; tArc arc; /* on va cr´eer un fichier pour graphviz, dans le fichier "outfile".dot */ strcpy(dotfile, outfile); strcat(dotfile, ".dot"); fic = fopen(dotfile, "w"); if (fic==NULL) halt ("Ouverture du fichier %s en ´ecriture impossible\n", dotfile); is_oriente = grapheEstOriente(graphe); nb_arcs = grapheNbArcs(graphe); nb_sommets = grapheNbSommets(graphe); if(is_oriente) fprintf(fic, "digraph {\n"); else fprintf(fic, "graph {\n"); for(i = 0; i < nb_sommets; i++){ grapheRecupNomSommet(graphe, i, nom_sommet3); if(tabCouleurs[i] == VERT) fprintf(fic, "%s [color=green];\n", nom_sommet3); if(tabCouleurs[i] == BLEU) fprintf(fic, "%s [color=blue];\n", nom_sommet3); if(tabCouleurs[i] == ROUGE) fprintf(fic, "%s [color=red];\n", nom_sommet3); } for(i = 0; i < nb_arcs; i++){ arc = grapheRecupArcNumero(graphe, i); grapheRecupNomSommet(graphe, arc.orig, nom_sommet1); grapheRecupNomSommet(graphe, arc.dest, nom_sommet2); if(is_oriente) fprintf(fic," %s -> %s\n",nom_sommet1, nom_sommet2); else fprintf(fic," %s -- %s\n", nom_sommet1, nom_sommet2); } fprintf(fic, "}\n"); /**/ fclose(fic); sprintf(commande, "dot -Tps %s -o %s", dotfile, outfile); ret = system(commande); if (ret == -1) halt("La commande suivante a echouée : %s\n", commande); }
int grapheNbSuccesseursSommet(tGraphe graphe, tNumeroSommet sommet){ auxVerifieNumeroSommet(graphe, sommet); if (!grapheEstOriente(graphe)) halt("Fonction réservée aux graphes orientés"); return graphe->tableSuccesseurs[sommet].nb; }
void graphe2visu (tGraphe graphe, char* outfile) { FILE *fic; /* le fichier .dot dan lequel on va ecrire*/ char commande[80]; /* la commande appeller par sprintf plus bas */ char dotfile[80]; /* le fichier dot pour creer le ps */ int nb_sommet, i, j, nb_successeur, ret; tNomSommet origine; tNomSommet destination; /* on va creer un fichier pour graphviz, dans le fichier "outfile".dot */ strcpy(dotfile, outfile); strcat(dotfile, ".dot"); /* on ouvre le fichier .dot en ecriture */ fic = fopen(dotfile, "w"); if (fic==NULL) halt("Ouverture du fichier %s en ecriture impossible\n", dotfile); /* on recupere le nombre de sommet du graphe*/ nb_sommet = grapheNbSommets(graphe); if (grapheEstOriente(graphe)) { fprintf(fic, "digraph {\n"); /* digraph pour oriente */ for (i=0; i<nb_sommet;i++) { /* on recupere le nb de successeur du sommet*/ nb_successeur = grapheNbSuccesseursSommet(graphe,i); for (j=0;j<nb_successeur;j++) { /* on recupere le nom du sommet i et on le stock dans la variable origine */ grapheRecupNomSommet(graphe,i,origine); /* on recupere le nom du successeur j du sommet i et on le stock dans la variable destination*/ grapheRecupNomSommet(graphe,grapheSuccesseurSommetNumero(graphe,i,j),destination); /* -> pour oriente*/ fprintf(fic, "\t%s -> %s;\n", origine, destination); } } fprintf(fic, "}"); } else { fprintf(fic, "graph {\n"); /* graph pour non oriente */ for (i=0; i<nb_sommet;i++) { /* on recupere le nb de voisin du sommet*/ nb_successeur = grapheNbVoisinsSommet(graphe,i); for (j=0;j<nb_successeur;j++) { /* on recupere le nom du sommet i et on le stock dans la variable origine */ grapheRecupNomSommet(graphe,i,origine); /* on recupere le nom du voisin j du sommet i et on le stock dans la variable destination*/ grapheRecupNomSommet(graphe,grapheVoisinSommetNumero(graphe,i,j),destination); /* -- pour non oriente*/ if (strcmp(origine, destination) < 0) fprintf(fic, "\t%s -- %s;\n", origine, destination); } } fprintf(fic, "}"); } fclose(fic); /* on stock dans commande la commande qui permet a partir d'un .dot de creer un .ps*/ sprintf(commande, "dot -Tps %s -o %s.ps", dotfile, outfile); /* on appelle la fonction stocker dans commande */ ret = system(commande); if (WEXITSTATUS(ret)) halt("La commande suivante a echoue \n%s\n", commande); }
/* affiche le graphe avec les sommets colorés */ void graphe2visuCouleurs(tGraphe graphe, char *outfile, tTabCouleurs tabCouleurs) { // le canal d'écriture FILE *fic; // la commande de transformation du fichier .dot en fichier .ps char commande[80]; // le fichier .dot servant à créer le .ps char dotfile[80]; // permettra d'exécuter la commande int ret; // on va créer un fichier pour graphviz, dans le fichier "outfile".dot strcpy(dotfile, outfile); strcat(dotfile, ".dot"); fic = fopen(dotfile, "w"); // on déclenche une exception si le fichier n'est pas valide if (fic == NULL) { halt ("Ouverture du fichier %s en écriture impossible\n", dotfile); } // on vérifie l'orientation du graphe et on fait l'affichage correspondant switch (grapheEstOriente(graphe)) { case 1 : fprintf(fic,"digraph {\n"); break; default : fprintf(fic,"graph {\n"); break; } tNomSommet nomSommet; // écrit dans le fichier la couleur des sommets à cette étape for (int i = 0; i < grapheNbSommets(graphe); i++) { grapheRecupNomSommet(graphe, i, nomSommet); fprintf(fic,"%s [color=%s];\n",nomSommet,enumToString(tabCouleurs[i])); } printf("\n"); // variables qui vont contenir les noms de sommets origine et destination, et leurs numéros, et enfin l'arc qui les relie tNumeroSommet numSommetOrig; tNumeroSommet numSommetDest; tNomSommet nomSommetOrig; tNomSommet nomSommetDest; tArc arc; int i; // on parcourt la liste des arcs for (i = 0 ; i < grapheNbArcs(graphe) ; i++) { // on récupère le numéro de l'arc ainsi que le numéro du sommet origine et celui du sommet destination arc = grapheRecupArcNumero(graphe,i); numSommetOrig = arc.orig; numSommetDest = arc.dest; // on récupère les noms des sommets et on les affiche selon l'orientation du graphe grapheRecupNomSommet(graphe,numSommetOrig,nomSommetOrig); grapheRecupNomSommet(graphe,numSommetDest,nomSommetDest); switch (grapheEstOriente(graphe)) { case 1 : fprintf(fic,"%s -> %s\n",nomSommetOrig,nomSommetDest); break; default : fprintf(fic,"%s -- %s\n",nomSommetOrig,nomSommetDest); break; } } // on cherche les sommets qui n'ont pas de voisins et on les affiche for (i = 0 ; i < grapheNbSommets(graphe) ; i++) { if (grapheNbVoisinsSommet(graphe,i) == 0) { grapheRecupNomSommet(graphe,i,nomSommetOrig); fprintf(fic,"%s\n",nomSommetOrig); } } fprintf(fic,"}"); // on ferme le canal d'écriture et on met à jour la commande fclose(fic); sprintf(commande, "dot -Tps %s -o %s.ps", dotfile, outfile); // on exécute la commande ret = system(commande); if (WEXITSTATUS(ret)) { halt("La commande suivante a échoué\n%s\n", commande); } /*sprintf(commande2,"evince %s.ps",outfile); printf("%s\n",commande2); ret = system(commande2);*/ timer(2); }