Voici qu'une partie de mes galères de train va bientôt s'évanouir : la très proche banlieue est enfin mieux desservie. Du moins le matin, et dans le sens qui m'arrange, c'est-à-dire celui des départs de la ville le matin, et celui des retours le soir — en réalité, j'utilise à présent fort peu le train à ces heures-là, puisque la plupart du temps je travaille chez moi. Il y a beaucoup à dire et à penser sur cela.

Il y a un grand mystère que j'espère un jour résoudre, c'est celui de la conception des horaires de trains. Je me demande parfois si cela n'est pas calculé à la main, ou alors (cela revient presque au même), par un algorithme très simple de placement, type glouton, qui ajoute les lignes au fur et à mesure. Ceci expliquerait cela. Le RER A, sous la responsabilité de la RATP, a des fréquences assez élevées en heure de pointe (de l'ordre de 2 minutes) parce que la division de la ligne sur ses extrémités lointaines est assez faible et que les rames ont toutes la même longueur. Sur le RER C, c'est en revanche le pire cas possible : les rames sont de longueurs différentes, il y a des trains de voyageurs sur les mêmes voies de temps à autre (avec des longueurs et vitesses différentes), et des trains de marchandises sur des voies parallèles, sachant qu'apparemment, pour faire simple et le plus sécurisé possible, il faut considérer les pires cas, c'est-à-dire raisonner comme si tous les trains avaient la longueur maximale, et en déduire ainsi les distances de sécurité — c'est-à-dire la vitesse et la fréquence.

Mais surtout, le RER C me fait penser aux programmes abominablement mal architecturés que je rencontre fréquemment chez mes clients/prospects non-informaticiens : ils sont issus de cette étrange pensée technicienne que l'on peut opérer convenablement des systèmes extrêmement complexes. Alors même que la complexité ne marche jamais, elle est source de problèmes permanents, car elle ne peut pas gérer convenablement l'imprévu (qui arrive en réalité tout le temps, mais dont on ne saurait prédire où ni comment ni quand). En réalité, il n'y a qu'une seule manière de se sortir de la complexité : il faut diviser ! Comme on divise le travail (cf le taylorisme), il faut savoir diviser le système complexe pour le rendre somme de systèmes (plus) simples. Le RER C fait 187km pour 140 millions de voyageurs, on y compte cinq points de divisions, c'est un vrai pasta monster. La ligne a plusieurs fois été remaniée, un ami m'a par exemple fourni des billets allant à Fontainebleau ; j'ai pour ma part connu les rames allant à Argenteuil, tronçon depuis rattaché plus intelligemment à St-Lazare ; j'espère qu'un jour les lignes pour Étampes ou Dourdan ne seront plus qu'un mauvais souvenir : voyez où cela se trouve sur une carte !

