Refonte du cours en 12 séances alignées sur le programme officiel
This commit is contained in:
158
Seance_9_Coloration.ipynb
Normal file
158
Seance_9_Coloration.ipynb
Normal file
@@ -0,0 +1,158 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 🎨 Séance 9 — Coloration de graphes\n",
|
||||
"\n",
|
||||
"## Objectifs pédagogiques\n",
|
||||
"À la fin de cette séance, vous serez capables de :\n",
|
||||
"- comprendre le **problème de coloration** d'un graphe et la notion de **nombre chromatique** ;\n",
|
||||
"- appliquer un algorithme glouton de coloration avec `networkx` ;\n",
|
||||
"- reconnaître des situations sociologiques et organisationnelles modélisables par la coloration de graphe.\n",
|
||||
"\n",
|
||||
"## Introduction\n",
|
||||
"Jusqu'ici, les arêtes de nos graphes représentaient des liens positifs (amitié, communication). La coloration de graphe part d'une idée différente : des arêtes qui représentent des **incompatibilités**, des **conflits**, des situations où deux sommets ne doivent surtout pas se retrouver \"dans la même case\".\n",
|
||||
"\n",
|
||||
"**Exemple concret :** vous devez organiser le planning des examens d'un semestre. Deux matières sont *en conflit* si des étudiant·es sont inscrit·es aux deux — dans ce cas, elles ne peuvent pas être programmées au même créneau. Combien de créneaux minimum faut-il pour que personne n'ait deux examens en même temps ?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Partie 1 — Le problème de coloration\n",
|
||||
"\n",
|
||||
"**Colorier un graphe**, c'est attribuer une couleur (ou un créneau, une catégorie...) à chaque sommet, de telle sorte que **deux sommets reliés par une arête n'aient jamais la même couleur**.\n",
|
||||
"\n",
|
||||
"Le **nombre chromatique** d'un graphe est le nombre minimum de couleurs nécessaires pour y parvenir. Plus un graphe a de conflits imbriqués les uns dans les autres, plus son nombre chromatique est élevé.\n",
|
||||
"\n",
|
||||
"**Question de réflexion préalable :** si trois matières sont toutes en conflit deux à deux (Maths-Info, Info-Socio, Maths-Socio), combien de créneaux minimum faut-il pour elles trois ? Pourquoi ne peut-on pas faire avec moins ?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Partie 2 — Un graphe de conflits d'examens\n",
|
||||
"\n",
|
||||
"Voici le graphe de conflits entre 5 matières :\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
" Maths — Info\n",
|
||||
" │ │\n",
|
||||
" Socio Anglais\n",
|
||||
" \\ /\n",
|
||||
" Sport\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"(Maths-Info, Info-Anglais, Anglais-Sport, Sport-Socio, Socio-Maths sont en conflit)\n",
|
||||
"\n",
|
||||
"**À la main :** essayez de proposer une répartition en créneaux (couleurs) avant de passer à Python. Combien de créneaux minimum pensez-vous nécessaires ?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {},
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import networkx as nx\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"\n",
|
||||
"G = nx.Graph()\n",
|
||||
"G.add_edges_from([\n",
|
||||
" (\"Maths\", \"Info\"),\n",
|
||||
" (\"Info\", \"Anglais\"),\n",
|
||||
" (\"Anglais\", \"Sport\"),\n",
|
||||
" (\"Sport\", \"Socio\"),\n",
|
||||
" (\"Socio\", \"Maths\"),\n",
|
||||
"])\n",
|
||||
"\n",
|
||||
"plt.figure()\n",
|
||||
"nx.draw(G, with_labels=True, node_color=\"lightblue\", node_size=1500)\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Partie 3 — Colorier automatiquement avec un algorithme glouton\n",
|
||||
"\n",
|
||||
"L'algorithme **glouton** de coloration parcourt les sommets un par un, et attribue à chacun **la plus petite couleur disponible** qui n'est pas déjà utilisée par l'un de ses voisins déjà colorié. C'est simple et rapide, mais il ne garantit **pas toujours** d'obtenir le nombre chromatique minimal — cela dépend de l'ordre dans lequel les sommets sont traités."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {},
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# NetworkX propose directement un algorithme glouton de coloration\n",
|
||||
"coloration = nx.greedy_color(G, strategy=\"largest_first\")\n",
|
||||
"\n",
|
||||
"print(\"Créneau (couleur) attribué à chaque matière :\")\n",
|
||||
"for matiere, creneau in coloration.items():\n",
|
||||
" print(f\" {matiere} : créneau {creneau}\")\n",
|
||||
"\n",
|
||||
"nb_creneaux = len(set(coloration.values()))\n",
|
||||
"print(f\"\\nNombre de créneaux utilisés : {nb_creneaux}\")\n",
|
||||
"\n",
|
||||
"# Visualisation avec les couleurs attribuées\n",
|
||||
"palette = [\"lightblue\", \"lightgreen\", \"lightcoral\", \"khaki\", \"plum\"]\n",
|
||||
"couleurs_sommets = [palette[coloration[noeud]] for noeud in G.nodes()]\n",
|
||||
"\n",
|
||||
"plt.figure()\n",
|
||||
"nx.draw(G, with_labels=True, node_color=couleurs_sommets, node_size=1500)\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Interprétation :** ce graphe de conflits forme un **cycle** à 5 sommets (chaque matière est en conflit avec exactement 2 autres, en boucle). Sur un cycle à un nombre **impair** de sommets, il est mathématiquement impossible de s'en sortir avec seulement 2 créneaux : en alternant 2 couleurs autour du cycle, on finit toujours par faire se toucher deux sommets de la même couleur. Il faut donc au minimum 3 créneaux.\n",
|
||||
"\n",
|
||||
"**Questions :**\n",
|
||||
"1. Le résultat de l'algorithme glouton correspond-il à votre proposition manuelle ?\n",
|
||||
"2. Si vous ajoutiez une 6ᵉ matière en conflit uniquement avec Maths, combien de créneaux seraient nécessaires ? Pourquoi ?\n",
|
||||
"3. Un graphe **sans aucune arête** (aucun conflit) a quel nombre chromatique ?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Synthèse\n",
|
||||
"\n",
|
||||
"| Concept | Signification | Exemple d'application |\n",
|
||||
"|:---------|:----------------|:--------------------------|\n",
|
||||
"| Sommet | Élément à catégoriser (matière, tâche, personne, fréquence radio...) | Un examen |\n",
|
||||
"| Arête | Incompatibilité entre deux sommets | Deux matières partagées par les mêmes étudiant·es |\n",
|
||||
"| Couleur | Catégorie/créneau attribué | Un créneau horaire |\n",
|
||||
"| Nombre chromatique | Nombre minimum de catégories nécessaires | Nombre minimum de créneaux d'examens |\n",
|
||||
"| Algorithme glouton | Attribue la plus petite couleur libre à chaque sommet, dans un ordre donné | Rapide, mais pas toujours optimal |\n",
|
||||
"\n",
|
||||
"## Questions de réflexion\n",
|
||||
"1. Donnez un autre exemple sociologique ou organisationnel modélisable par la coloration de graphe (répartition en groupes de travail, attribution de bureaux, allocation de fréquences...).\n",
|
||||
"2. Pourquoi un algorithme glouton, malgré sa simplicité, peut-il être un bon compromis en pratique même s'il ne garantit pas le minimum absolu ?\n",
|
||||
"3. En quoi la coloration de graphe diffère-t-elle fondamentalement des mesures vues en Séance 8 (centralité) ? Que cherche-t-on à optimiser dans chaque cas ?"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
Reference in New Issue
Block a user