{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "

Coloration d'un graphe et problèmes d'optimisation

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Nous allons utiliser la classe Graphe avec un dictionnaire de liste d'adjacence codée lors du TP précédent en ajoutant une méthode colorer et un affichage qui tient compte des couleurs

" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Import de networkx pour l'affichage des graphes.\n", "import networkx\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "class Graphe:\n", " def __init__(self):\n", " self.dico_adj = {}\n", " self.couleurs = {} # dictionnaire qui associe un sommet à sa couleur \n", " \n", " def ajouter_sommet(self,s):\n", " if s not in self.dico_adj :\n", " self.dico_adj[s] = [] # on choisira ici une liste et non un ensemble \n", " \n", " def ajouter_arete(self, s1, s2):\n", " if s1 not in self.dico_adj:\n", " self.ajouter_sommet(s1)\n", " if s2 not in self.dico_adj:\n", " self.ajouter_sommet(s2)\n", " if s2 not in self.dico_adj[s1]:\n", " self.dico_adj[s1].append(s2)\n", " if s1 not in self.dico_adj[s2]:\n", " self.dico_adj[s2].append(s1)\n", " \n", " def est_arete(self,s1,s2):\n", " return s2 in self.dico_adj[s1]\n", " \n", " def sommets(self):\n", " return list(self.dico_adj.keys())\n", " \n", " def voisins(self,s):\n", " return list(self.dico_adj[s])\n", " \n", " def colorer(self,s,couleur):\n", " \"\"\"méthode qui permet de colorer le sommet s avec la couleur couleur\"\"\"\n", " self.couleurs[s] = couleur\n", " \n", " \n", " def __str__(self): \n", " \"Affichage du graphe en utilisant le module networkx\"\n", " G = networkx.Graph()\n", " for s1 in self.sommets():\n", " for s2 in self.voisins(s1):\n", " G.add_edge(s1,s2)\n", " \n", " if self.couleurs:\n", " networkx.draw(G, with_labels=True,cmap=plt.get_cmap(\"tab10\"),node_size=500, nodelist=self.sommets(), node_color=list(self.couleurs.values()))\n", " else:\n", " networkx.draw(G, with_labels=True, node_size=500,node_color=\"lightblue\") \n", " \n", " return \"\"" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sommets du graphe: ['A', 'B', 'C', 'D']\n", "Voisins de A: ['B', 'D', 'C']\n", "Voisins de B: ['A', 'C', 'D']\n" ] } ], "source": [ "# Exemple Vérifiez le bon fonctionnement de la classe Graphe avec un exemple .\n", "\n", "gr = Graphe()\n", "\n", "gr.ajouter_arete(\"A\",\"B\")\n", "gr.ajouter_arete(\"B\",\"C\")\n", "gr.ajouter_arete(\"D\",\"B\")\n", "gr.ajouter_arete(\"A\",\"D\")\n", "gr.ajouter_arete(\"A\",\"C\")\n", "gr.ajouter_arete(\"C\",\"D\")\n", "\n", "\n", "print(\"Sommets du graphe:\",gr.sommets())\n", "print(\"Voisins de A:\",gr.voisins(\"A\"))\n", "print(\"Voisins de B:\",gr.voisins(\"B\"))\n" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "print(gr)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# coloriage de tous les sommetds\n", "gr.colorer(\"A\",\"yellow\")\n", "gr.colorer(\"B\",\"green\")\n", "gr.colorer(\"C\",\"green\")\n", "gr.colorer(\"D\",\"red\")\n", "print(gr)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Un problème d'aquarium

\n", "\n", "A, B, C, D, E, F, G et H désignent 8 espèces de poissons (Anguille, Barracuda, Carpe, Dorade, Espadon, Flétan , Guppy, Hippocampe et Ide)\n", "\n", "

Combien faut-il d'aquarium au minimum pour que les poissons cohabitent entre eux ?

\n", "Nous allons chercher à répondre a ce problème en utilisant la notion de coloration de graphe.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " \n", "## Exercice 1\n", "Mettre la situation sous forme de graphe dans lequel :\n", "- Chaque sommet est un des poissons.\n", "- Deux sommets sont reliés par une arête si et seulement si les poissons sont incompatibles. \n", "\n", "Représenter le graphe précédent à l'aide de `Python` en utilisant la classe `Graphe` ci-dessus.\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Votre code ici : Attention il faut proceder par ordre alphabetique\n", "A=Graphe()\n", "for lettre in \"ABCDEFGHI\":\n", " A.ajouter_sommet(lettre)\n", " \n", "A.ajouter_arete(\"A\",\"B\")\n", "A.ajouter_arete(\"A\",\"C\")\n", "\n", "A.ajouter_arete(\"A\",\"D\")\n", "A.ajouter_arete(\"A\",\"E\")\n", "\n", "A.ajouter_arete(\"B\",\"C\")\n", "A.ajouter_arete(\"B\",\"D\")\n", "A.ajouter_arete(\"B\",\"F\")\n", "A.ajouter_arete(\"B\",\"I\")\n", "A.ajouter_arete(\"G\",\"E\")\n", "A.ajouter_arete(\"F\",\"H\")\n", "\n", "A.ajouter_arete(\"G\",\"H\")\n", "A.ajouter_arete(\"G\",\"F\")\n", "A.ajouter_arete(\"H\",\"E\")\n", "\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "afficher le graphe" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(A.dico_adj)\n", "print(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " \n", "## Exercice 2 \n", "On dispose d'une couleur par aquarium.
Colorier les sommets du graphe de façon à ce que les poissons du même aquarium soient compatibles entre eux. \n", "Essayez d'utiliser le moins de couleurs différentes.\n", " \n", "Pour colorer un sommet, utilisez la méthode colorer comme dans l'exemple precedent : \n", "\n", " \n", " Vous pourrez des noms de couleurs que vous trouverez dans le site suivant : [https://html-color-codes.info/color-names/](https://html-color-codes.info/color-names/)\n", "\n", " \n", "
\n", " Cliquez ici pour un indice \n", "Par exemple, A et B ne peuvent pas être colorés de la même couleur car les poissons A et B sont incompatibles. Par contre A et F peuvent être colorés avec la même couleurs car les poissons A et F peuvent être mis dans le même aquarium.\n", "
\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "raw", "metadata": {}, "source": [ "Est-ce facile et rapide de le faire ? ...................." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " \n", "\n", "D'après vous, combien faut-il d'aquariums différents au minimum ? \n", " \n", "Peux-t-on le faire avec moins de 3 aquariums, argumentez votre réponse . \n", "\n", "
" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "**Votre réponse ici**\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " \n", "## Exercice 3 - Coloration séquentielle : un premier algorithme \n", "

Une première approche pour colorer le graphe est de prendre ses sommets les uns après les autres afin de leur affecter une couleur, tout en veillant à ce que deux sommets adjacents n'aient jamais la même couleur : c'est l'algorithme de coloration séquentielle.

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Algorithme de la fonction de coloration sequentielle

\n", "

fonction coloration(G)
\n", "

    \n", "
  1. créer une liste de couleurs possibles
  2. \n", "
  3. creer le dictionnaire de retour qui associe les sommets à leur couleur, initialiser la couleur à None
  4. \n", "
  5. parcourir chaque sommet du graphe
  6. \n", "
      \n", "
    • créer la liste des couleurs des voisins du sommet
    • \n", "
    • parcourir la liste des couleurs tant qu'une couleur est dans la liste des couleurs des voisins
    • \n", "
    • choisir alors la couleur qui n'y est pas et l'associer au sommet
    • \n", "
    \n", "
  7. renvoyer le dictionnaire
  8. \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

a) A quelle famille appartient cet algorithme ?

\n" ] }, { "cell_type": "raw", "metadata": {}, "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

b) A la main en reproduisant le graphe sur papier,
appliquer l'algorithme et écrire un numéro de couleur pour chaque sommet.

On commence à 1." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

c) Complèter alors le code python de la fonction coloration