Forcément, quand on ajoute un arrêt sur la ligne, ajoutant de fait une ou deux minutes de plus sur le trajet total, les usagers de Dourdan protestent fortement. Mais ils se trouvent à 40 km du centre de Paris, le problème n'est pas tant d'ajouter un arrêt que d'être sur cette ligne ! Par exemple, on pourrait relier Dourdan à Rambouillet (assez proche, via les champs...), qui dispose d'un semi-direct passant par Versailles-Chantier et reliant Montparnasse : ce serait bien plus rapide, et beaucoup moins absurde que de prendre un train reliant Dourdan (au sud lointain) à Versailles (au sud-ouest aussi), en passant par Paris (au nord) via le Sud-Est... On peut aussi se demander s'il est légitime à la fois de vouloir habiter dans une campagne profonde, et d'être mécontent de ne pas avoir de solution miracle pour relier la civilisation : il y a comme un air d'individualisme hérité des périodes des années 70-80, où le pouvoir technocratique en place avait trouvé intelligent de vouloir désengorger Paris vers la lointaine banlieue, y compris en produisant des villes hors-sol (ma petite cousine, qui habite derrière Marne-la-Vallée dans une de ces villes nouvelles, a découvert Paris la semaine dernière, à 14 ans passés : quel intérêt dès lors d'habiter près de Paris, pour le climat ?). Cette idée profondément stupide est de celles qui plombent à présent le pays et avec lesquelles il faut se démerder en souriant (enfin, surtout si on n'est pas trop directement concerné et qu'on a la foi). Le RER B est le pire dans le genre (j'ai déjà raté un avion et failli un Eurostar à cause de cette saleté encombrée), suivi de près par le RER A...

Cependant, le problème habituel, quand on découpe, c'est l'interfaçage. Pour reprendre l'exemple du taylorisme, l'effet pervers a été la perte de sens par les travailleurs et donc la vision d'ensemble des processus, menant à des erreurs et à de la contre-productivité — surtout sur les métiers plus intellectuels que le serrage de boulon, mais même pour eux, il a fallu que Toyota repense tout pour en arriver au lean management. Pour nos trains, cela signifie des changements, c'est-à-dire qu'il faudrait des trains qui soient stockés sur des voies, faisant des allers-retours simples (au lieu de parcourir une centaine de kilomètres avec des engorgements aux points de jonction et sur la double voie unique du centre de Paris, surtout le long de la Seine), et des voyageurs qui changent de trains quand ils veulent continuer leur voyage plus loin — comme c'est déjà le cas avec les métros à l'intérieur de Paris, ou même avec le RER C lui-même lorsque d'Ivry je veux relier Versailles (autochangement à l'intérieur de Paris, avec des temps d'attente totalement imprévisibles). Cela signifie aussi qu'il faut synchroniser les trains sur plusieurs points de ralliement, et que ces temps d'attente, perdus en apparence, compensent la complexité actuelle (qui échoue lamentablement, pour rappel).

Le problème est donc extrêmement complexe à résoudre, avec plusieurs hypothèses possibles, suivant des capacités physiques des gares et des lignes à définir et modéliser. Je ne vois qu'un seul moyen de régler cela : utiliser de la simulation numérique et des résolutions par métaheuristique. Je doute qu'actuellement la SNCF ait expérimenté de telles méthodes. Et l'organisation interne de l'entreprise est tellement complexe que je me demande même à qui l'on pourrait proposer un tel projet (qui nécessite des compétences extrêmement fortes, mais on est parfois surpris de trouver des gens fort compétents et sous-employés dans ce genre d'organisations tentaculaires où personne n'a de visibilité — mon paternel est de la maison, vous pensez bien que j'ai déjà abordé le sujet). Dans un algorithme de ce type, il faut trouver une base de jugement (ou notation) à maximiser. C'est-à-dire qu'il faut pouvoir exprimer par une formule de calcul, entre deux hypothèses, laquelle est la meilleure. Il faut pour cela découper le problème (encore ! Diviser, c'est régner), et attribuer des poids à chaque sous-problématique résolue plus ou moins correctement. On peut penser au nombre de voyageurs dont la desserte est assurée en un certain temps moyen, pondéré par le temps maximal du trajet (lui-même pondéré par le nombre de voyageurs de ce pire cas qui sont impactés), mais aussi pondéré par le ressenti des voyageurs face à la complexité (régularité et prévisibilité des arrêts, nombre de changements).

On trouve là un cas de chaînes de Markov et plus spécifiquement de files d'attente, de ce qu'on retrouve par exemple (et en simplifiant) dans les caisses de supermarché : si tout le monde attend à des caisses non spécialisées, une personne avec seulement un article attendra a priori autant de temps qu'une personne avec un caddie rempli à ras bord (en considérant le temps total d'attente de tout le monde, peu importe l'ordre de passage, c'est la vision du caissier en somme). Si l'on fait passer d'abord la personne à caddie (temps de passage = 5), puis celle à un article (temps = 1), on a un temps d'attente moyen de : (5 + (5 + 1)) / 2 = 5,5. En revanche, si l'on fait l'inverse, en donnant la priorité à la personne à un seul article, on a : (1 + (1 + 5)) = 3,5. On voit le gain ! Maintenant, imaginons six personnes avec un article (temps = 6 x 1) et une personne avec caddie bien rempli (temps = 4). Premier cas : (4 + (4 + 1) + (4 + 1 + 1) + (4 + 1 + 1 + 1) + (4 + 1 + 1 + 1 + 1) + (4 + 1 + 1 + 1 + 1 + 1) + (4 + 1 + 1 + 1 + 1 + 1 + 1)) / 2 = (4 + 5 + 6 + 7 + 8 + 9 + 10) / 2 = 24,5. Inversement, caddie en dernier, cela donne : (1 + (1 + 1) + (1 + 1 + 1) + (1 + 1 + 1 + 1) + (1 + 1 + 1 + 1 + 1) + (1 + 1 + 1 + 1 + 1 + 1) + (1 + 1 + 1 + 1 + 1 + 1 + 4)) / 2 = (1 + 2 + 3 + 4 + 5 + 6 + 10) / 2 = 15,5. Rien à voir ! Voilà pourquoi, après bien des années à s'entêter dans une organisation soviétique de la file d'attente unique égalitaire aux guichets communs, la poste a enfin ouvert des guichets séparés (sous la forme d'îlots) pour discriminer les opérations longues (dépôts et retraits d'argent, envois d'argent, opérations sur compte) et les opérations courtes (retrait d'un recommandé ou d'un colis), pour le bien général, quitte à avoir parfois des ressources temporairement inoccupées (guichet sans file d'attente). C'est l'idée des caisses "moins de dix articles" aux supermarchés (où quand on a onze articles dans les mains, on pleure... Ou on en sacrifie un, ce qui est assez idiot d'un point de vue de l'optimisation générale recherchée).

Cet algorithme consistant à faire passer le plus court d'abord est à rapprocher d'un algorithme d'ordonnancement des tâches dans les noyaux temps réel, appelé EDF, earliest deadline first, qui est le plus optimisé que l'on puisse avoir. La différence est cependant que dans ce cas informatique, une tâche peut être découpée (un peu comme si on pouvait faire passer des "morceaux" de caddies, et de temps en temps des personnes avec un article seulement à acheter), et qu'il faut absolument respecter certaines échéances (d'où la notion de temps réel). La deuxième hypothèse est extrêmement forte, et ne peut être respectée que si l'on connaît absolument tout ce qui va se passer sur le système (sous peine de risquer la fatale "inversion de priorité", de celle qui vous bloque un robot sur Mars, et vous oblige à le reflasher à distance — ça fait cher le roaming) ; c'est la raison pour laquelle je déconseille assez souvent à mes clients de mettre du temps réel dans leurs systèmes connectés, sur lesquels il peut se passer tout et n'importe quoi (en fait, ils confondent le temps réel dur et une latence de réponse faible, des systèmes temps réel "mous"). Dans un système d'exploitation classique, sur bureau, les problématiques sont tout autres encore : par exemple, la lecture d'un fichier MP3 nécessite une fréquence de décodage telle que le son n'est pas hachuré, et pour l'utilisateur, cela est plus important que d'attendre 100ms de plus que sa page web se charge.

