<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Projets on Benjamin Geer</title>
    <link>https://benjamingeer.eu/fr/categories/projets/</link>
    <description>Recent content in Projets on Benjamin Geer</description>
    <generator>Hugo</generator>
    <language>fr-FR</language>
    <lastBuildDate>Wed, 19 Aug 2026 15:06:58 +0000</lastBuildDate>
    <atom:link href="https://benjamingeer.eu/fr/categories/projets/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Comparer les performances de requêtes SQL</title>
      <link>https://benjamingeer.eu/fr/post/sqlstopwatch/</link>
      <pubDate>Thu, 29 Jan 2026 18:25:18 +0100</pubDate>
      <guid>https://benjamingeer.eu/fr/post/sqlstopwatch/</guid>
      <description>&lt;p&gt;J&amp;rsquo;ai réalisé un petit programme en Rust,&#xA;&lt;a href=&#34;https://codeberg.org/benjamingeer/sqlstopwatch&#34; target=&#34;_blank&#34;&gt;sqlstopwatch&lt;/a&gt;, pour comparer&#xA;les performances de différentes requêtes&#xA;&lt;a href=&#34;https://fr.wikipedia.org/wiki/Structured_Query_Language&#34; target=&#34;_blank&#34;&gt;SQL&lt;/a&gt;. J&amp;rsquo;ai été&#xA;inspiré par l&amp;rsquo;article &lt;a href=&#34;https://www.jooq.org/benchmark&#34; target=&#34;_blank&#34;&gt;Benchmarking&#xA;SQL&lt;/a&gt; publié par le projet jOOQ, dans lequel le&#xA;code du test est implémenté en SQL. Je voulais quelque chose de semblable,&#xA;mais j&amp;rsquo;avais quelques exigences supplémentaires :&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Un programme en ligne de commande avec une interface utilisateur simple en&#xA;mode texte (TUI) qui affiche une barre de progression.&lt;/li&gt;&#xA;&lt;li&gt;Le programme devrait prendre en charge&#xA;&lt;a href=&#34;https://www.postgresql.org&#34; target=&#34;_blank&#34;&gt;PostgreSQL&lt;/a&gt;, &lt;a href=&#34;https://www.mysql.com&#34; target=&#34;_blank&#34;&gt;MySQL&lt;/a&gt; et&#xA;&lt;a href=&#34;https://sqlite.org&#34; target=&#34;_blank&#34;&gt;SQLite&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Il devrait lire les requêtes SQL et les paramètres du test dans un fichier de&#xA;configuration indiqué sur la ligne de commande.&lt;/li&gt;&#xA;&lt;li&gt;Il devrait afficher les résultats sous forme de table dans le terminal ou les&#xA;enregistrer dans un fichier au format CSV que je puisse utiliser pour générer un&#xA;diagramme.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;L&amp;rsquo;interface utilisateur a été facile à réaliser avec&#xA;&lt;a href=&#34;https://ratatui.rs&#34; target=&#34;_blank&#34;&gt;Ratatui&lt;/a&gt;. Pour interagir avec la base de données, j&amp;rsquo;ai&#xA;utilisé la bibliothèque asynchrone &lt;a href=&#34;https://crates.io/crates/sqlx&#34; target=&#34;_blank&#34;&gt;sqlx&lt;/a&gt;, qui&#xA;fournit une bibliothèque SQLite embarquée.&lt;/p&gt;&#xA;&lt;p&gt;J&amp;rsquo;ai pensé à utiliser le format &lt;a href=&#34;https://toml.io&#34; target=&#34;_blank&#34;&gt;TOML&lt;/a&gt; pour le fichier de&#xA;configuration, mais le fichier doit fournir les identifiants de connexion. Dans&#xA;les environnements de test, il se peut que les identifiants doivent être chargés&#xA;à partir de variables d&amp;rsquo;environnement ou de fichiers sur un système de fichiers&#xA;monté, mais TOML ne permet pas d&amp;rsquo;effectuer de telles opérations. En plus, on&#xA;pourrait vouloir générer plusieurs requêtes similaires pour les comparer, comme&#xA;je l&amp;rsquo;ai fait dans &lt;a href=&#34;https://benjamingeer.eu/fr/post/bref&#34;&gt;ce projet d&amp;rsquo;optimisation de base de&#xA;données&lt;/a&gt;. Par conséquent, il vaut mieux que le fichier de&#xA;configuration soit un programme dans un langage de script. Mon &lt;a href=&#34;https://benjamingeer.eu/fr/post/organiclox&#34;&gt;exercice&#xA;d&amp;rsquo;implémentation d&amp;rsquo;un interpréteur de langage de script&lt;/a&gt;&#xA;m&amp;rsquo;avait permis d&amp;rsquo;apprécier à sa juste valeur la machine virtuelle&#xA;&lt;a href=&#34;https://www.lua.org&#34; target=&#34;_blank&#34;&gt;Lua&lt;/a&gt;. Le fichier de configuration est donc un script en&#xA;Lua, que je trouve plus commode de rédiger en&#xA;&lt;a href=&#34;https://fennel-lang.org&#34; target=&#34;_blank&#34;&gt;Fennel&lt;/a&gt;, un dialect de Lisp qui se compile en Lua.&#xA;Grâce à la bibliothèque &lt;a href=&#34;https://crates.io/crates/mlua&#34; target=&#34;_blank&#34;&gt;mlua&lt;/a&gt;, il a été très&#xA;facile d&amp;rsquo;embarquer un interpréteur Lua dans le programme et d&amp;rsquo;utiliser&#xA;&lt;a href=&#34;https://serde.rs&#34; target=&#34;_blank&#34;&gt;Serde&lt;/a&gt; pour convertir des tables Lua en &lt;code&gt;struct&lt;/code&gt;s Rust.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Créer un client Bittorrent en Rust</title>
      <link>https://benjamingeer.eu/fr/post/sayaca/</link>
      <pubDate>Thu, 15 Jan 2026 15:16:01 +0100</pubDate>
      <guid>https://benjamingeer.eu/fr/post/sayaca/</guid>
      <description>&lt;h2 class=&#34;heading&#34; id=&#34;aperçu&#34;&gt;&#xA;  Aperçu&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#aper%c3%a7u&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Pour continuer mon apprentissage de &lt;a href=&#34;https://benjamingeer.eu/fr/topics/rust/&#34;&gt;Rust&lt;/a&gt;, j&amp;rsquo;ai décidé de&#xA;réaliser un client pour&#xA;&lt;a href=&#34;https://en.wikipedia.org/wiki/BitTorrent&#34; target=&#34;_blank&#34;&gt;Bittorrent&lt;/a&gt;, le protocole de&#xA;transfert de données pair-à-pair. Les clients Bittorrent que j&amp;rsquo;ai utilisés ont&#xA;des interfaces graphiques complexes qui semblent destinées aux gens qui&#xA;téléchargent des torrents à longueur de journée, plutôt que pour l&amp;rsquo;utilisateur&#xA;occasionnel comme moi, qui veut tout simplement obtenir un seul fichier. Et&#xA;comme beaucoup d&amp;rsquo;applications à interface graphique, les clients Bittorrent ont&#xA;tendance à accumuler des fichiers qui occupent de l&amp;rsquo;espace disque dans des&#xA;répertoires obscurs. Je fais beaucoup de choses dans le terminal et quand j&amp;rsquo;ai&#xA;besoin de télécharger un fichier, mon réflexe est d&amp;rsquo;utiliser&#xA;&lt;a href=&#34;https://curl.se/&#34; target=&#34;_blank&#34;&gt;curl&lt;/a&gt;. Je me suis donc dit, pourquoi ne pas créer quelque&#xA;chose comme curl pour Bittorrent ? En pensant à &lt;a href=&#34;https://curl.se/docs/tutorial.html#:~:text=www.example.com-,Progress%20Meter,-The%20progress%20meter&#34; target=&#34;_blank&#34;&gt;l&amp;rsquo;indicateur de&#xA;progression&lt;/a&gt;&#xA;de curl, l&amp;rsquo;idée m&amp;rsquo;est venue à l&amp;rsquo;esprit de faire quelque chose de semblable avec&#xA;&lt;a href=&#34;https://ratatui.rs&#34; target=&#34;_blank&#34;&gt;Ratatui&lt;/a&gt;, une bibliothèque de création d&amp;rsquo;environnements&#xA;en mode texte (TUI), que je voulais de toute façon essayer.&lt;/p&gt;&#xA;&lt;p&gt;La réalisation d&amp;rsquo;un client Bittorrent semblait être une bonne occasion&#xA;d&amp;rsquo;apprendre la programmation asynchrone en Rust. J&amp;rsquo;avais lu beaucoup de&#xA;critiques d&amp;rsquo;&lt;code&gt;async&lt;/code&gt; en Rust, mais je l&amp;rsquo;ai trouvé agréable à utiliser (en&#xA;utilisant la bibliothèque &lt;a href=&#34;https://tokio.rs&#34; target=&#34;_blank&#34;&gt;Tokio&lt;/a&gt;) et certainement plus&#xA;confortable que les infrastructures logicielles comparables que j&amp;rsquo;avais&#xA;utilisées en Scala (&lt;a href=&#34;https://akka.io&#34; target=&#34;_blank&#34;&gt;Akka&lt;/a&gt; et &lt;a href=&#34;https://typelevel.org/cats-effect/&#34; target=&#34;_blank&#34;&gt;Cats&#xA;Effect&lt;/a&gt;). J&amp;rsquo;aime particulièrement le fait&#xA;qu&amp;rsquo;une fonction &lt;code&gt;async&lt;/code&gt; peut être exécutée dans une tâche existante ou dans sa&#xA;propre tâche, à la différence du &lt;code&gt;Future&lt;/code&gt; de Scala, qui est affecté à un fil&#xA;d&amp;rsquo;exécution et se lance dès sa construction. L&amp;rsquo;approche de Rust semble mieux&#xA;adapté au remaniement et à la maintenabilité. En même temps, je suis content de&#xA;ne pas avoir à gérer la complexité liée à l&amp;rsquo;utilisation des monades comme dans&#xA;Cats Effect.&lt;/p&gt;&#xA;&lt;p&gt;Le résultat est &lt;a href=&#34;https://codeberg.org/benjamingeer/sayaca&#34; target=&#34;_blank&#34;&gt;Sayaca&lt;/a&gt;, qui porte&#xA;le nom d&amp;rsquo;un oiseau sud-américain qui joue un rôle important dans la dispersion&#xA;des graines (le verbe anglais &lt;em&gt;to seed&lt;/em&gt; veut dire ensemencer, et dans la&#xA;terminologie de Bittorrent, envoyer des données aux autres pairs).&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;la-conception&#34;&gt;&#xA;  La conception&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#la-conception&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Ma première tâche a été de réaliser un analyseur syntaxique pour&#xA;&lt;a href=&#34;https://en.wikipedia.org/wiki/Bencode&#34; target=&#34;_blank&#34;&gt;Bencode&lt;/a&gt;, le format de données&#xA;utilisées dans le protocole Bittorrent. Au niveau conceptuel, Bencode ressemble&#xA;à &lt;a href=&#34;https://en.wikipedia.org/wiki/JSON&#34; target=&#34;_blank&#34;&gt;JSON&lt;/a&gt;, mais il est destiné à la&#xA;représentation de données binaires plutôt que textuelles. J&amp;rsquo;avais envie&#xA;d&amp;rsquo;essayer d&amp;rsquo;utiliser une bibliothèque de combinateurs d&amp;rsquo;analyseurs syntaxiques,&#xA;et je n&amp;rsquo;ai pas eu de mal à implémenter l&amp;rsquo;analyseur en utilisant&#xA;&lt;a href=&#34;https://github.com/rust-bakery/nom&#34; target=&#34;_blank&#34;&gt;nom&lt;/a&gt;. Comme je voulais être en mesure de&#xA;sérialiser et de désérialiser des &lt;code&gt;struct&lt;/code&gt;s en Rust au format Bencode, j&amp;rsquo;ai&#xA;ajouté la prise en charge de la bibliothèque &lt;a href=&#34;https://serde.rs&#34; target=&#34;_blank&#34;&gt;Serde&lt;/a&gt;. J&amp;rsquo;ai&#xA;publié la crate issue de ce travail sous le nom de&#xA;&lt;a href=&#34;https://crates.io/crates/bside&#34; target=&#34;_blank&#34;&gt;bside&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;La principale difficulté dans la conception du client résidait dans le caractère&#xA;confus des spécifications Bittorrent. Il y a des ambigüités (le mot &lt;em&gt;piece&lt;/em&gt; a&#xA;deux sens différents) et les implémentations se sont écartées des spécifications&#xA;(par exemple, les identifiants de pair ne sont pas utilisés pour identifier&#xA;les pairs). Une grande partie des informations relatives au protocole ne figure&#xA;pas dans les spécifications officielles, mais dans d&amp;rsquo;autres documents dispersés&#xA;sur le Web. Il y a une &lt;a href=&#34;https://www.bittorrent.org/beps/bep_0000.html&#34; target=&#34;_blank&#34;&gt;longue&#xA;liste&lt;/a&gt; (non mise à jour depuis&#xA;2018) de projets d&amp;rsquo;extension du protocole qui sont pris en charge par de&#xA;nombreux clients. Une extension dite &lt;a href=&#34;https://en.wikipedia.org/wiki/BitTorrent_protocol_encryption&#34; target=&#34;_blank&#34;&gt;de&#xA;chiffrement&lt;/a&gt;&#xA;(qui semble en réalité décrire une forme de brouillage) semble être largement&#xA;mise en œuvre, mais d&amp;rsquo;après ce que je peux en juger, depuis 2023, &lt;a href=&#34;https://web.archive.org/web/20230405235517/http://wiki.vuze.com/w/Message_Stream_Encryption&#34; target=&#34;_blank&#34;&gt;sa&#xA;spécification&lt;/a&gt;&#xA;n&amp;rsquo;est conservée que dans la Wayback Machine de l&amp;rsquo;Internet Archive. Il existe un&#xA;&lt;a href=&#34;https://bittorrent.org/beps/bep_0052.html&#34; target=&#34;_blank&#34;&gt;projet de spécification du protocole BitTorrent&#xA;v2&lt;/a&gt; (non mis à jour depuis 2017) qui&#xA;tente de corriger certains défauts du protocole d&amp;rsquo;origine, comme sa dépendance&#xA;vis-à-vis de la fonction de hachage&#xA;&lt;a href=&#34;https://en.wikipedia.org/wiki/SHA-1&#34; target=&#34;_blank&#34;&gt;SHA-1&lt;/a&gt; (qui n&amp;rsquo;est plus considérée comme&#xA;sécurisée depuis 2005). J&amp;rsquo;aurais pu errer longtemps dans un dédale de documents&#xA;et dans le code source des clients existants. Pour simplifier les choses, j&amp;rsquo;ai&#xA;décidé de ne mettre en œuvre que le &lt;a href=&#34;https://bittorrent.org/beps/bep_0003.html&#34; target=&#34;_blank&#34;&gt;protocole&#xA;d&amp;rsquo;origine&lt;/a&gt; et l&amp;rsquo;extension &lt;a href=&#34;https://www.bittorrent.org/beps/bep_0007.html&#34; target=&#34;_blank&#34;&gt;IPv6&#xA;tracker&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Quand un client Bittorrent enregistre des données sur le disque, il devrait&#xA;offrir de bonnes performances avec des fichiers volumineux, être capable&#xA;d&amp;rsquo;interrompre un téléchargement et de le reprendre plus tard (ce qui signifie&#xA;qu&amp;rsquo;il doit noter quels fragments ont été téléchargées) et gérer les torrents qui&#xA;comprennent plusieurs fichiers. Pour faire tout cela, et pour que les choses&#xA;soient claires pour l&amp;rsquo;utilisateur, j&amp;rsquo;ai choisi d&amp;rsquo;enregistrer les données&#xA;téléchargées dans un fichier intermédiaire (avec l&amp;rsquo;extension &lt;code&gt;.sayaca&lt;/code&gt;), dans le&#xA;même répertoire où les fichiers finaux seront enregistrés. Le fichier&#xA;intermédiaire contient un champ de bits indiquant les fragments qui ont été&#xA;téléchargés (il s&amp;rsquo;agit du même champ de bits qu&amp;rsquo;il faut de toute façon envoyer&#xA;aux pairs). Pour lire et écrire ce fichier, Sayaca utilise la projection en&#xA;mémoire, ce qui devrait offrir de bonnes performances d&amp;rsquo;entrée-sortie avec des&#xA;fichiers volumineux. Une fois le téléchargement terminé, il copie les données&#xA;depuis le fichier intermédiaire vers les fichiers finaux. Lorsque le programme&#xA;se ferme, le fichier intermédiaire est supprimé s&amp;rsquo;il n&amp;rsquo;est plus nécessaire.&lt;/p&gt;&#xA;&lt;p&gt;Comme un client Bittorrent est tributaire des entrées-sorties (&lt;em&gt;I/O bound&lt;/em&gt;),&#xA;j&amp;rsquo;ai décidé d&amp;rsquo;employer &lt;a href=&#34;https://codeberg.org/benjamingeer/sayaca/src/branch/main/docs/design.md&#34; target=&#34;_blank&#34;&gt;une architecture&#xA;événementielle&lt;/a&gt;&#xA;dans laquelle une seule tâche accomplit la majeure partie du travail, comme dans&#xA;&lt;a href=&#34;https://redis.io&#34; target=&#34;_blank&#34;&gt;Redis&lt;/a&gt;. Cette tâche principale délègue toute les&#xA;entrées-sorties réseau à d&amp;rsquo;autres tâches, avec lesquelles elle communique via&#xA;des &lt;a href=&#34;https://docs.rs/tokio/latest/tokio/sync/&#34; target=&#34;_blank&#34;&gt;canaux&lt;/a&gt;. Cela a été très simple à&#xA;mettre en œuvre et a eu l&amp;rsquo;avantage de rendre facile la création de tests&#xA;unitaires pour la tâche principale.&lt;/p&gt;&#xA;&lt;p&gt;Une grande partie du travail effectué par un client Bittorrent revient à tenir&#xA;une sorte de comptabilité. Dans Sayaca, ce travail est la responsabilité du&#xA;&lt;a href=&#34;https://codeberg.org/benjamingeer/sayaca/src/branch/main/src/client/bookkeeper.rs&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;Bookkeeper&lt;/code&gt;&lt;/a&gt;&#xA;(« comptable »). Par exemple, dans &lt;a href=&#34;https://wiki.theory.org/BitTorrentSpecification#Piece_downloading_strategy&#34; target=&#34;_blank&#34;&gt;l&amp;rsquo;algorithme&#xA;recommandé&lt;/a&gt;&#xA;de sélection des fragments à demander aux pairs, le client essaie de demander&#xA;d&amp;rsquo;abord les fragments les plus rares. Cela nécessite une structure de données&#xA;qui note les fragments dont dispose chaque pair, ainsi que la rareté de chaque&#xA;fragment, entre autres. Il y a plusieurs façons de réaliser cela et j&amp;rsquo;ai décidé&#xA;d&amp;rsquo;utiliser un &lt;a href=&#34;https://doc.rust-lang.org/std/collections/struct.BTreeMap.html&#34; target=&#34;_blank&#34;&gt;tableau associatif&#xA;ordonné&lt;/a&gt;, trié&#xA;par ordre de rareté, pour stocker les identifiants de fragments et les&#xA;ensembles de pairs qui les possèdent. Le &lt;code&gt;Bookkeeper&lt;/code&gt; peut ainsi trouver&#xA;facilement un fragment, choisi au hasard parmi les plus rares, associé à un pair&#xA;choisi au hasard parmi ceux qui possèdent ce fragment et qui nous ont autorisé à&#xA;leur envoyer des demandes. Ainsi une grande partie du travail du client consiste&#xA;à mettre à jour le &lt;code&gt;Bookkeper&lt;/code&gt; lors de la réception de nouvelles informations et&#xA;à l&amp;rsquo;interroger pour savoir ce qu&amp;rsquo;il faut faire ensuite.&lt;/p&gt;&#xA;&lt;p&gt;J&amp;rsquo;aime bien les TUI et il a été facile de créer un TUI simple avec Ratatui. Mais&#xA;comme le client est une bibliothèque qui communique avec son interface&#xA;utilisateur via des canaux, il serait simple d&amp;rsquo;intégrer le client dans une autre&#xA;interface utilisateur, comme une interface en ligne de commande &lt;a href=&#34;https://xogium.me/the-text-mode-lie-why-modern-tuis-are-a-nightmare-for-accessibility&#34; target=&#34;_blank&#34;&gt;plus&#xA;accessible&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;dautres-approches-possibles&#34;&gt;&#xA;  D&amp;rsquo;autres approches possibles&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#dautres-approches-possibles&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;J&amp;rsquo;ai choisi d&amp;rsquo;utiliser Tokio parce que je voulais en savoir plus à son sujet et&#xA;sur &lt;code&gt;async&lt;/code&gt;, mais je pense que le programme n&amp;rsquo;aurait probablement pas été très&#xA;différent si j&amp;rsquo;avais utilisé des fils d&amp;rsquo;exécution à la place, avec la même&#xA;communication via des canaux.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Créer une machine virtuelle en Rust</title>
      <link>https://benjamingeer.eu/fr/post/organiclox/</link>
      <pubDate>Sun, 12 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.eu/fr/post/organiclox/</guid>
      <description>&lt;h2 class=&#34;heading&#34; id=&#34;aperçu&#34;&gt;&#xA;  Aperçu&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#aper%c3%a7u&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Pour m&amp;rsquo;aider à apprendre le langage Rust, j&amp;rsquo;ai décidé de réaliser un&#xA;interpréteur pour Lox, le langage de script que Robert Nystrom a créé pour son&#xA;livre &lt;a href=&#34;https://craftinginterpreters.com/&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;Crafting Interpreters&lt;/em&gt;&lt;/a&gt;. Je&#xA;m&amp;rsquo;intéresse aux langages de script qui sont destinés à être embarqués dans des&#xA;applications, et cet exercice m&amp;rsquo;a semblé un bon moyen d&amp;rsquo;en savoir plus sur la&#xA;construction de ce type de langage.&lt;/p&gt;&#xA;&lt;p&gt;Le livre de Nystrom présente, étape par étape, le développement de deux versions&#xA;de l&amp;rsquo;interpréteur. Alors que la première, en Java, parcourt un arbre de syntaxe&#xA;abstraite (AST) pour exécuter un script, la deuxième, en C, comporte une machine&#xA;virtuelle qui exécute du bytecode. Cette deuxième version m&amp;rsquo;intéressait&#xA;davantage. Au fil des ans, j&amp;rsquo;avais réalisé deux interpréteurs qui parcourent des&#xA;arbres de syntaxe abstraite, en commençant par &lt;a href=&#34;https://freemarker.apache.org/&#34; target=&#34;_blank&#34;&gt;Apache&#xA;FreeMarker&lt;/a&gt;, ainsi qu&amp;rsquo;&lt;a href=&#34;https://doi.org/10.3233/sw-200386&#34; target=&#34;_blank&#34;&gt;un compilateur source à&#xA;source optimisant&lt;/a&gt; utilisant l&amp;rsquo;inférence de&#xA;types. Mais je n&amp;rsquo;avais pas encore fait de machine virtuelle. L&amp;rsquo;idée me rappelait&#xA;de bons souvenirs de programmation en assembleur sur l&amp;rsquo;&lt;a href=&#34;https://en.wikipedia.org/wiki/Apple_II&#34; target=&#34;_blank&#34;&gt;Apple&#xA;II&lt;/a&gt; quand j&amp;rsquo;avais quinze ans. Le jeu&#xA;d&amp;rsquo;instructions de la machine virtuelle de Nystrom est plus simple que celle du&#xA;processeur &lt;a href=&#34;https://fr.wikipedia.org/wiki/MOS_Technology_6502&#34; target=&#34;_blank&#34;&gt;Motorola 6502&lt;/a&gt; de&#xA;l&amp;rsquo;Apple II, mais le principe est le même. J&amp;rsquo;ai donc sauté la première partie du&#xA;livre pour aller directement à celle où il s&amp;rsquo;agit de la machine virtuelle.&lt;/p&gt;&#xA;&lt;p&gt;Le résultat est &lt;a href=&#34;https://codeberg.org/benjamingeer/organiclox&#34; target=&#34;_blank&#34;&gt;OrganicLox&lt;/a&gt;. La&#xA;conception est globalement celle présentée dans le livre, mais j&amp;rsquo;ai essayé de&#xA;coder dans un Rust courant, en visant des performances raisonnables, sans écrire&#xA;de code non sécurisé. Les fonctionnalités d&amp;rsquo;OrganicLox devraient être identiques&#xA;à celles du programme &lt;code&gt;clox&lt;/code&gt; de Nystrom : au moins, ses &lt;a href=&#34;https://github.com/munificent/craftinginterpreters/?tab=readme-ov-file#testing-your-implementation&#34; target=&#34;_blank&#34;&gt;246 tests&#xA;automatisés&lt;/a&gt;&#xA;passent.&lt;/p&gt;&#xA;&lt;p&gt;J&amp;rsquo;ai décidé de ne pas créer mon propre ramasse-miettes, car tout le monde semble&#xA;s&amp;rsquo;accorder à dire que les ramasse-miettes sont &lt;a href=&#34;https://manishearth.github.io/blog/2021/04/05/a-tour-of-safe-tracing-gc-designs-in-rust/&#34; target=&#34;_blank&#34;&gt;particulièrement difficiles à&#xA;réaliser en&#xA;Rust&lt;/a&gt;.&#xA;Par souci de simplicité, j&amp;rsquo;ai opté plutôt pour le comptage des références (au&#xA;moyen de &lt;a href=&#34;https://doc.rust-lang.org/std/rc/struct.Rc.html&#34; target=&#34;_blank&#34;&gt;Rc&lt;/a&gt;). Sur la branche&#xA;&lt;a href=&#34;https://codeberg.org/benjamingeer/organiclox/src/branch/main&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;main&lt;/code&gt;&lt;/a&gt;, cela&#xA;veut dire que les cycles de propriétés d&amp;rsquo;objets ne seront pas nettoyés. Sur la&#xA;branche&#xA;&lt;a href=&#34;https://codeberg.org/benjamingeer/organiclox/src/branch/with_dumpster_gc&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;with_dumpster_gc&lt;/code&gt;&lt;/a&gt;,&#xA;j&amp;rsquo;ai remplacé &lt;code&gt;Rc&lt;/code&gt; par la crate&#xA;&lt;a href=&#34;https://codeberg.org/benjamingeer/organiclox/src/branch/main&#34; target=&#34;_blank&#34;&gt;dumpster&lt;/a&gt;, qui&#xA;assure le comptage des références et nettoie aussi les cycles.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;ce-que-jai-préféré&#34;&gt;&#xA;  Ce que j&amp;rsquo;ai préféré&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#ce-que-jai-pr%c3%a9f%c3%a9r%c3%a9&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;J&amp;rsquo;ai beaucoup aimé ce livre : les explications claires de Nystrom, ses&#xA;illustrations utiles, son style léger et son humour ont rendu le livre&#xA;agréable à lire.&lt;/p&gt;&#xA;&lt;p&gt;Pour moi, la mise en œuvre des variables locales et des fermetures dans une&#xA;machine virtuelle à pile ont été parmi les aspects les plus intéressants de la&#xA;conception que présente Nystrom, conception qui s&amp;rsquo;inspire largement de &lt;a href=&#34;https://www.lua.org/doc/jucs05.pdf&#34; target=&#34;_blank&#34;&gt;celle de&#xA;l&amp;rsquo;interpréteur Lua&lt;/a&gt;. J&amp;rsquo;ai aimé apprendre que&#xA;le compilateur &lt;a href=&#34;https://craftinginterpreters.com/local-variables.html&#34; target=&#34;_blank&#34;&gt;associe les variables locales à des positions spécifiques sur la&#xA;pile&lt;/a&gt;, de sorte que la&#xA;machine virtuelle n&amp;rsquo;a besoin de connaître que ces positions et non pas les noms&#xA;des variables concernés.&lt;/p&gt;&#xA;&lt;p&gt;La mise en œuvre des &lt;em&gt;upvalues&lt;/em&gt;, à savoir les variables qui sont capturées par&#xA;les fermetures et qui doivent donc éventuellement être allouées sur le tas, n&amp;rsquo;a&#xA;pas été simple à faire correctement. En corrigeant un bogue, j&amp;rsquo;ai été heureux de&#xA;me rendre compte que &lt;a href=&#34;https://github.com/munificent/craftinginterpreters/blob/master/test/function/local_recursion.lox&#34; target=&#34;_blank&#34;&gt;l&amp;rsquo;appel récursif d&amp;rsquo;une function définie dans une portée&#xA;locale&lt;/a&gt;&#xA;nécessite que la fermeture de la fonction soit une des ses propres &lt;em&gt;upvalues&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;ce-que-jaurais-souhaité&#34;&gt;&#xA;  Ce que j&amp;rsquo;aurais souhaité&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#ce-que-jaurais-souhait%c3%a9&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Les explications de Nystrom sont tantôt ascendantes, tantôt descendantes.&#xA;L&amp;rsquo;approche ascendante a présenté plus de difficultés quant à la traduction de&#xA;sa conception en Rust, car je devais deviner où il voulait en venir. Plusieurs&#xA;fois j&amp;rsquo;ai dû remanier beaucoup de code parce que je n&amp;rsquo;avais pas deviné juste.&#xA;Comme l&amp;rsquo;implémentation de Lox dans toutes sortes de langages de programmation&#xA;semble être &lt;a href=&#34;https://github.com/munificent/craftinginterpreters/wiki/Lox-implementations&#34; target=&#34;_blank&#34;&gt;un exercice courant&lt;/a&gt;,&#xA;il aurait été utile d&amp;rsquo;avoir plus souvent une vue d&amp;rsquo;ensemble de la conception.&lt;/p&gt;&#xA;&lt;p&gt;Cela m&amp;rsquo;a fait plaisir de découvrir &lt;a href=&#34;https://craftinginterpreters.com/compiling-expressions.html&#34; target=&#34;_blank&#34;&gt;la technique de Pratt pour construire un analyseur&#xA;syntaxique descendant reposant sur la précédence des&#xA;opérateurs&lt;/a&gt;&#xA;et de constater qu&amp;rsquo;il est vraiment possible de générer du bytecode sans d&amp;rsquo;abord&#xA;construire un AST. Mais il aurait peut-être été plus&#xA;utile de construire un AST et d&amp;rsquo;apprendre quelque chose sur la conception d&amp;rsquo;une&#xA;deuxième phase pour optimiser le bytecode.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;la-performance&#34;&gt;&#xA;  La performance&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#la-performance&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;optimisation principale que j&amp;rsquo;ai faite au départ a été de faire en sorte que&#xA;l&amp;rsquo;analyseur lexical mette tous les identifiants dans un pool de chaînes de&#xA;caractères (en utilisant&#xA;&lt;a href=&#34;https://docs.rs/string-interner/latest/string_interner/&#34; target=&#34;_blank&#34;&gt;string_interner&lt;/a&gt;),&#xA;pour que ni le compilateur ni la machine virtuelle aient à comparer des chaînes&#xA;représentant des identifiants.&lt;/p&gt;&#xA;&lt;p&gt;Après avoir fini &lt;a href=&#34;https://craftinginterpreters.com/calls-and-functions.html&#34; target=&#34;_blank&#34;&gt;le chapitre&#xA;24&lt;/a&gt;, j&amp;rsquo;ai passé un&#xA;peu de temps à me pencher sur la performance, en suivant les conseils du &lt;a href=&#34;https://nnethercote.github.io/perf-book&#34; target=&#34;_blank&#34;&gt;Rust&#xA;Performance Book&lt;/a&gt;. J&amp;rsquo;ai fait des tests&#xA;de performance avec &lt;a href=&#34;https://docs.rs/criterion/latest/criterion/&#34; target=&#34;_blank&#34;&gt;criterion&lt;/a&gt; et&#xA;du profilage avec &lt;a href=&#34;https://perfwiki.github.io/main/&#34; target=&#34;_blank&#34;&gt;perf&lt;/a&gt; et&#xA;&lt;a href=&#34;https://github.com/KDAB/hotspot&#34; target=&#34;_blank&#34;&gt;hotspot&lt;/a&gt;, j&amp;rsquo;ai ajusté &lt;a href=&#34;https://nnethercote.github.io/perf-book/build-configuration.html#maximizing-runtime-speed&#34; target=&#34;_blank&#34;&gt;la configuration du&#xA;compilateur&#xA;Rust&lt;/a&gt;&#xA;and j&amp;rsquo;ai marqué quelques fonctions&#xA;&lt;a href=&#34;https://nnethercote.github.io/perf-book/inlining.html&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;inline&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Ensuite j&amp;rsquo;ai regardé &lt;a href=&#34;https://github.com/munificent/craftinginterpreters/wiki/Lox-implementations#rust&#34; target=&#34;_blank&#34;&gt;quelques autres versions de Lox en&#xA;Rust&lt;/a&gt;&#xA;et j&amp;rsquo;ai remarqué que tout le monde semble avoir eu du mal à obtenir des&#xA;performances proches de celles du &lt;code&gt;clox&lt;/code&gt; de&#xA;Nystrom et que les versions qui y arrivent comportent beaucoup de code&#xA;non sécurisé, ce que je voulais éviter.&lt;/p&gt;&#xA;&lt;p&gt;Je recommande vivement &lt;a href=&#34;https://ceronman.com/blog/my-experience-crafting-an-interpreter-with-rust/&#34; target=&#34;_blank&#34;&gt;billet de&#xA;blog&lt;/a&gt;&#xA;de Manuel Cerón sur sa tentative impressionnante, déterminée et partiellement&#xA;réussie d&amp;rsquo;égaler la vitesse de &lt;code&gt;clox&lt;/code&gt; en Rust en écrivant de plus en plus de&#xA;code non sécurisé.&lt;/p&gt;&#xA;&lt;p&gt;À titre de comparaison, voici les résultats de l&amp;rsquo;exécution de quelques-uns des&#xA;&lt;a href=&#34;https://github.com/munificent/craftinginterpreters/tree/master/test/benchmark&#34; target=&#34;_blank&#34;&gt;tests de performance de Nystrom&lt;/a&gt;&#xA;sur les versions suivantes :&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Le &lt;code&gt;clox&lt;/code&gt; de Nystrom&lt;/li&gt;&#xA;&lt;li&gt;La version sécurisée du &lt;code&gt;loxido&lt;/code&gt; de Cerón&lt;/li&gt;&#xA;&lt;li&gt;La version non sécurisée de &lt;code&gt;loxido&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;OrganicLox avec &lt;code&gt;Rc&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;OrganicLox avec le ramasse-miettes &lt;code&gt;dumpster&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;figure&gt;&lt;img src=&#34;https://benjamingeer.eu/fr/post/organiclox/lox-benchmarks-fr.svg&#34;&#xA;&#x9;&#x9;&#x9;alt=&#34;un diagramme à barres de résultats de tests de performance&#34; width=&#34;100%&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;OrganicLox avec &lt;code&gt;Rc&lt;/code&gt; est donc deux à quatre fois plus lent que &lt;code&gt;clox&lt;/code&gt;, ce qui&#xA;est peut-être typique des interpréteurs réalisés en Rust &lt;a href=&#34;https://github.com/raviqqe/stak/blob/939f7bae9f188027d2f9e2cdc62c3baa76be36ed/README.md?plain=1#L174&#34; target=&#34;_blank&#34;&gt;par rapport à ceux&#xA;réalisés en&#xA;C&lt;/a&gt;.&#xA;La version avec &lt;code&gt;dumpster&lt;/code&gt; est beaucoup plus lente. Il semble clair qu&amp;rsquo;un&#xA;ramasse-miettes rapide est essentiel pour une machine virtuelle très&#xA;performante.&lt;/p&gt;&#xA;&lt;p&gt;Quelle est l&amp;rsquo;importance de ces différences ? Les tests de performance sont&#xA;conçus pour simuler des scénarios extrêmes, par exemple en utilisant de longues&#xA;boucles ou la récursivité profonde, ou en créant une charge de travail&#xA;importante pour le ramasse-miettes. Ils ne sont donc pas forcément&#xA;représentatifs des cas d&amp;rsquo;utilisation réels. Il arrive souvent que les scripts&#xA;exécutés par une application dans un interpréteur embarqué sont courts et font&#xA;très peu de travail. On pourrait se faire une idée plus réaliste de la&#xA;performance d&amp;rsquo;une machine virtuelle dans un tel scénario en exécutant la suite&#xA;de tests d&amp;rsquo;intégration de Nystrom, qui exécute 246 scripts courts en Lox et&#xA;vérifie leurs sorties. Voici une comparaison :&lt;/p&gt;&#xA;&lt;figure&gt;&lt;img src=&#34;https://benjamingeer.eu/fr/post/organiclox/lox-tests-fr.svg&#34;&#xA;&#x9;&#x9;&#x9;alt=&#34;a bar chart of test suite running times&#34; width=&#34;100%&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Dans une application où chaque cycle CPU compte, les écarts entre les&#xA;performances de ces différentes implémentations pourraient avoir beaucoup&#xA;d&amp;rsquo;importance. Mais dans d&amp;rsquo;autres cas d&amp;rsquo;utilisation, ils pourraient être&#xA;insignifiants.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;dautres-approches-possibles&#34;&gt;&#xA;  D&amp;rsquo;autres approches possibles&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#dautres-approches-possibles&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Il est tentant d&amp;rsquo;essayer d&amp;rsquo;ajouter un compilateur à la volée (JIT) pour&#xA;améliorer la performance de l&amp;rsquo;interpréteur, soit en en écrivant un à partir de&#xA;zéro, soit en en utilisant un &lt;em&gt;backend&lt;/em&gt; existant comme &lt;a href=&#34;https://llvm.org/&#34; target=&#34;_blank&#34;&gt;LLVM&lt;/a&gt;&#xA;ou &lt;a href=&#34;https://cranelift.dev/&#34; target=&#34;_blank&#34;&gt;Cranelift&lt;/a&gt;.&#xA;&lt;a href=&#34;https://blog.nlnetlabs.nl/introducing-roto-a-compiled-scripting-language-for-rust&#34; target=&#34;_blank&#34;&gt;Roto&lt;/a&gt;&#xA;et&#xA;&lt;a href=&#34;https://blog.nlnetlabs.nl/introducing-roto-a-compiled-scripting-language-for-rust/&#34; target=&#34;_blank&#34;&gt;Dora&lt;/a&gt;&#xA;sont des exemples en Rust de cette approche. Mais même si on adopte cette&#xA;démarche, il n&amp;rsquo;est pas facile d&amp;rsquo;atteindre un haut niveau de performance. Dans&#xA;&lt;a href=&#34;https://blog.miguelgrinberg.com/post/python-3-14-is-here-how-fast-is-it&#34; target=&#34;_blank&#34;&gt;ces tests de&#xA;performance&lt;/a&gt;,&#xA;le nouveau JIT de Python n&amp;rsquo;a aucun effet mesurable sur les performances (voir&#xA;aussi &lt;a href=&#34;https://dinfuehr.com/blog/dora-implementing-a-jit-compiler-with-rust/#benchmarks&#34; target=&#34;_blank&#34;&gt;ces résultats de tests de la performance de&#xA;Dora&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;p&gt;Voilà une raison d&amp;rsquo;envisager d&amp;rsquo;utiliser un interpréteur existant qui a déjà&#xA;bénéficié d&amp;rsquo;années de développement, plutôt que d&amp;rsquo;en créer un nouveau. Le&#xA;langage &lt;a href=&#34;https://www.lua.org/&#34; target=&#34;_blank&#34;&gt;Lua&lt;/a&gt; est une option largement utilisée, mais il&#xA;n&amp;rsquo;est pas assez rapide pour certaines applications. La machine virtuelle&#xA;&lt;a href=&#34;https://luajit.org/&#34; target=&#34;_blank&#34;&gt;LuaJIT&lt;/a&gt; est un ordre de grandeur plus rapide que la&#xA;machine virtuelle Lua standard pour certains cas d&amp;rsquo;utilisation, mais c&amp;rsquo;est un&#xA;&lt;a href=&#34;https://www.polarsignals.com/blog/posts/2024/11/13/lua-unwinding&#34; target=&#34;_blank&#34;&gt;compilateur à la volée basé sur les arbres de&#xA;traces&lt;/a&gt;, ce&#xA;qui a des avantages et des inconvénients. Les développeurs de Lua ont publié un&#xA;&lt;a href=&#34;https://www.inf.puc-rio.br/~roberto/docs/pallene-sblp.pdf&#34; target=&#34;_blank&#34;&gt;article intéressant&lt;/a&gt;&#xA;qui traite des limites de cette approche et propose une autre solution (un&#xA;langage supplémentaire à typage statique, un peu comme&#xA;&lt;a href=&#34;https://cython.org/&#34; target=&#34;_blank&#34;&gt;Cython&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;p&gt;Pour certains cas d&amp;rsquo;utilisation, si des scripts embarqués ne font pas beaucoup&#xA;de travail, leurs performances pourraient ne pas être critiques. S&amp;rsquo;ils font&#xA;tellement de travail que leurs performances sont insuffisantes, une autre option&#xA;consiste à ne pas intégrer d&amp;rsquo;interpréteur du tout. Cloudflare, qui avait investi&#xA;massivement pendant plus de 20 ans dans des scripts en utilisant LuaJIT embarqué&#xA;dans &lt;a href=&#34;https://openresty.org/en/&#34; target=&#34;_blank&#34;&gt;OpenResty&lt;/a&gt;, &lt;a href=&#34;https://blog.cloudflare.com/20-percent-internet-upgrade/&#34; target=&#34;_blank&#34;&gt;les a récemment remplacés par du&#xA;code Rust&lt;/a&gt;.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Calculer des mesures de centralité avec le réseau de transport en commun parisien</title>
      <link>https://benjamingeer.eu/fr/post/paris-rail-centrality/</link>
      <pubDate>Fri, 29 Aug 2025 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.eu/fr/post/paris-rail-centrality/</guid>
      <description>&lt;p&gt;J&amp;rsquo;ai pensé qu&amp;rsquo;il serait intéressant d&amp;rsquo;essayer un peu d&amp;rsquo;&lt;a href=&#34;https://fr.wikipedia.org/wiki/Th%C3%A9orie_des_r%C3%A9seaux&#34; target=&#34;_blank&#34;&gt;analyse de réseau &lt;/a&gt; élémentaire en utilisant &lt;a href=&#34;https://www.ratp.fr/plans&#34; target=&#34;_blank&#34;&gt;le réseau du métro et du RER parisiens&lt;/a&gt;, en commençant par des indices de &lt;a href=&#34;https://fr.wikipedia.org/wiki/Centralit%C3%A9&#34; target=&#34;_blank&#34;&gt;centralité&lt;/a&gt;. Il s&amp;rsquo;agit de mesures qui classent les sommets d&amp;rsquo;un graphe en fonction de leur importance, selon une définition quelconque de l&amp;rsquo;importance. Par exemple, dans un réseau de transport, la centralité d&amp;rsquo;une station pourrait donner une indication de la probabilité que les passagers passent par cette station au cours de leur itinéraire. Un opérateur de transports en commun pourrait utiliser ces informations pour évaluer les inconvénients que causerait la fermeture de certaines stations, par exemple en raison d&amp;rsquo;inondations ou de travaux, et pour l&amp;rsquo;aider à identifier les moyens les plus efficaces d&amp;rsquo;améliorer la résilience du réseau. J&amp;rsquo;utiliserai ici &lt;a href=&#34;https://www.python.org&#34; target=&#34;_blank&#34;&gt;Python&lt;/a&gt;, &lt;a href=&#34;https://networkx.org&#34; target=&#34;_blank&#34;&gt;networkx&lt;/a&gt; et &lt;a href=&#34;https://sqlite.org&#34; target=&#34;_blank&#34;&gt;SQLite&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;construire-le-graphe&#34;&gt;&#xA;  Construire le graphe&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#construire-le-graphe&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;J&amp;rsquo;ai choisi ici de faire un seul graphe qui comprend le métro et le RER. Le premier problème est de construire ce graphe en établissant la liste de liens et la liste de sommets. Les établissements qui régissent les transports en commun parisiens ne fournissent pas de tel jeu de données, mais ils fournissent un &lt;a href=&#34;https://www.data.gouv.fr/datasets/horaires-prevus-sur-les-lignes-de-transport-en-commun-dile-de-france-gtfs-datahub/&#34; target=&#34;_blank&#34;&gt;jeu de données GTFS&lt;/a&gt; qui représente les horaires prévus sur toutes les lignes de transport pendant les 30 prochains jours. (Je tiens à remercier &lt;a href=&#34;https://masto.ai/@bovine3dom&#34; target=&#34;_blank&#34;&gt;Oliver Blanthorn&lt;/a&gt; de me l&amp;rsquo;avoir signalé.) Les données GTFS représentent les courses (les séquences d&amp;rsquo;arrêts) que les trains devraient parcourir sur les lignes de métro ou de RER. Pour construire la liste de liens du réseau, nous pouvons parcourir chaque course, en enregistrant un lien entre chaque arrêt et l&amp;rsquo;arrêt suivant. Certaines courses vont dans une direction, d&amp;rsquo;autres dans la direction inverse, et beaucoup ne comprennent pas tous les arrêts de la ligne, mais en les parcourant toutes, nous devrions accumuler un graphe orienté complet du réseau. Il faudra parcourir environ 64 000 courses, qui comprennent au total presque 1,5 million d&amp;rsquo;arrêts, et une grande partie des données sera redonante pour nous, mais cela n&amp;rsquo;a pas d&amp;rsquo;importance tant que le traitement des données ne prend pas trop de temps.&lt;/p&gt;&#xA;&lt;p&gt;Il s&amp;rsquo;agit donc de réaliser un procédé &lt;a href=&#34;https://fr.wikipedia.org/wiki/Extract-transform-load&#34; target=&#34;_blank&#34;&gt;ETL (Extract, transform, load)&lt;/a&gt;. D&amp;rsquo;abord j&amp;rsquo;ai créé &lt;a href=&#34;https://framagit.org/benjamingeer/benjamingeer/-/tree/main/notebook-data/paris-rail-data/download-data.sh&#34; target=&#34;_blank&#34;&gt;un script shell&lt;/a&gt; qui télécharge les données GTFS, ainsi que plusieurs fichiers d&amp;rsquo;un jeu de données qui s&amp;rsquo;appelle &lt;a href=&#34;https://data.iledefrance-mobilites.fr/explore/dataset/referentiel-des-lignes/information/?disjunctive.transportsubmode&amp;amp;disjunctive.operatorname&amp;amp;disjunctive.networkname&amp;amp;disjunctive.transportmode&#34; target=&#34;_blank&#34;&gt;Référentiel des lignes de transport en commun d’île-de-France&lt;/a&gt;, dont nous aurons également besoin. Comme tous ces fichiers sont au format CSV et utilisent des identifiants uniques pour relier les données des différents fichiers, notre tâche sera plus facile si nous utilisons une base de données relationnelle. Dans un &lt;a href=&#34;https://framagit.org/benjamingeer/benjamingeer/-/tree/main/notebook-data/paris-rail-data/import-data.sh&#34; target=&#34;_blank&#34;&gt;deuxième script shell&lt;/a&gt;, j&amp;rsquo;importe les fichiers pertinents dans une base de données intermédiaire gérée par SQLite et je crée quelques index pour accélérer les requêtes de l&amp;rsquo;étape de transformation. Ce script s&amp;rsquo;exécute en 21 secondes environ sur mon ordinateur portable et la taille de la base de données obtenue est de 2,1 Go.&lt;/p&gt;&#xA;&lt;p&gt;Enfin, j&amp;rsquo;ai créé &lt;a href=&#34;https://framagit.org/benjamingeer/benjamingeer/-/tree/main/notebook-data/paris-rail-data/build-graph.py&#34; target=&#34;_blank&#34;&gt;un script Python&lt;/a&gt; pour les étapes de transformation et de chargement. Il lit la base de données intermédiaire et construit la base de données de sortie, qui ne contient que la table de liens et la table de sommets. Comme la base de données de sortie est petite (132 Ko), le script la crée en mémore pour améliorer la performance de cette étape, puis la sauvegarde quand elle est complète. L&amp;rsquo;exécution de ce script prend environ 8 secondes.&lt;/p&gt;&#xA;&lt;p&gt;Dans le Référentiel, les liens entre le métro et le RER sont représentés par des zones de correspondance et des pôles d&amp;rsquo;échange, qui peuvent comprendre plusieurs stations reliées par des couloirs. Pour inclure ces relations dans le graphe, j&amp;rsquo;ai choisi d&amp;rsquo;ajouter des liens entre toutes les stations faisant partie du même groupe.&lt;/p&gt;&#xA;&lt;p&gt;La base de données de sortie représente un multigraphe orienté, puisque deux stations peuvent être reliées par plusieurs lignes. Dans un tel cas, nous pouvons considérer que les deux stations en question ont un lien plus fort que deux stations qui ne sont reliées que par une seule ligne. Toutes choses étant égales par ailleurs, plus il y a de lignes entre deux stations, plus il y aura de passagers qui voyagent entre les deux. Nous conserverons ces informations sur les liens multiples en faisant nos calculs.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;visualiser-des-parties-du-graphe&#34;&gt;&#xA;  Visualiser des parties du graphe&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#visualiser-des-parties-du-graphe&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Visualisons d&amp;rsquo;abord une partie des données pour vérifier qu&amp;rsquo;elles sont correctes. Nous pouvons créer une fonction qui affiche le graphe d&amp;rsquo;un réseau de transport. Ici, nous nous intéressons uniquement aux sommets et aux liens, et non pas à leur position géographique. Pour repérer facilement les lignes, nous pouvons utiliser les couleurs précisées pour le &lt;a href=&#34;https://www.ratp.fr/plans&#34; target=&#34;_blank&#34;&gt;plan du réseau&lt;/a&gt;, qui se trouvent dans le jeu de données GTFS, ainsi que le noir pour les liens que j&amp;rsquo;ai ajoutés pour les zones de correspondance et les pôles d&amp;rsquo;échange.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;InlineBackend&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;figure_formats&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;svg&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sqlite3&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pandas&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pd&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;networkx&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;nx&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;numpy&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;np&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;plt&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;itertools&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;it&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;draw_graph&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;label_x_offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;plt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;figure&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;figsize&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;plt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;margins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.18&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;plt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx_agraph&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;graphviz_layout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prog&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;dot&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# See https://networkx.org/documentation/stable/auto_examples/drawing/plot_multigraphs.html&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;connectionstyle&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;arc3,rad=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;accumulate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;draw_networkx_nodes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;#000000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;edge_colors&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;#&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;source_node_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_node_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edge_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;route_color&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;source_node_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target_node_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;edge_key&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edges&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;draw_networkx_edges&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;edge_color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edge_colors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;connectionstyle&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;connectionstyle&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;label_pos&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;node_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node_pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;label_x_offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_pos&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;text&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;draw_networkx_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;label_pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_node_attributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;node_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;horizontalalignment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;left&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;verticalalignment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bottom&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;font_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_rotation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Essayons avec les lignes de métro 1 et 4 et le RER A:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;DATABASE&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;../../../notebook-data/paris-rail-data/paris-graph.db&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sqlite3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;connect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;file:&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DATABASE&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;?mode=ro&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;nodes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_sql_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;select distinct&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        nodes.node_id, nodes.node_name&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    from nodes&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    inner join edges on&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        nodes.node_id = edges.source_node_id or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        nodes.node_id = edges.target_node_id&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    where&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type = 1 and edges.route_name = &amp;#39;1&amp;#39;) or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type = 1 and edges.route_name = &amp;#39;4&amp;#39;) or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type = 2 and edges.route_name = &amp;#39;A&amp;#39;) or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type is null and&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;            (edges.route_name = &amp;#39;PdE Châtelet - Les Halles&amp;#39; or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;            edges.route_name = &amp;#39;ZdC Gare de Lyon&amp;#39;))&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;index_col&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;node_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;edges&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_sql_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;select * from edges where&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type = 1 and edges.route_name = &amp;#39;1&amp;#39;) or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type = 1 and edges.route_name = &amp;#39;4&amp;#39;) or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type = 2 and edges.route_name = &amp;#39;A&amp;#39;) or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type is null and&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;            (edges.route_name = &amp;#39;PdE Châtelet - Les Halles&amp;#39; or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;            edges.route_name = &amp;#39;ZdC Gare de Lyon&amp;#39;))&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;from_pandas_edgelist&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;edges&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;source_node_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;target_node_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;edge_attr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;create_using&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MultiDiGraph&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;node_attributes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nodes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;orient&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;index&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_node_attributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_attributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;draw_graph&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Les lignes de métro 1 et 4 et le RER A&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;label_x_offset&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;https://benjamingeer.eu/fr/post/paris-rail-centrality/index_files/index_4_0.svg&#34; alt=&#34;svg&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Cela semble correct.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;visualiser-les-résultats&#34;&gt;&#xA;  Visualiser les résultats&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#visualiser-les-r%c3%a9sultats&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Les fonctions proposées par &lt;code&gt;networkx&lt;/code&gt; pour le calcul des mesures de centralité renvoient un dictionnaire dont les clés sont des identifiants de sommet et dont les valeurs sont des scores de centralité. Nous pouvons créer une fonction qui accepte un tel dictionnaire et affiche un diagramme à barres des 25 stations les plus importantes par ordre décroissant de centralité.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;centrality_chart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centrality_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;names_and_scores&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node_attributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]][&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;node_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;centrality_dict&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;top_25&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;names_and_scores&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reverse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;25&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;top_25_df&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DataFrame&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;top_25&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;columns&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Station&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Score de centralité&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Station&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;ax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;top_25_df&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;plot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;barh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;ax&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;invert_yaxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 class=&#34;heading&#34; id=&#34;la-centralité-de-degré&#34;&gt;&#xA;  La centralité de degré&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#la-centralit%c3%a9-de-degr%c3%a9&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Lisons d&amp;rsquo;abord l&amp;rsquo;intégralité du graphe :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;nodes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_sql_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;select * from nodes&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;index_col&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;node_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;edges&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_sql_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;select * from edges&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;from_pandas_edgelist&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;edges&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;source_node_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;target_node_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;edge_attr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;create_using&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MultiDiGraph&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;node_attributes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nodes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;orient&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;index&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_node_attributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_attributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nodes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; sommets et &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edges&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; liens chargés.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;563 sommets et 1363 liens chargés.&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;La mesure de centralité la plus simple est la centralité de degré : pour chaque sommet, nous pouvons compter ses liens entrants ou sortants et normaliser le résultat en le divisant par $n - 1$, où $n$ est le nombre de sommets. Dans ce cas présent, les resultats sont les mêmes pour la centralité de degré entrant et la centralité de degré sortant.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;in_degree_centrality_dict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;in_degree_centrality&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;centrality_chart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;in_degree_centrality_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Centralité de degré entrant&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;https://benjamingeer.eu/fr/post/paris-rail-centrality/index_files/index_11_0.svg&#34; alt=&#34;svg&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;On voit tout de suite que les stations ayant les scores le plus élevés sont surtout des stations de métro plutôt que des stations RER. Une explication possible serait la structure apparemment plus radiale du réseau RER par rapport au métro. En plus d&amp;rsquo;être situées sur plusieurs lignes, plusieurs de ces stations (telles que Havre-Caumartin) font partie d&amp;rsquo;un pôle d&amp;rsquo;échange.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;la-centralité-de-vecteur-propre&#34;&gt;&#xA;  La centralité de vecteur propre&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#la-centralit%c3%a9-de-vecteur-propre&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Avec la &lt;a href=&#34;https://fr.wikipedia.org/wiki/Centralit%C3%A9#Centralit%C3%A9_de_vecteur_propre&#34; target=&#34;_blank&#34;&gt;centralité de vecteur propre&lt;/a&gt;, chaque sommet reçoit un score proportionnel à la somme des scores de ses voisins. Un sommet peut ainsi obtenir un score élevé en ayant beaucoup de voisins et/ou en ayant des voisins dont le score est élevé. Dans un graphe non orienté à $n$ sommets, la centralité de vecteur propre $x_i$ d&amp;rsquo;un sommet $i$, dont l&amp;rsquo;ensemble des voisins est $M(i)$, est définie par :&lt;/p&gt;&#xA;$$&#xA;x_i = \frac{1}{\lambda} \sum_{j \in M(i)} x_j&#xA;$$&lt;p&gt;où $\lambda$ est une constante. Nous pouvons écrire cette équation en utilisant la matrice d&amp;rsquo;adjacence $A$ du réseau, dans laquelle $a_{ij}$ est égal à 1 s&amp;rsquo;il y a un lien entre les sommets $i$ et $j$ et à 0 s&amp;rsquo;il n&amp;rsquo;y en a pas :&lt;/p&gt;&#xA;$$&#xA;x_i = \frac{1}{\lambda} \sum_{j = 1}^n a_{ij} x_j&#xA;$$&lt;p&gt;Cela équivaut à :&lt;/p&gt;&#xA;$$&#xA;\mathbf{x} = \frac{1}{\lambda} A\mathbf{x}&#xA;$$&lt;p&gt;où $\mathbf{x}$ est un vecteur dont les éléments sont les scores de centralité. On peut donc écrire :&lt;/p&gt;&#xA;$$&#xA;A\mathbf{x} = \lambda\mathbf{x}&#xA;$$&lt;p&gt;Il s&amp;rsquo;ensuit que $\lambda$ est une valeur propre de $A$ et que $\mathbf{x}$ est le vecteur propre correspondant. Étant donné les valeurs propres et les vecteurs propres de la matrice, il est simple de choisir le vecteur propre pertinent, car (selon le &lt;a href=&#34;https://fr.wikipedia.org/wiki/Th%C3%A9or%C3%A8me_de_Perron-Frobenius&#34; target=&#34;_blank&#34;&gt;théorème de Perron-Frobenius&lt;/a&gt;), pour une matrice (comme la matrice d&amp;rsquo;adjacence) qui n&amp;rsquo;a pas d&amp;rsquo;éléments négatifs, seul le vecteur propre associé à la plus grande valeur propre peut être choisi de façon à ce qu&amp;rsquo;il n&amp;rsquo;ait pas d&amp;rsquo;éléments négatifs. Avec un graphe orienté comme notre réseau de transport, on peut choisir un vecteur propre à gauche ou un vecteur propre à droite. On préfère d&amp;rsquo;habitude le vecteur propre à gauche (et c&amp;rsquo;est ce que fait &lt;code&gt;networkx&lt;/code&gt;), de sorte que le score d&amp;rsquo;un sommet dépend de ses liens entrants plutôt que de ses liens sortants. Cela ne change pas grand-chose dans le cas présent, car presque tous les liens entrants de notre réseau ont un lien sortant correspondant.&lt;/p&gt;&#xA;&lt;p&gt;Lorsque la centralité de vecteur propre est utilisée avec un graphe orienté, celui-ci doit être fortement connexe. C&amp;rsquo;est le cas de notre réseau de transport, car chaque station est accessible depuis toutes les autres :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_strongly_connected&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;True&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Nous utiliserons ici la fonction &lt;code&gt;networkx.eigenvector_centrality_numpy&lt;/code&gt;, qui construit d&amp;rsquo;abord la matrice d&amp;rsquo;adjacence. Dans un multigraphe orienté comme le nôtre, s&amp;rsquo;il y a $n$ liens allant dans le même sens entre deux sommets, &lt;code&gt;networkx&lt;/code&gt; les représente par la valeur $n$ dans la matrice, ce qui équivaut à un seul lien d&amp;rsquo;intensité $n$. Ensuite il obtient le vecteur propre pertinent et renvoie un dictionnaire qui contient chaque identifiant de sommet et l&amp;rsquo;élément correspondant du vecteur propre.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;eigenvector_centrality_dict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eigenvector_centrality_numpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;centrality_chart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eigenvector_centrality_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Centralité de vecteur propre&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;https://benjamingeer.eu/fr/post/paris-rail-centrality/index_files/index_16_0.svg&#34; alt=&#34;svg&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Si on compare ces résultats à ceux obtenus pour la centralité de degré, on peut constater que la station Havre-Caumartin, qui se trouve au milieu du pôle d&amp;rsquo;échange Paris Saint-Lazare - Opéra (qui comprend six stations), obtient un score plus élevé parce qu&amp;rsquo;elle est adjacente à deux stations, Saint-Lazare et Opéra, qui ont des scores élevés. Plusieurs autres stations, dont Saint-Augustin, Auber et and Haussmann Saint-Lazare, obtiennent des scores plus élevés pour la même raison.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;la-centralité-dintermédiarité&#34;&gt;&#xA;  La centralité d’intermédiarité&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#la-centralit%c3%a9-dinterm%c3%a9diarit%c3%a9&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;La &lt;a href=&#34;https://fr.wikipedia.org/wiki/Centralit%C3%A9#Centralit%C3%A9_d%27interm%C3%A9diarit%C3%A9&#34; target=&#34;_blank&#34;&gt;centralité d’intermédiarité&lt;/a&gt; compte le nombre de fois où un sommet se trouve sur un des plus courts chemins (c&amp;rsquo;est-à-dire qui traversent le moins de sommets possible) entre chaque paire d&amp;rsquo;autres sommets. Pour un sommet $v$, elle est définie par :&lt;/p&gt;&#xA;$$&#xA;c_B(v) =\sum_{s \neq v \neq t} \frac{\sigma(s, t|v)}{\sigma(s, t)}&#xA;$$&lt;p&gt;où $s$ et $t$ sont n&amp;rsquo;importe quels autres sommets du réseau, $\sigma(s, t)$ est le nombre de plus courts chemins de $s$ à $t$ et $\sigma(s, t|v)$ est le nombre de ces chemins qui passent par $v$. Dans un réseau de transport, un station dont $c_B(v)$ a une valeur élevée est une station par laquelle beaucoup de passagers passeront probablement s&amp;rsquo;ils choissisent un des plus courts chemins menant à leur destination.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;betweenness_centrality_dict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;betweenness_centrality&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;centrality_chart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;betweenness_centrality_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Centralité d’intermédiarité&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;https://benjamingeer.eu/fr/post/paris-rail-centrality/index_files/index_19_0.svg&#34; alt=&#34;svg&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;La plupart des stations figurant sur cette liste sont des stations RER plutôt que des stations de métro, ce qui est logique, car le RER couvre une plus grande distance entre les arrêts. Ainsi, si le même trajet peut être effectué en métro ou en RER, le trajet le plus court sera généralement celui en RER. Il n&amp;rsquo;est pas surprenant de voir Châtelet les Halles en tête de liste, compte tenu de sa situation géographique centrale et du grand nombre de lignes qui passent par son pôle d&amp;rsquo;échange. Il semble qu&amp;rsquo;il y ait aussi d&amp;rsquo;autres configurations qui peuvent donner un score élevé à une station. Par exemple, Juvisy se trouve sur un long tronçon du RER C où il y a peu de correspondances, et elle est reliée à un tronçon semblable du RER D. Il semble donc probable que beaucoup de plus courts chemins doivent passer par cette station.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;conclusion&#34;&gt;&#xA;  Conclusion&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#conclusion&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Ceci n&amp;rsquo;est qu&amp;rsquo;une brève exploration de quelques mesures de centralité pour ce réseau, avec quelques exemples illustrant comment différentes définitions de l&amp;rsquo;importance d&amp;rsquo;un sommet peuvent donner lieu à des scores différents. Tous les scripts utilisés ici se trouvent &lt;a href=&#34;https://framagit.org/benjamingeer/benjamingeer/-/tree/main/notebook-data/paris-rail-data&#34; target=&#34;_blank&#34;&gt;dans le dépôt Git de ce blog&lt;/a&gt;, ainsi que le &lt;a href=&#34;https://framagit.org/benjamingeer/benjamingeer/-/tree/main/notebooks/en/paris-rail-centrality/index.ipynb&#34; target=&#34;_blank&#34;&gt;calepin Jupyter&lt;/a&gt; à partir duquel j&amp;rsquo;ai généré cette page. N&amp;rsquo;hésitez pas à &lt;a href=&#34;https://benjamingeer.eu/fr/about/&#34;&gt;me contacter&lt;/a&gt; pour toute question ou suggestion.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Mal partum</title>
      <link>https://benjamingeer.eu/fr/post/the-sound-of-crying/</link>
      <pubDate>Thu, 06 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.eu/fr/post/the-sound-of-crying/</guid>
      <description>&lt;p&gt;En 2024 j&amp;rsquo;ai fait les sous-titres anglais du court-métrage &lt;a href=&#34;https://pasfeerique.com/mal-partum&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;Mal partum&lt;/em&gt;&lt;/a&gt;, un beau documentaire sur la dépression post-partum. Émilie D. s&amp;rsquo;est appuyée sur son expérience personnelle pour réaliser un film qui apporte des connaissances pratiques dont nous pouvons tous nous servir.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>كوكبنا</title>
      <link>https://benjamingeer.eu/fr/post/kawkabna/</link>
      <pubDate>Fri, 20 Sep 2024 15:00:00 +0000</pubDate>
      <guid>https://benjamingeer.eu/fr/post/kawkabna/</guid>
      <description>&lt;p&gt;Un podcast en arabe que j&amp;rsquo;ai commencé en 2021, sur l&amp;rsquo;écologie, la migration et les inégalités, et que j&amp;rsquo;aimerais me remettre à publier un jour : &lt;a href=&#34;https://%d9%83%d9%88%d9%83%d8%a8%d9%86%d8%a7.%d8%b4%d8%a8%d9%83%d8%a9&#34; target=&#34;_blank&#34;&gt;كوكبنا.شبكة&lt;/a&gt;.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Tondauer</title>
      <link>https://benjamingeer.eu/fr/post/tondauer/</link>
      <pubDate>Fri, 20 Sep 2024 14:00:00 +0000</pubDate>
      <guid>https://benjamingeer.eu/fr/post/tondauer/</guid>
      <description>&lt;p&gt;En 2020 j&amp;rsquo;ai commencé un projet qui s&amp;rsquo;appelle &lt;a href=&#34;https://tondauer.art/fr/&#34; target=&#34;_blank&#34;&gt;Tondauer&lt;/a&gt;, pour faire des éditions de partitions sous licence Creative Commons. C&amp;rsquo;est arrivé à cause du confinement lié au Covid-19 cette année-là. J&amp;rsquo;apprenais à jouer le&#xA;&lt;a href=&#34;https://tondauer.art/fr/2021/03/mendelssohn-prelude-mwv-u-123/&#34; target=&#34;_blank&#34;&gt;Prélude Op. 104a, n° 2 (MSV U 123)&lt;/a&gt; de Felix Mendelssohn, parce qu&amp;rsquo;il convenait bien à mon sentiment de frustration et à mon humeur agitée à l&amp;rsquo;époque.&lt;/p&gt;&#xA;&lt;p&gt;J&amp;rsquo;ai commencé par une édition du XIXe siècle qui pouvait être téléchargée gratuitement. Puis j&amp;rsquo;ai acheté une édition qui proposait des doigtés, et je me suis demandé pourquoi elle avait des notes différentes. J&amp;rsquo;ai cherché sans succès le manuscrit du compositeur, ne trouvant qu&amp;rsquo;un brouillon antérieur. Ayant lu la biographie de Mendelssohn écrite par R. Larry Todd, je lui ai envoyé un mail pour lui demander s&amp;rsquo;il savait où se trouvait le manuscrit de la version finale. Il m&amp;rsquo;a répondu que celui-ci n&amp;rsquo;avait pas été trouvé. Cela signifiait que les seules sources étaient les premières éditions, publiées après la mort du compositeur.&lt;/p&gt;&#xA;&lt;p&gt;En travaillant dans le domaine des humanités numériques, j’avais appris quelque chose sur la façon dont les éditions critiques sont réalisées. J&amp;rsquo;ai donc décidé de faire ma propre édition critique. Pendant plusieurs mois, au fur et à mesure de la réouverture des bibliothèques et des archives, j&amp;rsquo;ai reçu des reproductions numériques des deux premières éditions, une allemande et une britannique. Les deux éditeurs avaient travaillés ensemble pour les publier simultanément, mais elles ne contenaient pas non plus les mêmes notes. Dans mon édition, j&amp;rsquo;ai essayé d&amp;rsquo;expliquer de façon plausible ce qui s&amp;rsquo;était passé et de reconstituer au mieux les intentions du compositeur. Finalement j&amp;rsquo;ai essayé de faire l&amp;rsquo;édition que j&amp;rsquo;aurais voulu avoir, en ajoutant des doigtés grâce à l&amp;rsquo;aide de &lt;a href=&#34;https://www.roskellacademy.com/&#34; target=&#34;_blank&#34;&gt;Penelope Roskell&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Plus récemment, j&amp;rsquo;ai travaillé avec la musicologue Florence Launay sur des éditions d&amp;rsquo;œuvres oubliées de compositrices, en commençant par les &lt;a href=&#34;https://tondauer.art/2022/10/polignac-preludes/&#34; target=&#34;_blank&#34;&gt;Preludes for Piano&lt;/a&gt; d&amp;rsquo;Armande de Polignac. Ces pièces subsistaient uniquement dans un seul exemplaire de la première édition, conservé par les descendants de la compositrice. Florence l&amp;rsquo;avait photocopié et des pianistes avaient enregistré ces pièces en utilisant des photocopies de cette photocopie. Maintenant que nous avons publié une édition corrigée avec la préface de Florence, j&amp;rsquo;espère que d&amp;rsquo;autres pianistes prendront plaisir à jouer ces Préludes.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Ressources sociologiques</title>
      <link>https://benjamingeer.eu/fr/post/socioresources/</link>
      <pubDate>Fri, 20 Sep 2024 13:00:00 +0000</pubDate>
      <guid>https://benjamingeer.eu/fr/post/socioresources/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://socioresources.net/fr/&#34; target=&#34;_blank&#34;&gt;Mon ancien blog&lt;/a&gt; (2013-2021) sur la sociologie de l&amp;rsquo;autonomie et l&amp;rsquo;autonomie de la sociologie.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>أبحاث لفتت نظري</title>
      <link>https://benjamingeer.eu/fr/post/abhath/</link>
      <pubDate>Fri, 20 Sep 2024 12:00:00 +0000</pubDate>
      <guid>https://benjamingeer.eu/fr/post/abhath/</guid>
      <description>&lt;p&gt;Mon ancien blog en arabe (2009-2014), sur lequel je résumais des recherches que je trouvais intéressantes : &lt;a href=&#34;https://benjamingeer.blogspot.com/&#34; target=&#34;_blank&#34;&gt;أبحاث لفتت نظري&lt;/a&gt;.&lt;/p&gt;&#xA;</description>
    </item>
  </channel>
</rss>