\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def coloration(G,couleurs) :\n", " \"\"\"\n", " role : modifier l'attribut couleurs du graphe G en associant à chaque sommet une couleur differente de ses voisins\n", " entrée : un graphe, une liste de noms de couleurs\n", " sortie : rien\n", " \"\"\"\n", " # modification de l'attribut couleurs du graphe en associant à chaque sommet aucune couleur :None \n", " G.couleurs = {s:....... for s in ...........}\n", " for sommet in ..........:\n", " couleurs_des_voisins = [............. for voisin in G.voisins(sommet)]\n", " k = ...\n", " while .............. in couleurs_des_voisins:\n", " k = k + 1\n", " G.couleurs[sommet] = .................\n", " \n", " # coloriage de tous les sommets\n", " for sommet in G.sommets():\n", " ............................\n", " \n", " " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# choix de couleurs et coloration de A\n", "mes_couleurs= [\"Blue\",\"Red\",\"Yellow\",\"Green\",\"gold\",\"Orange\",\"Brown\"]\n", "coloration(A,mes_couleurs)\n", "print(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

afficher les sommets et la couleur associée

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(A.couleurs)\n", "print(A)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Ecrire une fonction qui va compter le nombre de couleurs utilisés

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def nb_couleurs(G):\n", " pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Exercice 4 - Amelioration : l'algorithme de Welsh et Powell