En revanche, un algorithme simple qui privilégierait toujours les tâches nécessitant peu de temps, et oublierait les grosses tâches (surtout sur un système non préemptible où l'on ne peut pas décider du découpage de la tâche en tranches), risque la famine, c'est-à-dire qu'une tâche ne tourne jamais, car toujours préemptée par des tâches plus prioritaires. C'est ce qu'il m'est arrivé une fois au Grand Palais : la file d'attente prioritaire de billets coupe-file achetés sur le web (et une autre encore plus prioritaire pour les cartes Sésames, tellement chères à l'année qu'un nombre négligeable est concerné cette fois, donc facilement absorbé) préemptait en permanence la file standard, ce que l'on ne pouvait prévoir en tant que simple visiteur, n'ayant pas l'information du nombre de billets coupe-file vendus pour ce jour-là (sinon je n'aurais pas cramé une RTT !). Pour du Picasso (que je n'aime pas beaucoup), il m'a ainsi fallu attendre plus de 6 heures avant de pouvoir entrer (un vendredi d'hiver à 0°C ! À 10€ le billet pour 1h30 de visite ! 15 minutes pour décongeler, une fois dedans). En informatique, pour éviter cela, on utilise la méthode du vieillissement : plus on attend et plus on gagne en priorité, jusqu'à devenir plus prioritaire que les petits nouveaux normalement prioritaires. Autrement dit, il faut parfois mettre un train direct pour la grande banlieue plutôt que de multiplier les omnibus (la ligne passant par Melun et Fontainebleau décrochée de la ligne D et rattachée en surface à gare de Lyon, par exemple).

