{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# 2A.algo - Parcourir les rues de Paris\n", "\n", "Algorithme de plus courts chemins dans un graphe. Calcul d'un chemin compar\u00e9 au calcul de tous les chemins les plus courts."]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Populating the interactive namespace from numpy and matplotlib\n"]}], "source": ["%matplotlib inline"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Cette id\u00e9e vient d'une soir\u00e9e Google Code initi\u00e9e par Google et \u00e0 laquelle des \u00e9l\u00e8ves de l'ENSAE ont particip\u00e9. On dispose de la description des rues de Paris (qu'on consid\u00e8rera comme des lignes droites). On veut d\u00e9terminer le trajet de huit voitures de telle sorte qu'elles parcourent la ville le plus rapidement possible. On supposera deux cas :\n", "\n", "- Les voitures peuvent \u00eatre plac\u00e9es n'importe o\u00f9 dans la ville.\n", "- Les voitures d\u00e9marrent et reviennent au m\u00eame point de d\u00e9part, le m\u00eame pour toutes.\n", "\n", "Ce notebook d\u00e9crit comment r\u00e9cup\u00e9rer les donn\u00e9es et propose une solution. Ce probl\u00e8me est plus connu sous le nom du [probl\u00e8me du postier chinois](https://fr.wikipedia.org/wiki/Probl%C3%A8me_du_postier_chinois) ou [Route inspection problem](https://en.wikipedia.org/wiki/Route_inspection_problem) pour lequel il existe un algorithme optimal \u00e0 co\u00fbt polynomial. Le probl\u00e8me n'est donc pas [NP complet](https://en.wikipedia.org/wiki/NP-completeness)."]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [{"data": {"text/html": ["
run previous cell, wait for 2 seconds
\n", ""], "text/plain": [""]}, "execution_count": 3, "metadata": {}, "output_type": "execute_result"}], "source": ["from jyquickhelper import add_notebook_menu\n", "add_notebook_menu()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Une versions de ce probl\u00e8me est propos\u00e9e sous forme de challenge : [City Tour](http://www.xavierdupre.fr/app/ensae_projects/helpsphinx/challenges/city_tour.html)."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Les donn\u00e9es\n", "\n", "On r\u00e9cup\u00e8re les donn\u00e9es sur Internet."]}, {"cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": [" downloading of http://www.xavierdupre.fr/enseignement/complements/paris_54000.zip to paris_54000.zip\n", " unzipped paris_54000.txt to .\\paris_54000.txt\n"]}, {"data": {"text/plain": ["['.\\\\paris_54000.txt']"]}, "execution_count": 4, "metadata": {}, "output_type": "execute_result"}], "source": ["import pyensae.datasource\n", "data = pyensae.datasource.download_data(\"paris_54000.zip\")\n", "data"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On extrait du fichier l'ensemble des carrefours (vertices) et des rues ou segment de rues (edges)."]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["#E= 17958 #V= 11348 > 11347\n"]}], "source": ["name = data[0]\n", "with open(name, \"r\") as f : lines = f.readlines()\n", " \n", "vertices = []\n", "edges = [ ]\n", "for i,line in enumerate(lines) :\n", " spl = line.strip(\"\\n\\r\").split(\" \")\n", " if len(spl) == 2 :\n", " vertices.append ( (float(spl[0]), float(spl[1]) ) )\n", " elif len(spl) == 5 and i > 0:\n", " v1,v2 = int(spl[0]),int(spl[1])\n", " ways = int(spl[2]) # dans les deux sens ou pas\n", " p1 = vertices[v1]\n", " p2 = vertices[v2]\n", " edges.append ( (v1,v2,ways,p1,p2) )\n", " elif i > 0 :\n", " raise Exception(\"unable to interpret line {0}: \".format(i) + line)\n", "print(\"#E=\",len(edges), \"#V=\",len(vertices), \">\",max (max( _[0] for _ in edges), max( _[1] for _ in edges)))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On trace sur un graphique un \u00e9chantillon des carrefours. On suppose la ville de Paris suffisamment petite et loin des p\u00f4les pour consid\u00e9rer les coordonn\u00e9es comme cart\u00e9siennes (et non comme longitude/latitude)."]}, {"cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [{"data": {"text/plain": ["[]"]}, "execution_count": 6, "metadata": {}, "output_type": "execute_result"}, {"data": {"image/png": "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\nQmCC\n", "text/plain": [""]}, "metadata": {}, "output_type": "display_data"}], "source": ["import matplotlib.pyplot as plt\n", "import random\n", "sample = [ vertices[random.randint(0,len(vertices)-1)] for i in range(0,1000)]\n", "plt.plot( [_[0] for _ in sample], [_[1] for _ in sample], \".\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Puis on dessine \u00e9galement un \u00e9chantillon des rues."]}, {"cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [{"data": {"image/png": "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\nAABJRU5ErkJggg==\n", "text/plain": [""]}, "metadata": {}, "output_type": "display_data"}], "source": ["sample = [ edges[random.randint(0,len(edges)-1)] for i in range(0,1000)]\n", "for edge in sample:\n", " plt.plot( [_[0] for _ in edge[-2:]], [_[1] for _ in edge[-2:]], \"b-\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Petite remarque : il n'y a pas de rues reliant le m\u00eame carrefour :"]}, {"cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [{"data": {"text/plain": ["0"]}, "execution_count": 8, "metadata": {}, "output_type": "execute_result"}], "source": ["len ( list(e for e in edges if e[0]==e[1] ))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Une premi\u00e8re solution au premier probl\u00e8me\n", "\n", "Ce probl\u00e8me est tr\u00e8s similaire \u00e0 celui du [portier chinois](http://fr.wikipedia.org/wiki/Probl%C3%A8me_du_postier_chinois). La solution qui suit n'est pas n\u00e9cessaire la meilleure mais elle donne une id\u00e9e de ce que peut-\u00eatre une recherche un peu exp\u00e9rimentale sur le sujet.\n", "\n", "Chaque noeud repr\u00e9sente un carrefour et chaque rue est un arc reliant des deux carrefours. L'objectif est de parcourir tous les arcs du graphe avec 8 voitures. \n", "\n", "Premiere remarque, l'\u00e9nonc\u00e9 ne dit pas qu'il faut parcourir toutes les rues une seule fois. On con\u00e7oit ais\u00e9ment que ce serait l'id\u00e9al mais on ne sait pas si ce serait possible. N\u00e9anmoins, si une telle solution (un chemin passant une et une seule fois par toutes les rues) existe, elle est forc\u00e9ment optimale.\n", "\n", "Deuxi\u00e8me remarque, les sens interdits rendent le probl\u00e8me plus complexe. On va dans un premier temps ne pas en tenir compte. On verra comment ajouter la contrainte par la suite et il y a aussi le probl\u00e8me des impasses. On peut n\u00e9anmoins les contourner en les supprimant du graphe : il faut n\u00e9cessairement faire demi-tour et il n'y a pas de meilleure solution.\n", "\n", "Ces deux remarques \u00e9tant faite, ce probl\u00e8me rappelle un peu le probl\u00e8me des sept ponts de [Konigsberg](http://fr.wikipedia.org/wiki/Probl%C3%A8me_des_sept_ponts_de_K%C3%B6nigsberg) : comment traverser passer par les sept de la ville une et une seule fois. Le math\u00e9maticien [Euler](http://fr.wikipedia.org/wiki/Leonhard_Euler) a r\u00e9pondu \u00e0 cette question : c'est simple, il suffit que chaque noeud du graphe soit rejoint par un nombre pair de d'arc (= ponts) sauf au plus 2 (les noeuds de d\u00e9part et d'arriv\u00e9e). De cette fa\u00e7on, \u00e0 chaque qu'on rejoint un noeud, il y a toujours une fa\u00e7on de repartir."]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [{"data": {"image/png": "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\n", "text/plain": [""]}, "metadata": {}, "output_type": "display_data"}], "source": ["import networkx as nx\n", "g = nx.Graph()\n", "for i,j in [(1,2),(1,3),(1,4),(2,3),(3,4),(4,5),(5,2),(2,4) ]:\n", " g.add_edge( i,j )\n", "import matplotlib.pyplot as plt\n", "f, ax = plt.subplots(figsize=(6,3))\n", "nx.draw(g, ax = ax)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On ne peut pas trouver une chemin qui parcourt tous les arcs du graphe pr\u00e9c\u00e9dent une et une seule fois. Qu'en est-il du graphe de la ville de Paris ? On compte les noeuds qui ont un nombre pairs et impairs d'arcs les rejoignant (on appelle cela le [degr\u00e9](http://fr.wikipedia.org/wiki/Degr%C3%A9_(th%C3%A9orie_des_graphes)))."]}, {"cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [{"data": {"text/plain": ["[[(2, 1337), (3, 7103), (4, 2657), (5, 209), (6, 35), (7, 6), (8, 1)]]"]}, "execution_count": 10, "metadata": {}, "output_type": "execute_result"}], "source": ["nb_edge = { }\n", "for edge in edges :\n", " v1,v2 = edge[:2]\n", " nb_edge[v1] = nb_edge.get(v1,0)+1\n", " nb_edge[v2] = nb_edge.get(v2,0)+1\n", "parite = { }\n", "for k,v in nb_edge.items():\n", " parite[v] = parite.get(v,0) + 1\n", "[ sorted(parite.items()) ]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On remarque que la plupart des carrefours sont le d\u00e9part de 3 rues. Qu'\u00e0 cela ne tienne, pourquoi ne pas ajouter des arcs entre des noeuds de degr\u00e9 impair jusqu'\u00e0 ce qu'il n'y en ait plus que 2. De cette fa\u00e7on, il sera facile de construire un seul chemin parcourant toutes les rues. Comment ajouter ces arcs ? Cela va se faire en deux \u00e9tapes :\n", "\n", "- On utilise l'algorithme de [Bellman-Ford](http://fr.wikipedia.org/wiki/Algorithme_de_Bellman-Ford) pour construire une matrice des plus courts chemins entre tous les noeuds.\n", "- On s'inspire de l'algorithme de poids minimal [Kruskal](http://fr.wikipedia.org/wiki/Algorithme_de_Kruskal). On trie les arcs par ordre croissant de distance. On ajoute ceux qui r\u00e9duisent le nombre de noeuds de degr\u00e9 impairs en les prenant dans cet ordre.\n", "\n", "**Quelques justifications :** le meilleur parcours ne pourra pas descendre en de\u00e7a de la somme des distances des rues puisqu'il faut toutes les parcourir. De plus, s'il existe un chemin qui parcourt toutes les rues, en d\u00e9doublant toutes celles parcourues plus d'une fois, il est facile de rendre ce chemin *eul\u00e9rien* dans un graphe l\u00e9g\u00e8rement modifi\u00e9 par rapport au graphe initial."]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Etape 1 : la matrice Bellman\n", "\n", "Je ne d\u00e9taillerai pas trop, la page Wikipedia est assez claire. Dans un premier temps on calcule la longueur de chaque arc (de fa\u00e7on cart\u00e9sienne). Une autre distance ([Haversine](http://en.wikipedia.org/wiki/Haversine_formula)) ne changerait pas le raisonnement."]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": ["def distance(p1,p2):\n", " return ((p1[0]-p2[0])**2+(p1[1]-p2[1])**2)**0.5\n", "edges = [ edge + (distance( edge[-2],edge[-1]),) for edge in edges]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Ensuite, on impl\u00e9mente l'algorithme de [Bellman-Ford](http://fr.wikipedia.org/wiki/Algorithme_de_Bellman-Ford)."]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["2015-04-12 01:16:40.590690 iteration 0 modif 72870 # 35916 / 128777104 = 0.03%\n", "2015-04-12 01:16:41.340550 iteration 1 modif 120368 # 104842 / 128777104 = 0.08%\n", "2015-04-12 01:16:42.887810 iteration 2 modif 180646 # 213826 / 128777104 = 0.17%\n", "2015-04-12 01:16:45.510596 iteration 3 modif 255702 # 368960 / 128777104 = 0.29%\n", "2015-04-12 01:16:49.759326 iteration 4 modif 347092 # 576106 / 128777104 = 0.45%\n", "2015-04-12 01:16:55.781000 iteration 5 modif 455899 # 839276 / 128777104 = 0.65%\n", "2015-04-12 01:17:04.276258 iteration 6 modif 584263 # 1162870 / 128777104 = 0.90%\n"]}], "source": ["import datetime\n", "init = { (e[0],e[1]) : e[-1] for e in edges }\n", "init.update ( { (e[1],e[0]) : e[-1] for e in edges } )\n", "\n", "edges_from = { }\n", "for e in edges :\n", " if e[0] not in edges_from : edges_from[e[0]] = []\n", " if e[1] not in edges_from : edges_from[e[1]] = []\n", " edges_from[e[0]].append(e)\n", " edges_from[e[1]].append( (e[1], e[0], e[2], e[4], e[3], e[5] ) )\n", " \n", "modif = 1\n", "total_possible_edges = len(edges_from)**2\n", "it = 0\n", "while modif > 0 :\n", " modif = 0\n", " initc = init.copy() # to avoid RuntimeError: dictionary changed size during iteration\n", " s = 0\n", " for i,d in initc.items() :\n", " fromi2 = edges_from[i[1]]\n", " s += d\n", " for e in fromi2 :\n", " if i[0] == e[1] : # on fait attention \u00e0 ne pas ajouter de boucle sur le m\u00eame noeud\n", " continue\n", " new_e = i[0], e[1]\n", " new_d = d + e[-1]\n", " if new_e not in init or init[new_e] > new_d :\n", " init[new_e] = new_d \n", " modif += 1\n", " print(datetime.datetime.now(), \"iteration \", it, \" modif \", modif, \" # \", len(initc),\"/\",total_possible_edges,\"=\", \n", " \"%1.2f\" %(len(initc)*100 / total_possible_edges) + \"%\")\n", " it += 1\n", " if it > 6 : break"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On s'aper\u00e7oit vite que cela va \u00eatre tr\u00e8s tr\u00e8s long. On d\u00e9cide alors de ne consid\u00e9rer que les paires de noeuds pour lesquelles la distance \u00e0 vol d'oiseau est inf\u00e9rieure au plus grand segment de rue ou inf\u00e9rieure \u00e0 cette distance multipli\u00e9e par un coefficient."]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [{"data": {"text/plain": ["0.017418989861067814"]}, "execution_count": 13, "metadata": {}, "output_type": "execute_result"}], "source": ["max_segment = max( e[-1] for e in edges )\n", "max_segment"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On calcule les arcs admissibles (en esp\u00e9rant que les noeuds de degr\u00e9 impairs seront bien dedans). Cette \u00e9tape prend quelques minutes :"]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["original 35916 / 128777104 = 0.000278900510140374\n", "addition 2875586 / 128777104 = 0.022329947721141486\n"]}], "source": ["possibles = { (e[0],e[1]) : e[-1] for e in edges }\n", "possibles.update ( { (e[1],e[0]) : e[-1] for e in edges } )\n", "initial = possibles.copy()\n", "for i1,v1 in enumerate(vertices) :\n", " for i2 in range(i1+1,len(vertices)):\n", " v2 = vertices[i2]\n", " d = distance(v1,v2)\n", " if d < max_segment / 2 : # on ajuste le seuil\n", " possibles [ i1,i2 ] = d\n", " possibles [ i2,i1 ] = d\n", "print(\"original\",len(initial),\"/\",total_possible_edges,\"=\", len(initial)/total_possible_edges)\n", "print(\"addition\",len(possibles)-len(initial),\"/\",total_possible_edges,\"=\", (len(possibles)-len(initial))/total_possible_edges)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On v\u00e9rifie que les noeuds de degr\u00e9 impairs font tous partie de l'ensemble des noeuds recevant de nouveaux arcs. La matrice de Bellman envisagera au pire 2.2% de toutes les distances possibles."]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["si vous voyez cette ligne, c'est que tout est bon\n"]}], "source": ["allv = { p[0]:True for p in possibles if p not in initial } # possibles est sym\u00e9trique\n", "for v,p in nb_edge.items() :\n", " if p % 2 == 1 and v not in allv :\n", " raise Exception(\"probl\u00e8me pour le noeud: {0}\".format(v))\n", "print(\"si vous voyez cette ligne, c'est que tout est bon\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On continue avec l'algorithme de [Bellman-Ford](http://fr.wikipedia.org/wiki/Algorithme_de_Bellman-Ford) modifi\u00e9 :"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["2015-04-12 01:18:45.389333 iteration 0 modif 72870 # 35916 / 128777104 = 0.03%\n", "2015-04-12 01:18:46.179293 iteration 1 modif 119604 # 104842 / 128777104 = 0.08%\n", "2015-04-12 01:18:47.853483 iteration 2 modif 178033 # 213086 / 128777104 = 0.17%\n", "2015-04-12 01:18:50.790772 iteration 3 modif 248648 # 365751 / 128777104 = 0.28%\n", "2015-04-12 01:18:55.302585 iteration 4 modif 330443 # 566457 / 128777104 = 0.44%\n", "2015-04-12 01:19:02.002318 iteration 5 modif 419549 # 815211 / 128777104 = 0.63%\n", "2015-04-12 01:19:11.623367 iteration 6 modif 508807 # 1109019 / 128777104 = 0.86%\n", "2015-04-12 01:19:23.579840 iteration 7 modif 585973 # 1438040 / 128777104 = 1.12%\n", "2015-04-12 01:19:38.370350 iteration 8 modif 639491 # 1785232 / 128777104 = 1.39%\n", "2015-04-12 01:19:56.035255 iteration 9 modif 656961 # 2127675 / 128777104 = 1.65%\n", "2015-04-12 01:20:16.436453 iteration 10 modif 638987 # 2441604 / 128777104 = 1.90%\n", "2015-04-12 01:20:39.075644 iteration 11 modif 591284 # 2711201 / 128777104 = 2.11%\n", "2015-04-12 01:21:04.245760 iteration 12 modif 519515 # 2928527 / 128777104 = 2.27%\n", "2015-04-12 01:21:33.496050 iteration 13 modif 434787 # 3091667 / 128777104 = 2.40%\n", "2015-04-12 01:22:02.419568 iteration 14 modif 346204 # 3205671 / 128777104 = 2.49%\n", "2015-04-12 01:22:29.389913 iteration 15 modif 263229 # 3279078 / 128777104 = 2.55%\n", "2015-04-12 01:22:55.394012 iteration 16 modif 191482 # 3323381 / 128777104 = 2.58%\n", "2015-04-12 01:23:22.033884 iteration 17 modif 133738 # 3348569 / 128777104 = 2.60%\n", "2015-04-12 01:23:49.684842 iteration 18 modif 90442 # 3362160 / 128777104 = 2.61%\n", "2015-04-12 01:24:17.267404 iteration 19 modif 59686 # 3369505 / 128777104 = 2.62%\n", "2015-04-12 01:24:46.839139 iteration 20 modif 38936 # 3373640 / 128777104 = 2.62%\n"]}], "source": ["import datetime\n", "init = { (e[0],e[1]) : e[-1] for e in edges }\n", "init.update ( { (e[1],e[0]) : e[-1] for e in edges } )\n", "\n", "edges_from = { }\n", "for e in edges :\n", " if e[0] not in edges_from : edges_from[e[0]] = []\n", " if e[1] not in edges_from : edges_from[e[1]] = []\n", " edges_from[e[0]].append(e)\n", " edges_from[e[1]].append( (e[1], e[0], e[2], e[4], e[3], e[5] ) )\n", " \n", "modif = 1\n", "total_possible_edges = len(edges_from)**2\n", "it = 0\n", "while modif > 0 :\n", " modif = 0\n", " initc = init.copy() # to avoid RuntimeError: dictionary changed size during iteration\n", " s = 0\n", " for i,d in initc.items() :\n", " if i not in possibles : \n", " continue # we skip undesired edges ------------------- addition\n", " fromi2 = edges_from[i[1]]\n", " s += d\n", " for e in fromi2 :\n", " if i[0] == e[1] : # on fait attention \u00e0 ne pas ajouter de boucle sur le m\u00eame noeud\n", " continue\n", " new_e = i[0], e[1]\n", " new_d = d + e[-1]\n", " if new_e not in init or init[new_e] > new_d :\n", " init[new_e] = new_d \n", " modif += 1\n", " print(datetime.datetime.now(), \"iteration \", it, \" modif \", modif, \" # \", len(initc),\"/\",total_possible_edges,\"=\", \n", " \"%1.2f\" %(len(initc)*100 / total_possible_edges) + \"%\")\n", " it += 1\n", " if it > 20 : \n", " break"]}, {"cell_type": "markdown", "metadata": {}, "source": ["L'algorithme consiste \u00e0 regarder les chemins $a \\rightarrow b \\rightarrow c$ et \u00e0 comparer s'il est plus rapide que $a \\rightarrow c$. 2.6% > 2.2% parce que le filtre est appliqu\u00e9 seulement sur $a \\rightarrow b$. Finalement, on consid\u00e8re les arcs ajout\u00e9s puis on retire les arcs originaux."]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": ["original = { (e[0],e[1]) : e[-1] for e in edges }\n", "original.update ( { (e[1],e[0]) : e[-1] for e in edges } )\n", "additions = { k:v for k,v in init.items() if k not in original }\n", "additions.update( { (k[1],k[0]):v for k,v in additions.items() } ) "]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Kruskall\n", "\n", "On trie les arcs par distance croissante, on enl\u00e8ve les arcs qui ne relient pas des noeuds de degr\u00e9 impair puis on les ajoute un par jusqu'\u00e0 ce qu'il n'y ait plus d'arc de degr\u00e9 impair."]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["nb degr\u00e9 impairs 22 nombre d'arcs ajout\u00e9s 3648\n", "longueur ajout\u00e9e 3.5423464430662346\n", "longueur initiale 17.418504406203844\n"]}], "source": ["degre = { }\n", "for k,v in original.items() : # original est sym\u00e9trique\n", " degre[k[0]] = degre.get(k[0],0) + 1\n", "\n", "tri = [ (v,k) for k,v in additions.items() if degre[k[0]] %2 == 1 and degre[k[1]] %2 == 1 ]\n", "tri.extend( [ (v,k) for k,v in original.items() if degre[k[0]] %2 == 1 and degre[k[1]] %2 == 1 ] )\n", "tri.sort()\n", "\n", "impairs = sum ( v%2 for k,v in degre.items() )\n", "\n", "added_edges = [] \n", "\n", "for v,a in tri :\n", " if degre[a[0]] % 2 == 1 and degre[a[1]] % 2 == 1 :\n", " # il faut refaire le test car degre peut changer \u00e0 chaque it\u00e9ration\n", " degre[a[0]] += 1\n", " degre[a[1]] += 1\n", " added_edges.append ( a + (v,) )\n", " impairs -= 2\n", " if impairs <= 0 :\n", " break\n", "\n", "# on v\u00e9rifie\n", "print(\"nb degr\u00e9 impairs\",impairs, \"nombre d'arcs ajout\u00e9s\",len(added_edges))\n", "print(\"longueur ajout\u00e9e \", sum( v for a,b,v in added_edges ))\n", "print(\"longueur initiale \", sum( e[-1] for e in edges ))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Le nombre de noeuds impairs obtenus \u00e0 la fin doit \u00eatre inf\u00e9rieur \u00e0 2 pour \u00eatre s\u00fbr de trouver un chemin (mais on choisira 0 pour avoir un circuit eul\u00e9rien). Mon premier essai n'a pas donn\u00e9 satisfaction (92 noeuds impairs restant) car j'avais choisi un seuil (max_segment / 4) trop petit lors de la s\u00e9lection des arcs \u00e0 ajouter. J'ai augment\u00e9 le seuil par la suite mais il reste encore 22 noeuds de degr\u00e9 impairs. On a le choix entre augmenter ce seuil mais l'algorithme est d\u00e9j\u00e0 long ou chercher dans une autre direction comme laisser l'algorithme de Bellman explorer les noeuds de degr\u00e9 impairs. Ca ne veut pas forc\u00e9ment dire qu'il manque des arcs mais que peut-\u00eatre ils sont mal choisis. Si l'arc $i \\rightarrow j$ est choisi, l'arc $j \\rightarrow k$ ne le sera pas car $j$ aura un degr\u00e9 pair. Mais dans ce cas, si l'arc $j \\rightarrow k$ \u00e9tait le dernier arc disponible pour combler $k$, on est coinc\u00e9. On peut augmenter le seuil encore mais cela risquee de prendre du temps et puis cela ne fonctionnerait pas toujours sur tous les jeux de donn\u00e9es.\n", "\n", "On pourait alors \u00e9crire une sorte d'algorithme it\u00e9ratif qui ex\u00e9cute l'algorithme de Bellman, puis lance celui qui ajoute les arcs. Puis on revient au premier en ajoutant plus d'arcs autour des noeuds probl\u00e8matique lors de la seconde \u00e9tape. L'ensemble est un peu long pour tenir dans un notebook mais le code est celui de la fonction [eulerien_extension](http://www.xavierdupre.fr/app/ensae_teaching_cs/helpsphinx/ensae_teaching_cs/special/rues_paris.html#special.rues_paris.eulerien_extension). Je conseille \u00e9galement la lecture de cet article : [Efficient Algorithms for Eulerian Extension](http://www.akt.tu-berlin.de/fileadmin/fg34/publications-akt/euler_short.pdf) (voir \u00e9galement [On Making Directed Graphs Eulerian](http://arxiv.org/abs/1101.4283)). L'ex\u00e9cution qui suit prend une vingtaine de minutes."]}, {"cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["data\n", "start, nb edges 17958\n", "possible_edges\n", "original 17958 / 64382878.0 = 0.00027892508936925745\n", "addition 1312214 / 64382878.0 = 0.020381412586122666\n", "next\n", "iteration 0 modif 72876 # 17958 / 64382878 = 0.03%\n", "iteration 1 modif 119544 # 52421 / 64382878 = 0.08%\n", "iteration 2 modif 177609 # 106511 / 64382878 = 0.17%\n", "iteration 3 modif 247689 # 182680 / 64382878 = 0.28%\n", "iteration 4 modif 327843 # 282626 / 64382878 = 0.44%\n", "iteration 5 modif 413418 # 405980 / 64382878 = 0.63%\n", "iteration 6 modif 496069 # 550546 / 64382878 = 0.86%\n", "iteration 7 modif 561366 # 710517 / 64382878 = 1.10%\n", "iteration 8 modif 598700 # 875788 / 64382878 = 1.36%\n", "iteration 9 modif 600000 # 1034325 / 64382878 = 1.61%\n", "iteration 10 modif 567801 # 1175548 / 64382878 = 1.83%\n", "iteration 11 modif 510076 # 1292961 / 64382878 = 2.01%\n", "iteration 12 modif 433796 # 1384196 / 64382878 = 2.15%\n", "iteration 13 modif 349510 # 1449682 / 64382878 = 2.25%\n", "iteration 14 modif 267371 # 1493038 / 64382878 = 2.32%\n", "iteration 15 modif 194659 # 1519796 / 64382878 = 2.36%\n", "iteration 16 modif 135778 # 1535222 / 64382878 = 2.38%\n", "iteration 17 modif 90864 # 1543743 / 64382878 = 2.40%\n", "iteration 18 modif 58784 # 1548367 / 64382878 = 2.40%\n", "iteration 19 modif 37306 # 1550830 / 64382878 = 2.41%\n", "iteration 20 modif 23232 # 1552160 / 64382878 = 2.41%\n", "nb odd degrees 7318 nb added edges 0\n", "nb odd degrees 28 nb added edges 3645\n", "added length 312.732395725235\n", "initial length 1511.8818424919855\n", "degrees [444, 833, 1112, 1672, 2080, 2218, 2428, 2595, 2767, 2772]\n", "------- nb odd vertices 28 iteration 0\n", "iteration 0 modif 18055 # 1552928 / 64382878 = 2.41%\n", "iteration 1 modif 11117 # 1555011 / 64382878 = 2.42%\n", "iteration 2 modif 8346 # 1556008 / 64382878 = 2.42%\n", "iteration 3 modif 6811 # 1557026 / 64382878 = 2.42%\n", "iteration 4 modif 6056 # 1558080 / 64382878 = 2.42%\n", "iteration 5 modif 5889 # 1559203 / 64382878 = 2.42%\n", "iteration 6 modif 6182 # 1560422 / 64382878 = 2.42%\n", "iteration 7 modif 6606 # 1561720 / 64382878 = 2.43%\n", "iteration 8 modif 7245 # 1563108 / 64382878 = 2.43%\n", "iteration 9 modif 8000 # 1564601 / 64382878 = 2.43%\n", "iteration 10 modif 8813 # 1566180 / 64382878 = 2.43%\n", "iteration 11 modif 9947 # 1567891 / 64382878 = 2.44%\n", "iteration 12 modif 11220 # 1569765 / 64382878 = 2.44%\n", "iteration 13 modif 12595 # 1571750 / 64382878 = 2.44%\n", "iteration 14 modif 14231 # 1573865 / 64382878 = 2.44%\n", "iteration 15 modif 15907 # 1576113 / 64382878 = 2.45%\n", "iteration 16 modif 17720 # 1578466 / 64382878 = 2.45%\n", "iteration 17 modif 19396 # 1580917 / 64382878 = 2.46%\n", "iteration 18 modif 21385 # 1583422 / 64382878 = 2.46%\n", "iteration 19 modif 23468 # 1586072 / 64382878 = 2.46%\n", "iteration 20 modif 25721 # 1588844 / 64382878 = 2.47%\n", "nb odd degrees 7318 nb added edges 0\n", "nb odd degrees 0 nb added edges 3659\n", "added length 341.68448700406753\n", "initial length 1511.8818424919855\n", "degrees []\n", "end, nb added 3659\n"]}], "source": ["from ensae_teaching_cs.special.rues_paris import eulerien_extension, distance_paris,get_data\n", "print(\"data\")\n", "edges = get_data()\n", "print(\"start, nb edges\", len(edges))\n", "added = eulerien_extension(edges, distance=distance_paris)\n", "print(\"end, nb added\", len(added))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On enregistre le r\u00e9sultat o\u00f9 on souhaite recommencer \u00e0 partir de ce moment-l\u00e0 plus tard."]}, {"cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": ["with open(\"added.txt\",\"w\") as f : f.write(str(added))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Et si vous voulez le retrouver :"]}, {"cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": ["from ensae_teaching_cs.data import added\n", "data = added()"]}, {"cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": ["from ensae_teaching_cs.special.rues_paris import eulerien_extension, distance_paris, get_data\n", "edges = get_data()\n", "\n", "with open(data, \"r\") as f: text = f.read()\n", "added_edges = eval(text)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Chemin Eul\u00e9rien\n", "\n", "A cet instant, on n'a pas vraiment besoin de conna\u00eetre la longueur du chemin eul\u00e9rien passant par tous les arcs. Il s'agit de la somme des arcs initiaux et ajout\u00e9s (soit environ 334 + 1511). On suppose qu'il n'y qu'une composante connexe. Construire le chemin eul\u00e9rien fait appara\u00eetre quelques difficult\u00e9s comme la suivante : on parcourt le graphe dans un sens mais on peut laisser de c\u00f4t\u00e9 une partie du chemin et cr\u00e9er une seconde composante connexe."]}, {"cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [{"data": {"image/png": "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\nF5Hr3RwAAAAASUVORK5CYII=\n", "text/plain": [""]}, "execution_count": 23, "metadata": {}, "output_type": "execute_result"}], "source": ["from pyquickhelper.helpgen import NbImage\n", "NbImage(\"euler.png\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Quelques algorithmes sont disponibles sur cette page [Eulerian_path](http://en.wikipedia.org/wiki/Eulerian_path). L'algorithme de Hierholzer consiste \u00e0 commencer un chemin eul\u00e9rien qui peut revenir au premier avant d'avoir tout parcouru. Dans ce cas, on parcourt les noeuds du graphe pour trouver un noeud qui repart ailleurs et qui revient au m\u00eame noeud. On insert cette boucle dans le chemin initial. Tout d'abord, on construit une structure qui pour chaque noeud associe les noeuds suivant. La fonction [euler_path](http://www.xavierdupre.fr/app/ensae_teaching_cs/helpsphinx/ensae_teaching_cs/special/rues_paris.html#special.rues_paris.eurler_path)"]}, {"cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [{"data": {"text/plain": ["[(2121, ['street', 3, 2121, 0.049532522902426074]),\n", " (10363, ['street', 2121, 10363, 0.1474817976215633]),\n", " (3517, ['street', 3517, 10363, 0.10602477572757586]),\n", " (2829, ['street', 2829, 3517, 0.03409802890007801]),\n", " (3515, ['street', 3515, 2829, 0.060836636019222866])]"]}, "execution_count": 24, "metadata": {}, "output_type": "execute_result"}], "source": ["from ensae_teaching_cs.special.rues_paris import euler_path\n", "path = euler_path(edges, added_edges)\n", "path[:5]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Le label ``street`` signifie que l'ar\u00eate provient de l'ensemble des rues, le label ``jump`` signifie que c'est une ar\u00eate ajout\u00e9e. Pour couper le parcours en 8 (8 voitures), il suffit de couper le chemin en 8 parts presque \u00e9gales en trouvant 8 ar\u00eates ``jump`` presque \u00e9galement r\u00e9parties le long du chemin eul\u00e9rien. On peut bien \u00e9videmment couper \u00e0 une ar\u00eate ``street`` mais celle-l\u00e0 devra faire partie d'un des deux ensembles pas l'ar\u00eate ``jump`` qui peut \u00eatre jet\u00e9e. On peut envisager une approche dichotomique. Couper en deux, recouper en deux chaque intervalle et minimiser sur la meilleur ar\u00eate ``jump`` du d\u00e9but.\n", "\n", "Il reste maintenant \u00e0 prendre en compte les sens interdits. Cette modification peut intervenir \u00e0 deux endroits :\n", "\n", "* Soit le nombre de sens interdit est faible et on peut s'en d\u00e9patouiller en parcourant le plus possible des rues dans le bon sens, en choisissant le plus les arcs dans le bon sens lors de la cr\u00e9ation du chemin eul\u00e9rien.\n", "* Soit on cr\u00e9e un graphe eul\u00e9rien orient\u00e9 (pour chaque noeud, les nombres d'ar\u00eates sortantes et entrantes sont \u00e9gaux, voir [Euler Circuit in a Directed Graph](http://www.geeksforgeeks.org/euler-circuit-directed-graph/)).\n", "\n", "Dans le cas o\u00f9 on souhaite que les voitures partent toutes du m\u00eame point et reviennent \u00e0 ce m\u00eame point, la solution pr\u00e9c\u00e9dente fournira une borne sup\u00e9rieure (il suffit d'ajouter des ar\u00eates ``jump`` pour amener et ramener les voitures)."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Algorithme optimal\n", "\n", "La variante de l'algorithme de [Kruskal](https://en.wikipedia.org/wiki/Kruskal%27s_algorithm) propose une solution approch\u00e9e pour apparier les noeuds de degr\u00e9 impair. On cherche \u00e0 minimiser la somme des distances entre les noeuds apparier. Il existe un algorithme optimal pour r\u00e9soudre ce probl\u00e8me : l'[algorithme d'Edmonds pour les couplages](https://en.wikipedia.org/wiki/Blossom_algorithm)."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Variantes"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Sens interdit et gaphe orient\u00e9\n", "\n", "Si la ville contient des sens interdits, c'est comme si le graphe \u00e9tait orient\u00e9. Chaque arc ne peut \u00eatre parcouru que dans un sens. Il faut alors distinguer les degr\u00e9s entrants et sortants de chaque noeud. Il faut s'assurer pour chaque noeud que le nombre d'arc entrant et sortant sont identiques. Si ce n'est pas le cas, on se sert de l'algorithme d'appariement pour recr\u00e9er des arcs."]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Windy postman problem\n", "\n", "C'est une variante pour laquelle le co\u00fbt d'un arc n'est pas le m\u00eame selon qu'on le parcourt dans un sens ou dans l'autre (\u00e0 contre sens). Ce probl\u00e8me est [NP complet](https://en.wikipedia.org/wiki/NP-completeness)."]}, {"cell_type": "code", "execution_count": 24, "metadata": {"collapsed": true}, "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.2"}}, "nbformat": 4, "nbformat_minor": 2}