Skip to content
Snippets Groups Projects
graphe.c 14 KiB
Newer Older
Aymane Amessegher's avatar
Aymane Amessegher committed
/*
  Structures de type graphe
  Structures de donnees de type liste
  (Pas de contrainte sur le nombre de noeuds des  graphes)
*/


#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
Aymane Amessegher's avatar
Aymane Amessegher committed
#include "fap.h"
Aymane Amessegher's avatar
Aymane Amessegher committed
#include "graphe.h"
Aymane Amessegher's avatar
Aymane Amessegher committed
#include "stdbool.h"
Aymane Amessegher's avatar
Aymane Amessegher committed


psommet_t chercher_sommet (pgraphe_t g, int label)
{
  psommet_t s ;

  s = g ;

  while ((s!= NULL) && (s->label != label))
    {
      s = s->sommet_suivant ;
    }
  return s ;
}

parc_t existence_arc (parc_t l, psommet_t s)
{
  parc_t p = l ;

  while (p != NULL)
    {
      if (p->dest == s)
	return p ;
      p = p->arc_suivant ;
    }
  return p ;
  
}


void ajouter_arc (psommet_t o, psommet_t d, int distance)
{
  parc_t parc ;

  parc = (parc_t) malloc (sizeof(arc_t)) ;

  if (existence_arc (o->liste_arcs, d) != NULL)
    {
      fprintf(stderr, "ajout d'un arc deja existant\n") ;
      exit (-1) ;
    }
  
  parc->poids = distance ;
  parc->dest = d ;
  parc->arc_suivant = o->liste_arcs ;
  o->liste_arcs = parc ;
  return ;
}



// ===================================================================

int nombre_sommets (pgraphe_t g)
{
  psommet_t p = g ;
  int nb = 0 ;

  while (p != NULL)
    {
      nb = nb + 1 ;
      p = p->sommet_suivant ;
    }

  return nb ;
}

int nombre_arcs (pgraphe_t g)
{

  psommet_t p = g ;
  int nb_arcs = 0 ;

  while (p != NULL)
    {
      parc_t l = p->liste_arcs ;

      while (l != NULL)
	{
          nb_arcs = nb_arcs + 1 ;
	  l = l->arc_suivant ;
	}
      
      p = p->sommet_suivant ;
    }
  return nb_arcs ;
}

void init_couleur_sommet (pgraphe_t g)
{
  psommet_t p = g ;

  while (p != NULL)
    {
      p->couleur = 0 ; // couleur indefinie
      p = p->sommet_suivant ; // passer au sommet suivant dans le graphe
    }
  
  return ;
}

