Problème coloration de graphe eulérien python

Fermé
nknies - 8 mai 2022 à 19:02
nknies Messages postés 8 Date d'inscription dimanche 8 mai 2022 Statut Membre Dernière intervention 12 mai 2022 - 12 mai 2022 à 14:48
Bonjour,

Nous sommes étudiantes en prépa intégrée d'école d'ingénieur et nous avons un problème python.

Nous devons coder la coloration de graphes eulérien grâce à la méthode de Welsch-Powell qui est la suivante :
1) Repérer le degré de chaque sommet.
2) Ranger les sommets par ordre de degrés décroissants (dans certains cas plusieurs possibilités).
3) Attribuer au premier sommet (A) de la liste une couleur.
4) Suivre la liste en attribuant la même couleur au premier sommet (B) qui ne soit pas adjacent à (A).
5) Suivre (si possible) la liste jusqu'au prochain sommet (C) qui ne soit adjacent ni à A ni à B.
6) Continuer jusqu'à ce que la liste soit finie.
7) Prendre une deuxième couleur pour le premier sommet (D) non encore coloré de la liste.
8) Répéter les opérations 3 à 7.
9) Continuer jusqu'à avoir coloré tous les sommets.

Notre code permet de créer un graphe puis des listes de listes avec le nom du sommet et son degré (c'est à dire le nombre de sommets auxquels il est relié). Nous avons ensuite une matrice d'adjacence qui permet d'obtenir ces degrés. Puis viens le problème de la coloration du graphe, nous n'arrivons pas à obtenir ce que l'on souhaite. Autrement dit, nous n'arrivons pas a colorer le premier sommet avec le plus grand degré ainsi que tout les sommets qui ne sont pas lié à celui-ci de la même couleur.

Finalement notre problème vient au moment de la coloration, cela ne colore pas correctement.

Pouvez vous nous aider ? Merci d'avance :)

import numpy as np

#permet de créer les arrêtes grâce au sommet initial et au sommet final
class Arete:
    #permet d'initialliser les paramètre de la class
    def __init__(self, initial=0, final=0):
        self.sommet_initial=initial # sommet initial de l'arête
        self.sommet_final=final # sommet final de l'arête
        
    #demnde à l'utilisateur d'entrer le sommet initial et le sommet final pour chaque
    def saisie_arete (self):
        self.sommet_initial=int(input("sommet initial? "))
        self.sommet_final=int(input("sommet final? "))
        return self
        
#permet de créer tout le graphe en interne (grâce au nombre de sommets et aux arrêtes)  
class Graphe:
    #initialisation des données de la class
    def __init__(self, ns=0, na=0, aretes=[]):
        self.nombre_sommet=ns # nombre de sommets du graphe
        self.nombre_arete=na #nombre d'aretes du graphe
        self.liste_aretes=aretes # liste des arêtes du graphe
        
    #demande à l'utilisateur les données dont nous avons besoin pour créer le graphe
    #demande le nombre de sommet puis le nombre d'arrêtes (car peuvent être différents)
    def saisie_graphe(self):
        self.nombre_sommet=int(input("combien de sommet dans le graphe? "))
        self.nombre_arete=int(input("combien d'aretes dans le graphe? "))
    #cela permet d'appeler la fonction de saisie des arrêtes présente dans la class Arete
    #reitére n fois l'opération n etant le nombre d'arrête que l'utilisateur à renseigné plus tôt
        for i in range (0,self.nombre_arete):
            self.liste_aretes.append(Arete.saisie_arete(Arete(0,0)))
        return self
    
    #créer la matrice d'adjacence qui nous renseigne sur le degré de chaque sommet
    def matrice(self):
        sommets=[]#on ne prends chaque sommets qu'une seule fois
        deg=[] #liste de liste des sommets et degré non trié
        #permet de mettre dans la liste tout les chifffres entrées
        for i in self.liste_aretes:
            sommets.append(i.sommet_initial)
            sommets.append(i.sommet_final)
        lsommets=sommets[:]
        
        #permet de compter le nombre de fois que le sommet
        #apparait et le garder qu'une seule fois
        for a in sommets:
            while sommets.count(a)>1:
                sommets.remove(a)
        for a in sommets:#fois 2 sinon ça ne marche pas
            while sommets.count(a)>1:
                sommets.remove(a)
        sommets.sort() #permet de trier les sommets par ordre croissant (de noms)
        print(sommets)
        
        #si l'utilisateur se trompe et rentre des informations impossible donc incorrecte
        #cela renvoie une erreur
        if self.nombre_sommet < len(sommets):
            print("le nombre de sommet prévu et le nombre de sommet rentré n'est pas le meme")
        else:
            #enregistre le degré de chaque sommet dans une liste de liste
            for o in sommets :
                d=lsommets.count(o) #degré d'un sommet
                s=[o,d] #liste avec nom et degré
                deg.append(s) #implémente le degré de chaque sommet dans la liste vide deg
            # permet de trier par ordre décroissant les sommets suivant leur degrés
            degtri=sorted(deg, key=lambda x:x[1], reverse=True)
            print (sorted(deg, key=lambda x:x[1], reverse=True))
            
            #création de la matrice d'adjacence
            mat=np.zeros((self.nombre_sommet,self.nombre_sommet))
            
            
            #implémente les informations dans la matrice et l'affiche
            for i in self.liste_aretes:    
                coord1=sommets.index(i.sommet_initial)
                coord2=sommets.index(i.sommet_final)
                mat[coord1,coord2]=1
                mat[coord2,coord1]=1
            print (mat)
            
            #CEST LA QUE CA BEUUUG
            d=1
            
            #création d'une liste vide pour pouvoir mettre les noms des sommets
            for z in range(self.nombre_sommet):
                co=[]
                w=degtri[z][0]-1
                e=degtri[z][1]
                if e>0:
                    for p in range (1,self.nombre_sommet):
                        if mat[p-1  ,w]==0:
                            co.append(degtri[p-1][0])
                            degtri[p-1][1]=0
                            degtri[z][0]=0
                            
                
                    with open("couleur.txt",'r') as fich:
                        for i in range(d):
                            ligne = fich.readline()
                    print(co, "est de la couleur", ligne)
                d=d+1
                
                #print(z)
            


print(Graphe.matrice(Graphe.saisie_graphe(Graphe(0,0,[]))))
A voir également:

5 réponses

yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024 1 481
8 mai 2022 à 20:08
bonjour,
il est préférable de partager un programme qui ne pose pas de question.
merci d'adapter le programme pour éviter tous les input().
0
nknies Messages postés 8 Date d'inscription dimanche 8 mai 2022 Statut Membre Dernière intervention 12 mai 2022
8 mai 2022 à 20:35
Bonjour, je ne sais pas comment faire mais vous pouvez entrer ça :

nombre de sommets 4
nombre d'arrêtes 5
sommet initial 1
sommet final 2
sommet initial 2
sommet final 4
sommet initial 2
sommet final 3
sommet initial 3
sommet final 4
sommet initial 4
sommet final 1

Merci beaucoup :)
0
yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024 1 481
8 mai 2022 à 20:42
comment tu peux faire : remplacer les input() par des assignations.
as-tu écrit ce code?
0
yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024 1 481
8 mai 2022 à 20:43
cela donne une erreur: le fichier
couleur.txt
n'est pas présent.
0
nknies Messages postés 8 Date d'inscription dimanche 8 mai 2022 Statut Membre Dernière intervention 12 mai 2022
8 mai 2022 à 20:48
oui j'ai écrit le code avec ma camarade comment je peux envoyer le fichier couleur sur le forum ?
0
yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024 1 481
8 mai 2022 à 21:13
si le fichier est court, peut-être simplement partager ici son contenu?
0
nknies Messages postés 8 Date d'inscription dimanche 8 mai 2022 Statut Membre Dernière intervention 12 mai 2022 > yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024
8 mai 2022 à 21:26
rose
peche
violet
jaune
blanc
bleu
rouge
blanc
noir
marron
beige
gris
violet pale
lilas
pourpre
aubergine
indigo
carmin
0
yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024 1 481 > nknies Messages postés 8 Date d'inscription dimanche 8 mai 2022 Statut Membre Dernière intervention 12 mai 2022
8 mai 2022 à 21:30
le programme fonctionne bien.
quel résultat obtiens-tu?
que résultat attends-tu?
0
nknies Messages postés 8 Date d'inscription dimanche 8 mai 2022 Statut Membre Dernière intervention 12 mai 2022 > yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024
8 mai 2022 à 21:34
avec l'exemple que je vous ai donné j'attend ça comme résultat:
[2] est de la couleur rose
[4] est de la couleur peche
[1,3] est de la couleur violet
sauf que ça nous donne pas du tout ça donc ça