Autre soucis encore du multitâche en informatique : la race condition. C'est ce qui arrive lorsque les tâches sont dépendantes les unes des autres, et que celle qui devait arriver avant tarde trop. J'ai une fois été appelé en urgence pour un problème de débogage où l'ajout de "printf" pour afficher des messages nécessaires pour trouver un problème ralentissait la tâche, et entraînait d'autres problèmes un peu partout, parce que les autres tâches étaient mal synchronisées, ou dépendaient d'interruptions extérieures non contrôlables (en l'occurrence, pour une Set Top Box, difficile de ralentir le flux vidéo extérieur à décoder !). Si nous revenons à nos trains, c'est ce qui se passe dès qu'il y a un retard sur la ligne. Pour un métro, linéaire (coopératif, dirait-on en informatique), cela ralentit l'ensemble de la ligne, et les seuls problèmes sont le retard des voyageurs (décalage du départ) et l'engorgement (en somme on crée une file d'attente sur une ressource plus rare). Mais sur notre RER C, l'impact est bien plus fort, car il y a des trains omnibus et des trains semi-directs qui doublent les premiers, sachant que tous doivent ensuite respecter les mesures de sécurité de la SNCF (un train toutes les quatre minutes, si je ne m'abuse) une fois dans Paris intra-muros, sur la même voie pour un sens donné (le problème est essentiellement sur les gares de St-Michel, Pont de l'Alma et Tour Eiffel, car toutes les autres disposent de plusieurs voies dans les deux sens). Dans ce genre de cas, mieux vaudrait rapidement recalculer le meilleur moyen de contenter tout le monde en générant de nouveau totalement l'agenda des trains — actuellement, le système de pénalités du STIF est d'une idiotie sans nom, puisqu'il vaut mieux supprimer un train, et donc libérer de la ressource-voie au détriment d'une attente beaucoup plus longue pour les usagers laissés à quai, que de payer pour les minutes de retard (calculées par rapport aux horaires de passages théoriques, donc inflexibles) engrangées sur toutes les trop nombreuses stations du parcours. Pour cela, il faut des algorithmes d'ordonnancement très puissants et rapides, dont nous avons vu que leur existence paraît assez théorique à la SNCF... Il y a aussi un problème politique à régler auprès du STIF pour qu’elle change ses mesures de qualités (on dirait de la mauvaise KPI de managers fous modernes).

Autre exemple d'ordonnancement : lorsqu'il y a une grève (ou certains travaux lourds, ce qui revient à peu près au même du point de vue des usagers). Il vaut mieux alors rendre un maximum de trains omnibus, ce qui certes retarde la personne qui doit aller en bout de ligne (minoritaire) mais fait gagner beaucoup de temps à celles qui sont sur les premières stations (extrêmement majoritaires), ce qui ferait beaucoup baisser le temps d'attente moyen — et c'est bien lui seul qui compte, modulo le fait de ne pas rendre totalement insupportable l'attente aux "sacrifiés" pour le bien commun, sachant par ailleurs qu'une partie bénéficierait aussi de trains omnibus et non demi-service qui leur permettraient certains trajets de banlieue à banlieue. C'est quelque chose qui est parfois mis en place, mais très (trop !) tardivement lorsque cela arrive, manifestement parce que c'est complexe à calculer avec le système actuel (outre qu'en gare, c'est-à-dire sur le terrain, les agents SNCF sont parfaitement idiots à ce sujet, ayant pu m'entretenir avec certains à ce propos).

Donc, pour notre arrêt supplémentaire à Ivry-sur-Seine, où les quais sont bondés le matin et le soir (la ville étant limitrophe, elle se développe énormément ces dix dernières années, et pourrait rattraper Issy, Puteaux ou St-Denis), l'ajout d'un train supplémentaire dans la beaucoup trop longue tranche de 15 minutes qui est la fréquence actuelle (alors qu'il faut moins de trois minutes pour arriver à Bibliothèque François Mitterrand, qui grâce à la 14 permet de traverser Paris vers St-Lazare en dix minutes seulement !) va faire baisser le temps moyen de transport des voyageurs de bien belle façon, faisant augmenter cependant un peu le temps de transport des banlieusards plus lointain. C'est une forme de répartition démocratique (dictature de la majorité), mais il n'y a qu'à lire le blog du RER C pour s'apercevoir à quel point cela est déjà extrêmement mal perçu : le problème de la liaison banlieue-Paris (et ne parlons pas de la liaison banlieue-banlieue, qui est en réalité LE plus gros problème catastrophique qui se cache derrière) est hautement politique et source des plus hautes tensions.

Pour résumer, je ne vois donc que deux solutions à mettre en oeuvre simultanément :
    _ découper la ligne en tranches autonomes et articulées seulement dans des gares-relais comme Massy, Chantiers ou Juvisy (Choisy aussi, on peut en trouver d'autres) ;
    _ écrire un logiciel de simulation de toutes les lignes concernées, qui peut calculer les horaires idéaux en fonctions de tous les paramètres possibles (notamment le nombre de voyageurs le matin, et de fait les temps d'attente dans chaque gare pour laisser descendre et monter les voyageurs, ceci étant dépendant en outre de la fréquence même des trains), et qui soit écrit avec des méthodes métaheuristiques permettant rapidement de tout recalculer en cas d'imprévu (rame en panne et voyageurs à récupérer dans le train suivant ou un train "détourné", problèmes divers sur la ligne tels que la signalisation ou un passage à niveau déficients, retards pour cause de portes bloquées ou de signal d'alarme, etc.), ce qui arrive très régulièrement et me paraît pour le moment géré à la main (donc forcément mal étant donné la complexité du problème !).

La moralité est qu'un informaticien éclairé vaut mieux que tout un tas de politiques de la région négociant au STIF leurs bouts de chandelles — pendant que les citoyens-usagers souffrent énormément — et que des cheminots dépassés qui gèrent avec des moyens assez dérisoires (je n'avais pas fait de compte-rendu de ma très sympathique visite du Centre opération Transilien RER C à Montparnasse, en novembre 2012, mais c'était fort intéressant !), dans la hâte permanente, des problèmes extrêmement trop complexes pour eux (qui ne relèvent pas de leur champ de compétence, surtout, et il n'y aucune honte à cela : faire passer des trains sans aucun incident fatal dans ces conditions est tout de même un sacré challenge ! On râle, mais on arrive entier à destination, c'est le principal faut-il rappeler). Surtout que l'on voit qu'un vote à la région en février sur les nouveaux horaires trouve sa traduction sur le terrain en décembre. Niveau agilité, on repassera... À ce rythme-là, on trouvera la solution idéale en 2042. Peut-être.

Je n'ai plus qu'à espérer que ce billet titillera les bonnes personnes et ouvrira un nouveau champ de réflexion... À votre disposition !  :)