Le TP est noté~: envoyez vos réponses à \texttt{simon.de-givry@inrae.fr} sous forme d'un petit document (LibreOffice, Word) en reprenant les numéros de section pour vos réponses et en ajoutant en pièces jointes vos codes python.
Précisez moi dans le message votre environnement de travail (Ubuntu ENAC/domicile, Windows domicile, Mac domicile).
\subsection{Installation sous Windows à la maison}~\label{windows}
Installer {\sf Visual Studio 2019} Communauté \url{https://visualstudio.microsoft.com/fr/downloads}.
Lors de l'installation, choisir de modifier l'installation par défaut, en incluant dans "Charge de travail" le module "Développement Python" avec Python 2.
Pour la partie sur les problèmes de tournées, installer {\sf Concorde} (Windows GUI) \url{http://www.math.uwaterloo.ca/tsp/concorde.html}. Télécharger \texttt{LKH-2.exe}\url{http://webhotel4.ruc.dk/~keld/research/LKH}, à copier dans le répertoire \texttt{tpgraph1/tsp} (voir plus loin).
Pour la partie sur la coloration de graphe, installer {\sf MiniZinc}\url{https://www.minizinc.org}.
Installation optionnelle~: {\sf or-tools}\url{https://developers.google.com/optimization} en téléchargeant la version {\em FlatZinc Binary distribution}.
Ouvrez le fichier \texttt{tpgraph1win.zip} à l'adresse
Décompactez le dossier \texttt{tpgraph1} dans \texttt{Documents}.
Démarrer Visual Studio 2019 et créer un nouveau projet en sélectionnant le répertoire \texttt{Documents/tpgraph1/tsp}. Choisir l'environnement Python 2.7 et finir l'installation en ajoutant le package {\sf networkx} (cliquer sur l'icone juste à droite du choix de Python 2.7).
\subsection{Installation sous Ubuntu dans une salle TP à l'ENAC}~\label{ubuntu}
Démarrer sous Linux Ubuntu et ouvrez le fichier \texttt{tpgraph1.zip} à l'adresse
Décompactez le dossier \texttt{tpgraph1} dans \texttt{/tmp} puis ouvrez un terminal de commandes {\sf xterm} et aller dans le dossier du TP en faisant \texttt{cd /tmp/tpgraph1}.
Les différents solvers utiles à ce TP ainsi que leur documentation dont celle de la librairie python {\sf networkx} d'algorithmes sur les graphes se trouvent dans le dossier \texttt{solvers}.
Lancer les commandes {\sf bash} suivantes pour avoir accès à ces solvers~:
Installer Python2 et la librairie {\sf networkx}~:
%\texttt{sudo apt update}\\
%\texttt{sudo apt upgrade}\\
%\texttt{sudo apt install python2.7}\\
%\texttt{sudo apt install python-pip}\\
%\texttt{sudo pip install networkx}\\
\begin{minted}{bash}
sudo apt update
sudo apt upgrade
sudo apt install python2.7
sudo apt install python-pip
sudo pip install networkx
\end{minted}
Puis suivre les instructions à la Section~\ref{ubuntu}.
\subsection{Installation sous MacOS à la maison}
Installer la version Mac OS X de Visual Studio 2019 Communauté (pour avoir Python 2) et celle de MiniZinc ainsi que or-tools (optionnel), en suivant les instructions données en Section~\ref{windows}.
Il n'existe pas de version Mac OS X de LKH et Concorde, ne pas faire les questions des Sections~\ref{francecmp} et~\ref{monde}.
\section{Construction de tournées d'aéroports (10 pts)}
Sous Ubuntu, allez dans le dossier \texttt{/tmp/tpgraph1/tsp}. Sous Windows/Mac, vous avez déjà ouvert \texttt{tpgraph1/tsp} sous Visual Studio 2019.
\subsection{Tournée des aéroports de France}
Le fichier \texttt{france.geo} contient les coordonnées latitude/longitude en degré des principaux aéroports français.
\subsubsection{Obtention d'un minorant à l'aide de l'arbre couvrant (2 pts)}
Modifier le fichier python \texttt{airports.py} pour calculer un minorant du tour des aéroports français.
Pour cela, utiliser la fonction \texttt{minimum\_spanning\_tree} dans {\sf networkx}, en s'inspirant de l'exemple donné dans la documentation \texttt{networkx.pdf}.
Donner la valeur du minorant trouvé.
\subsubsection{Obtention d'un majorant à l'aide de l'heuristique nearest neihbor (4 pts)}
Construire un tour approché en utilisant l'heuristique {\em nearest neihbor}. Il s'agit de partir d'un sommet quelconque puis d'ajouter successivement le plus proche voisin non visité jusqu'à inclure tous les sommets et revenir au sommet initial. Donner la valeur du majorant trouvé.
Quelle est la complexité de votre algorithme en fonction du nombre d'aéroports ?
\subsubsection{Comparaison avec des solvers exacts et approchés (2 pts)}~\label{francecmp}
Comparer en terme de coût et de temps de calcul le solver de recherche locale {\sf LKH} contre une méthode exacte utilisant la programmation linéaire {\sf concorde}. Donner les résultats de votre comparaison. Que concluez vous par rapport à la solution trouvée dans la section précédente ?
Commandes pour exécuter les solvers sous Ubuntu~:\\
\texttt{LKH france.par}\\
\texttt{concorde france.tsp}\\
Sous Windows, il faut ouvrir une {\em Invite de commandes} dans \texttt{Accessoires}, aller dans le répertoire \texttt{Documents/tpgraph1/tsp} et exécuter\\
\texttt{LKH-2.exe france.par}\\
Pour Concorde, il faut charger \texttt{france\_concorde\_windows.tsp} et choisir \texttt{Edges/Set Edge Norm/Geographic} avant de faire \texttt{Solve}.
\subsection{Tournée mondiale (2 pts)}~\label{monde}
Le fichier \texttt{airports.geo} contient les coordonnées latitude/longitude en degré des principaux aéroports internationaux.
Sachant la vitesse de croisière du concorde à 2158 km/h, en déduire une estimation du temps nécessaire pour survoler tous les aéroports (sans limite de carburant).
Commandes pour exécuter les solvers sous Ubuntu~:\\
\texttt{LKH airports.par}\\
\texttt{concorde airports.tsp}\\
Sous Windows, faire de même que précédemment.
Pour Concorde, utiliser \texttt{airports\_concorde\_windows.tsp}.
\section{Construction de routes aériennes (10 pts)}
Sous Ubuntu, aller dans le dossier \texttt{/tmp/tpgraph1/coloring}.
Sous Windows/Mac, ouvrir le dossier local \texttt{Documents/tpgraph1/coloring} avec Visual Studio 2019.
Les fichiers \texttt{flightsA01.txt} et \texttt{flightsB01.txt} contiennent des listes de vols directs de British Airways.
On cherche à attribuer un niveau de vol à chaque route aérienne (correspondant à un ensemble de vols effectuant le même trajet) de manière que si deux routes se croisent alors elles utilisent un niveau différent.
\subsection{Nombre chromatique du graphe d'intersections (6 pts)}
En utilisant le script python2\texttt{flights.py} et le théorème de Brooks, donner un minorant et un majorant du nombre chromatique pour chaque liste de vols.
Utiliser les fonctions {\sf networkx}\texttt{graph\_clique\_number} et \texttt{G.degree}.
Comparer avec la solution trouvée par l'heuristique DSATUR sur les deux scénarios (fonction {\sf networkx}\texttt{greedy\_color}).
Générer ensuite un problème au format {\sf MiniZinc} de coloration du graphe d'intersections avec $k$ couleurs.
Résoudre ce problème à l'aide du solver {\sf mzn-gecode}.
Trouver le nombre chromatique pour les deux scénarios.
Prouver leur optimalité. Expliquer votre démarche.
Commandes sous Ubuntu pour générer le problème et exécuter le solver avec $k=10$ couleurs sur le premier scénario~:\\
Sous Windows/Mac, avec Visual Studio 2019, modifier le fichier \texttt{flights.py} suivant le scénario choisi et le nombre de couleurs voulu.
Exécuter le code \texttt{flights.py} pour générer le fichier \texttt{.mzn} correspondant.
Double-cliquer dessus pour lancer MiniZinc IDE et le résoudre.
\subsection{Amélioration des performances de la résolution (2 pts)}
Modifier \texttt{flights.py} pour ajouter dans le modèle {\sf MiniZinc} généré des contraintes \texttt{alldifferent} pour l'ensemble des cliques du graphe d'intersection (fonction {\sf networkx}\texttt{find\_cliques}).
Est ce que cela permet de réduire le nombre de noeuds de l'arbre de recherche pour la preuve d'optimalité ? de réduire le temps de résolution ? Tester sur les deux scénarios et donner vos résultats.
Exemple de syntaxe {\sf MiniZinc} pour définir une clique sur les sommets $(6,17,19,57,63)$~:\\
Comparer avec un modèle n'ajoutant qu'une seule clique maximale par sommet (fonction {\sf networkx}\texttt{cliques\_containing\_node}).
\subsection{Minimisation des écarts au niveau de vol optimal (2 pts)}
On suppose que les avions préfèrent le niveau 0 ou sinon un niveau proche.
Modéliser la somme des écarts au niveau de vol optimal comme une somme sur les variables du problème.
Minimiser cette somme. Donner votre meilleur résultat.
Exemple de syntaxe {\sf MiniZinc} pour minimiser une somme sur les sommets $(6,7,8,9)$~:\\
\texttt{solve minimize sum([x6, x7, x8, x9]);}\\
\texttt{output [show(sum([x6, x7, x8, x9]))];}\\
Commande sous Ubuntu pour exécuter le solver en mode optimisation et voir les solutions intermédiaires~:\\
\texttt{../solvers/gecode/mzn-gecode -s -a flightsA01.mzn}\\
Sous Windows/Mac, vous pouvez directement lancer la résolution par défaut avec {\sf gecode} ou bien ajouter un nouveau solver en indiquant le lien vers l'exécutable {\sf fzn-or-tools} et en cochant toutes les options (v,s,\ldots).