J'ai besoin de ce résultat car le programme doit d'abord donné une couleur au sommet de plus haut degré (donc le sommet 2), puis au sommet 4 etc etc et le sommet 1 et 3 sont de la même couleur car ils ne sont pas relié
0
nknies Messages postés 8 Date d'inscription dimanche 8 mai 2022 Statut Membre Dernière intervention 12 mai 2022 > nknies Messages postés 8 Date d'inscription dimanche 8 mai 2022 Statut Membre Dernière intervention 12 mai 2022
8 mai 2022 à 21:36
je ne comprends pas où est le problème dans mon programme, cela assigne bien des couleurs mais pas comme je le veux
0
nknies Messages postés 8 Date d'inscription dimanche 8 mai 2022 Statut Membre Dernière intervention 12 mai 2022
8 mai 2022 à 20:49
le problème avec les assignations c'est que je ne sais pas comment faire car j'ai une boucle qui demande plusieurs fois le sommet initial et final donc je ne vois pas trop comment faire pour enlever tout ça sans que ça ne cesse de fonctionner
0
yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024 1 481
8 mai 2022 à 21:13
il faut probablement un peu adapter le programme, en effet.
0
nknies Messages postés 8 Date d'inscription dimanche 8 mai 2022 Statut Membre Dernière intervention 12 mai 2022 > yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024
8 mai 2022 à 21:27
je pense qu'il faut changer tout le programme finalement. Je ne suis pas très forte en informatique j'essaie de suivre des tutos mais je ne trouve rien sur la coloration de graphe
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
mamiemando Messages postés 33166 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 2 juillet 2024 7 761
Modifié le 10 mai 2022 à 17:45
Bonjour,