\n", "

Il s'agit maintenant d'utiliser l'algorithme de coloration séquentielle avec un ordre judicieux, en vue d'obtenir une coloration valide la plus « acceptable » possible.

\n", "

L'algorithme de Welsh et Powell consiste ainsi à colorer séquentiellement le graphe en visitant les sommets par ordre de degré décroissant. L'idée est que les sommets ayant beaucoup de voisins sont plus difficiles à colorer : il faut les colorier en premier.

\n", "\n", "

On rappelle que le degré d'un sommet est le nombre d'arêtes issues de ce sommet, c'est-à-dire son nombre de voisins.

\n", "\n", " \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

On souhaite implémenter une fonction tri_sommets telle que tri_sommets(G) renvoie la liste des étiquettes des sommets du graphe G passé en paramètre triés par degrés décroissants

\n", "\n", "a) creer la liste des couples (sommet, degre(sommets)) du graphe." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sommets_degre = [ (...,...................) for s in A.sommets()]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(sommets_degre)" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "b) on utilise la fonction sorted qui permet dans cette écriture de trier les sommets par degré décroissante" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "L= sorted(sommets_degre, key=lambda T:T[1], reverse=True)\n", "print(L)" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "c) créeer alors la liste Trié (uniquement) des sommets triés par degré décroissant " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Trié= [L[0] for L in L]\n", "print(Trié)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "d) compléter alors la fonction suivante" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def coloration_WP(G,couleurs) :\n", " \"\"\"\n", " role : modifier l'attribut couleurs du graphe G en associant à chaque sommet une couleur differente de ses voisins\n", " entrée : un graphe, une liste de noms de couleurs\n", " sortie : rien\n", " \"\"\"\n", " # code à rajouter pour parcourir la liste des sommets par degré décroissant\n", " \n", " \n", " # ajouter le code de la fonction coloration en modifiant une ligne \n", " \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#test avec A\n", "mes_couleurs= [\"gold\",\"Blue\",\"Red\",\"Yellow\",\"Green\",\"Orange\",\"Brown\"]\n", "coloration_WP(A,mes_couleurs)\n", "print(A)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nb_couleurs(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Exercice pour le 12 mars

\n", "\n", "\n", "Plan du musée : ( on ne tiendra pas compte des portes vers l'exterieur ) \n", "\n", "![BAC1](https://nc-lycees.netocentre.fr/s/dekKrNAF3Px4DdX/preview)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## question 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "M=Graphe()\n", "for lettre in (\"A\",\"Acceuil\",\"B\",\"Boutique\",\"C\",\"D\",\"E\",\"F\",\"G\",\"H\",\"F\"):\n", " M.ajouter_sommet(lettre)\n", " \n", " \n", "M.ajouter_arete(\"A\",\"Acceuil\")\n", "# à completer\n", "\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# affichage du graphe\n", "print(M.dico_adj)\n", "print(M)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Question 2 \n", "\n", "\n" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "a) ......................\n", "b)................................" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Question 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Question 3 : on utilisera les fonctions du tp ci_dessus\n", "mes_couleurs= [\"gold\",\"Blue\",\"Red\",\"Yellow\",\"Green\",\"Orange\",]\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" } }, "nbformat": 4, "nbformat_minor": 4 }