int colorier_graphe (pgraphe_t g)
{
  /*
    coloriage du graphe g
    
    datasets
    graphe data/gr_planning
    graphe data/gr_sched1
    graphe data/gr_sched2
  */

  psommet_t p = g ;
  parc_t a ;
  int couleur ;
  int max_couleur = INT_MIN ; // -INFINI
  
  int change ;

  init_couleur_sommet (g) ;
  
  while (p != NULL)
    {
      couleur = 1 ; // 1 est la premiere couleur

      // Pour chaque sommet, on essaie de lui affecter la plus petite couleur

      // Choix de la couleur pour le sommet p
      
      do
	{
	  a = p->liste_arcs ;
	  change = 0 ;
      
	  while (a != NULL)
	    {
	      if (a->dest->couleur == couleur)
		{
		  couleur = couleur + 1 ;
		  change = 1 ;
		} 
	      a = a->arc_suivant ; 
	    }

	} while (change == 1) ;

      // couleur du sommet est differente des couleurs de tous les voisins
      
      p->couleur = couleur ;
      if (couleur > max_couleur)
	max_couleur = couleur ;

      p = p->sommet_suivant ;
    }
  
  return max_couleur ;
}
Aymane Amessegher's avatar
Aymane Amessegher committed
void afficher_graphe_largeur(pgraphe_t g, int r) {
    init_couleur_sommet(g);
    psommet_t g2 = chercher_sommet(g, r); 
    fap file = creer_fap_vide(); 
    inserer(file, g2, 0);
    printf("%d, ", g2->label); 
    g2->couleur = 1; 

    while (!est_fap_vide(file)) {
        void *sommet; 
        int priorite;
        extraire(file, &sommet, &priorite); 
        psommet_t sommet_cast = (psommet_t)sommet;
        parc_t arcs = sommet_cast->liste_arcs;
        while (arcs) {
            if (arcs->dest->couleur == 0) { 
                printf("%d, ", arcs->dest->label); 
                inserer(file, arcs->dest, 0);
                arcs->dest->couleur = 1; 
            }
            arcs = arcs->arc_suivant;
        }
    }
    detruire_fap(file); 
    printf("\n");
}
Aymane Amessegher's avatar
Aymane Amessegher committed
//recu
Aymane Amessegher's avatar
Aymane Amessegher committed
void afficher_graphe_profondeur(pgraphe_t g, int r) {
    init_couleur_sommet(g); 
    psommet_t sommet = chercher_sommet(g, r); 
    parcourir_profondeur(sommet); 
Aymane Amessegher's avatar
Aymane Amessegher committed
void parcourir_profondeur(psommet_t sommet) {
    if (sommet == NULL) {
        return;
    }
Aymane Amessegher's avatar
Aymane Amessegher committed
    printf("%d :> ", sommet->label);
    sommet->couleur = 1; 
    parc_t arcs = sommet->liste_arcs;
    while (arcs) {
        if (arcs->dest->couleur == 0) { 
            parcourir_profondeur(arcs->dest);
        }
        arcs = arcs->arc_suivant;
    }
Aymane Amessegher's avatar
Aymane Amessegher committed
void initialiser_distance_racine(pgraphe_t graphe, int infini) {
    psommet_t sommet = graphe;
    while (sommet != NULL) {
        sommet->distance_racine = infini;
        sommet = sommet->sommet_suivant;
    }
}
Aymane Amessegher's avatar
Aymane Amessegher committed
void algo_dijkstra(pgraphe_t g, int r) {
    if (!g) 
        return;

    init_couleur_sommet(g);
    initialiser_distance_racine(g, INT_MAX); 

    fap file = creer_fap_vide(); 
    psommet_t sommet_depart = chercher_sommet(g, r); 
    if (!sommet_depart) 
        return;

    sommet_depart->distance_racine = 0;

    file = inserer(file, sommet_depart, sommet_depart->distance_racine); 

    while (!est_fap_vide(file)) { 
        int distance;
        psommet_t sommet_courant;
        file = extraire(file, (void **)&sommet_courant, &distance); 

        sommet_courant->couleur = 1; 

        for (parc_t arc = sommet_courant->liste_arcs; arc != NULL; arc = arc->arc_suivant) {
            
            if (arc->dest->couleur == 0 || arc->dest->distance_racine > distance + arc->poids) {
                arc->dest->couleur = 1; 
                arc->dest->distance_racine = distance + arc->poids; 
                file = inserer(file, arc->dest, arc->dest->distance_racine); 
            }
        }
    }
}

void afficher_dijkstra(pgraphe_t g) {
    bool aucun_chemin_trouve = true;
    for (psommet_t s = g; s != NULL; s = s->sommet_suivant) {
        if (s->distance_racine != INT_MAX) { 
            aucun_chemin_trouve = false; 
            printf("Le sommet %d est accessible à une distance de %d\n", s->label, s->distance_racine);
        }
    }
    if (aucun_chemin_trouve) { 
        printf("Aucun chemin trouvé dans le graphe.\n");
    }
Aymane Amessegher's avatar
Aymane Amessegher committed
}





// ======================================================================




Aymane Amessegher's avatar
Aymane Amessegher committed
int degre_sortant_sommet  (pgraphe_t g, psommet_t s) {
    int degre = 0;
    parc_t arc = s->liste_arcs;
    while (arc != NULL) {
        degre++; 
        arc = arc->arc_suivant; 
    }
    return degre; 
    }

int degre_entrant_sommet  (pgraphe_t g, psommet_t s) {
    int degre = 0;
    for (psommet_t sommet = g; sommet != NULL; sommet = sommet->sommet_suivant) {
        parc_t arc = sommet->liste_arcs;
        while (arc != NULL) {

            if (arc->dest == s) {
                degre++;
            }
            arc = arc->arc_suivant;
        }
    }
Aymane Amessegher's avatar
Aymane Amessegher committed
    return degre;
Aymane Amessegher's avatar
Aymane Amessegher committed
int degre_maximal_graphe  (pgraphe_t g) {
    int degre_maximal = 0; 
Aymane Amessegher's avatar
Aymane Amessegher committed
    for (psommet_t sommet = g; sommet != NULL; sommet = sommet->sommet_suivant) {
        int degre = degre_sortant_sommet(g, sommet);
        if (degre > degre_maximal) {
            degre_maximal = degre; 
        }
    }
Aymane Amessegher's avatar
Aymane Amessegher committed
    return degre_maximal;
Aymane Amessegher's avatar
Aymane Amessegher committed
int degre_minimal_graphe  (pgraphe_t g) {
    int degre_minimal = INT_MAX; 
Aymane Amessegher's avatar
Aymane Amessegher committed
    for (psommet_t sommet = g; sommet != NULL; sommet = sommet->sommet_suivant) {
        int degre = degre_sortant_sommet(g, sommet); 
        if (degre < degre_minimal) {
            degre_minimal = degre; 
        }
    }
    return degre_minimal;
Aymane Amessegher's avatar
Aymane Amessegher committed
}


int independant (pgraphe_t g)
{
Aymane Amessegher's avatar
Aymane Amessegher committed
    return degre_maximal_graphe(g) <= 1;// si c'est plus cad  que directement y'a des sommets en communs 
} 



int complet (pgraphe_t g) {
    for (psommet_t sommet1 = g; sommet1 != NULL; sommet1 = sommet1->sommet_suivant) {
        for (psommet_t sommet2 = sommet1->sommet_suivant; sommet2 != NULL; sommet2 = sommet2->sommet_suivant) {
            int a_relie = 0;
            for (parc_t arc = sommet1->liste_arcs; arc != NULL; arc = arc->arc_suivant) {
                if (arc->dest == sommet2) {
                    a_relie = 1;
                    break;
                }
            }
            if (!a_relie) {
                return 0;
            }
        }
    }
    return 1; 
}

Aymane Amessegher's avatar
Aymane Amessegher committed
int regulier(pgraphe_t g) {
    int degre = degre_sortant_sommet(g, g);

    for (psommet_t sommet = g->sommet_suivant; sommet != NULL; sommet = sommet->sommet_suivant) {
        if (degre_sortant_sommet(g, sommet) != degre) {
            return 0;
        }
    }
    return 1; 
Aymane Amessegher's avatar
Aymane Amessegher committed
// ---------------------------------------------------------------------------------------------------
chemin_t creer_chemin(pgraphe_t g) {
    chemin_t chemin;
    chemin.permier_sommet = g;
    if (g == NULL) {
        printf("\n Pas de chemin \n");
        return chemin;
    }

    psommet_t sommet_courant = g;
    parc_t arc = sommet_courant->liste_arcs; 

    while (arc != NULL) {
        parc_t nouvel_arc = (parc_t)malloc(sizeof(arc_t));
        nouvel_arc->poids = arc->poids;
        nouvel_arc->dest = arc->dest;
        nouvel_arc->arc_suivant = chemin.liste_arcs;
        chemin.liste_arcs = nouvel_arc;
        sommet_courant = arc->dest;
        arc = sommet_courant->liste_arcs; 
    }

    return chemin;
}


// void afficher_chemin(chemin_t c) {
//     parc_t arc = c.liste_arcs;
//     printf("Chemin : ");
//     while (arc != NULL) {
//         printf(" -> %d ", arc->dest->label);
//         arc = arc->arc_suivant;
//     }
//     printf("\n");
// }



Aymane Amessegher's avatar
Aymane Amessegher committed
int elementaire(pgraphe_t g, chemin_t c) {
    psommet_t sommet = chercher_sommet(g, c.permier_sommet->label);
    if (sommet == NULL) {
        printf("Le sommet initial n'existe pas dans le graphe.\n");
        return 0;
    }
Aymane Amessegher's avatar
Aymane Amessegher committed
    psommet_t sommet_precedent = NULL;
    for (parc_t arc = c.liste_arcs; arc != NULL; arc = arc->arc_suivant) {
        if (sommet_precedent != NULL && sommet_precedent == arc->dest) {
            printf("Le chemin n'est pas élémentaire. Il passe deux fois par le sommet %d.\n", arc->dest->label);
            return 0;
        }
        sommet_precedent = arc->dest;
Aymane Amessegher's avatar
Aymane Amessegher committed
    }
Aymane Amessegher's avatar
Aymane Amessegher committed
    return 1;
}

int simple(pgraphe_t g, chemin_t c) {
    int* arcs_parcourus = (int*)malloc(nombre_arcs(g) * sizeof(int));
    int index = 0;

    parc_t arc = c.liste_arcs;
    while (arc != NULL) {

        for (int i = 0; i < index; i++) {
            if (arcs_parcourus[i] == arc->poids) {
                free(arcs_parcourus);
                return 0; 
            }
Aymane Amessegher's avatar
Aymane Amessegher committed
        arcs_parcourus[index++] = arc->poids;
        arc = arc->arc_suivant; 
    }

    free(arcs_parcourus);

    return 1; 
}
int eulerien(pgraphe_t g, chemin_t c) {
    int nb_arcs_graphe = nombre_arcs(g);
Aymane Amessegher's avatar
Aymane Amessegher committed
    int nb_arcs_chemin = 0;
    parc_t arc = c.liste_arcs;
    while (arc != NULL) {
        nb_arcs_chemin++;
        arc = arc->arc_suivant;
Aymane Amessegher's avatar
Aymane Amessegher committed
    return nb_arcs_chemin == nb_arcs_graphe;
}
int graphe_eulerien(pgraphe_t g) {
    for (psommet_t sommet = g; sommet != NULL; sommet = sommet->sommet_suivant) {
        int degre_sortant = degre_sortant_sommet(g, sommet);
Aymane Amessegher's avatar
Aymane Amessegher committed
        if (degre_sortant % 2 != 0) {//si c'est impaire pas eulerien
            return 0;
        }
    }
Aymane Amessegher's avatar
Aymane Amessegher committed
    return 1;
Aymane Amessegher's avatar
Aymane Amessegher committed
int graphe_hamiltonien(pgraphe_t g) {
    if (g == NULL) {
        return 0;
    }

    for (psommet_t sommet = g; sommet != NULL; sommet = sommet->sommet_suivant) {
        init_couleur_sommet(g);

        if (verifier_chemin_hamiltonien(g, sommet, sommet, 1)) {
            return 1; 
        }
    }

    return 0;
}
// Pour cette fonction l'idée de recusivité est prise d'internet .
int verifier_chemin_hamiltonien(pgraphe_t g, psommet_t sommet_initial, psommet_t sommet_actuel, int count) {
    sommet_actuel->couleur = 1;

    if (count == nombre_sommets(g)) {
        return 1;
    }

    for (parc_t arc = sommet_actuel->liste_arcs; arc != NULL; arc = arc->arc_suivant) {
        if (arc->dest->couleur == 0) {
            if (verifier_chemin_hamiltonien(g, sommet_initial, arc->dest, count + 1)) {
                return 1; 
            }
        }
    }
    sommet_actuel->couleur = 0;
    return 0;
}
int distance(pgraphe_t g, int x, int y) {
    psommet_t x1 = chercher_sommet(g, x);
    psommet_t y1 = chercher_sommet(g, y);
    if (x1 == NULL || y1 == NULL) {
        printf("Un/deux de ces sommets ne sont pas dans le graphe\n");
        return -1; 
    }
Aymane Amessegher's avatar
Aymane Amessegher committed
    init_couleur_sommet(g);
    initialiser_distance_racine(g, INT_MAX);
Aymane Amessegher's avatar
Aymane Amessegher committed
    fap file = creer_fap_vide();
Aymane Amessegher's avatar
Aymane Amessegher committed
    x1->distance_racine = 0;

    file = inserer(file, x1, x1->distance_racine);

    // dijkstra là
    while (!est_fap_vide(file)) {
        int distance;
        file = extraire(file, (void **)&x1, &distance);
        x1->couleur = 1;
        if (x1 == y1) {
            return distance;
        }
        for (parc_t arc = x1->liste_arcs; arc != NULL; arc = arc->arc_suivant) {
            
            if (arc->dest->couleur == 0 || arc->dest->distance_racine > distance + arc->poids) {
                arc->dest->couleur = 1; 
                arc->dest->distance_racine = distance + arc->poids;
                file = inserer(file, arc->dest, arc->dest->distance_racine);
            }
        }
    }

    printf("pas de chemins.\n");
    return -1; //err
}
int excentricite(pgraphe_t g, int n) {
    psommet_t sommet_n = chercher_sommet(g, n);
    if (sommet_n == NULL) {
        printf("Le sommet %d n'existe pas dans le graphe ^^.\n", n);
        return -1;
    }

    init_couleur_sommet(g);
    initialiser_distance_racine(g, INT_MAX);

    fap file = creer_fap_vide();

    sommet_n->distance_racine = 0;

    file = inserer(file, sommet_n, sommet_n->distance_racine);

    int excentricite_max = -1;

    while (!est_fap_vide(file)) {
        int distance;
        file = extraire(file, (void **)&sommet_n, &distance);
        sommet_n->couleur = 1;

        // maj max
        if (distance > excentricite_max) {
            excentricite_max = distance;
        }

        for (parc_t arc = sommet_n->liste_arcs; arc != NULL; arc = arc->arc_suivant) {
            if (arc->dest->couleur == 0 || arc->dest->distance_racine > distance + arc->poids) {
                arc->dest->couleur = 1; // visité
                arc->dest->distance_racine = distance + arc->poids; // maj distance

                file = inserer(file, arc->dest, arc->dest->distance_racine);//inserer le sommet  
            }
        }
    }

    return excentricite_max;
}
int diametre(pgraphe_t g) {
    int dia_max = 0;

    for (psommet_t sommet = g; sommet != NULL; sommet = sommet->sommet_suivant) {
        int excentricicite_sommet = excentricite(g, sommet->label);

        if (excentricicite_sommet > dia_max) {
            dia_max = excentricicite_sommet;
        }
    }
    return dia_max;
}