Ton sujet d'exercice est expliqué en détail dans cette vidéo, qui te donne même le pseudo code à réaliser.

Il te faut créer dans un premier temps une structure de données pour stocker ton graphe, avec les primitives dont tu auras besoin à savoir :
  • le degré d'un sommet
  • la liste des voisins d'un sommet


Ensuite, il te faut les structures de données utilisée par l'algorithme de Welsh-Powell (donc, le tableau évoqué dans la vidéo sus-mentionnée), à savoir :
  • un dictionnaire qui associe à chaque sommet sa couleur


L'idéal serait ensuite de repartir d'un exemple (par exemple celui de la vidéo) et vérifier que ton code se comporte de la même manière (ou du moins, d'une manière acceptable puisque si des sommets sont de mêmes degrés et non colorés, ils peuvent être traités dans un ordre arbitraire).

Pour avoir un code plus simple, je pense que tu as intérêt à raisonner avec des sommets identifiés par un entier et des couleurs identifiées par un entier, quitte à associer par la suite une chaîne de caractère à chacun de ses entiers. Cela te permettra d'utiliser directement une liste d'entiers pour associer à chaque sommet son identifiant de couleur.

Au niveau de l'implémentation de ta classe de graphe, tu peux si besoin t'inspirer de ce fichier qui montre comment coder un graphe dirigé et non dirigé et les primitives associées (dans ton cas
out_edges
+
target
pour lister les voisins d'un sommet et
out_degree
pour le degré d'un sommet). Ce fichier te montre comment utiliser ces classes et ces fonctions.

Comme l'indique yg_be, ne te préoccupe pas pour le moment de l'interface utilisateur pour créer le graphe : code-le en dur dans ton code, cela t'évitera de le saisir à chaque fois et te (nous) gagnera du temps. À terme, il serait souhaitable d'avoir un fichier qui charge le graphe à partir d'un fichier, mais ça n'est pas le sujet de ton exercice donc tu peux ignorer cette remarque.

Bonne chance
0
nknies Messages postés 8 Date d'inscription dimanche 8 mai 2022 Statut Membre Dernière intervention 12 mai 2022
12 mai 2022 à 14:48
D'accord merci beaucoup nous allons essayer :)
0