Skip to content

Comments

WIP: Evolutionary network design branch#1600

Draft
tahini wants to merge 59 commits intomainfrom
evolutionaryTransitNetworkDesign
Draft

WIP: Evolutionary network design branch#1600
tahini wants to merge 59 commits intomainfrom
evolutionaryTransitNetworkDesign

Conversation

@tahini
Copy link
Collaborator

@tahini tahini commented Nov 25, 2025

Feature branch for the evolutionary transit network design algorithm implementation.

Current status: It compiles!!!... 👯

TODO:

frontend:

  • Nettoyage... beaucoup de nettoyage...
  • Utiliser les option descriptor pour les paramètres de conception de réseau aussi (1re section)
  • Fournir et afficher des messages d'aide dans les formulaires des option descriptors (encore connus sous le nom de SimulationAlgorithmOptionDescriptor)
  • Ajouter un type secondsToMinutes ou qqc du genre aux option descriptors pour permettre d'avoir des valeurs en secondes, mais indiquer de les faire entrer en minutes dans les UI.
  • Validation de chaque étape. S'assurer que le bouton Suivant soit actif seulement si tout est valide. Tous les champs n'ont pas encore été validés
  • Valeurs par défaut des objets. Bien que les valeurs par défaut s'affichent dans l'interface, elles ne sont pas automatiquement assignées aux objets correspondant, donc elles peuvent rester non-définies si non-modifiées
  • Traductions des champs non-traduits (ou mise à jour des traductions, car elles sont déjà en qq part) (@kaligrafy)
  • Affichage du résumé et confirmation sur la dernière page.
  • Permettre de visualiser les résultats (@kaligrafy)

backend:

  • Faire fonctionner qqc, la job ne roule de toute évidence pas, ni ne complète avec une exception. Donc au moins faire qq générations avec des console.log
  • Revoir le flot au complet, les types ont été changés pour passer la Job et pour que ça compile, mais ça a probablement brisé beaucoup de choses.
  • Ajouter les méthodes de simulation (pour l'instant, c'est des valeurs par défaut)
  • Sauvegarder les résultats en qq part somehow
  • Gérer la cache correctement (ou s'assurer que c'est géré correctement?)
  • S'arranger pour que la cache n'ait pas besoin d'un symlink dans le répertoire de cache principale...
  • Gérer les checkpoints et le internal_data pour récupérer la Job en cas d'arrêt
  • Ajouter des checkpoints au niveau des candidats, pour récupérer les jobs en cours et déjà complétées
  • Sauvegarder les messages d'erreur dans la tâche pour pouvoir les visualiser
  • S'assurer que les messages d'erreur sont tous compréhensibles et exhaustifs pour l'utilisateur (@kaligrafy)
  • Gérer l'annulation de la tâche
  • Faire fonctionner les tests
  • Ajouter de nouveaux tests
  • Emettre la progression de la tache, présentement stuck à "en attente" (@kaligrafy)
  • Fixer ratio des ODs à utiliser pour le calcul et vérifier implémentation (@kaligrafy)
  • Vérifier ce qui se passe avec des lignes directionnelles? Possiblement ajouter un param: ramener le véhicule ou téléportation (@kaligrafy)
  • Pondération à partir du fichier OD (@tahini, @kaligrafy)
  • Déplacer les fonction de "fitness" hors du fichier de préférence
  • Trouver probleme de l'interface qui gèle pour Yannick sur Chrome
  • Documenter et, peut-être, permettre de paramétrer les fonctions de fitness
  • Faire un sample du fichier des OD trips pour les tâches de calculs: mettre une heure de départ aléatoire entre 8 et 9 AM.
  • S'assurer que les scénarios sauvegardés ont des horaires pour la journée complète: pour simplifier la quantité de données à traiter, les différents services à simuler ne couvrent qu'une petite période de la journée (2x le plus long trajet avant 8AM et après 9AM). Si on ne conserve que ça, seuls les trips dans ces horaires seront routés
  • Add a friendly name to simulations so that scenarios associated with it can be easily identified and remove the GAL from scenario names. Add the jobID (in case someone copies the job parameters without changing the name, each run needs to have a unique name) to the name and if there is no name specified, only the jobID will identify the job
  • Add a README to packages/transition-backend/src/services/evolutionaryAlgorithm/ To describe the various directory
  • the maximum interval seems to be an exclusive value, putting 30 minutes seem to rather cap to 29 minutes
  • Generate result files even if the job failed
  • Dans les résultats, différencier non-routés des erreurs, au moins en les comptant.
  • s'assurer que la destruction de la job parent ne cause pas trop d'erreur aux enfants en cours. Tout doit se terminer de façon harmonieuse (il y a présentement beaucoup de lgos d'erreurs dans ce cas)
  • Dans une run sur l'infra, il y a eu un cas où les fichiers dans les resources ne se sont pas sauvegardés correctement. La tâche a terminé, les fichiers étaient bien sur le serveur, mais pas dans les resources de la tâche. Hypothèse: race condition, manque un await en qq part.

@tahini tahini force-pushed the evolutionaryTransitNetworkDesign branch 6 times, most recently from 2a054d3 to 4028711 Compare December 1, 2025 21:51
@tahini tahini force-pushed the evolutionaryTransitNetworkDesign branch 6 times, most recently from 1221c70 to d51a1d8 Compare December 8, 2025 22:15
@kaligrafy kaligrafy force-pushed the evolutionaryTransitNetworkDesign branch from d51a1d8 to 5e6d988 Compare December 15, 2025 15:28
@tahini tahini force-pushed the evolutionaryTransitNetworkDesign branch 2 times, most recently from 8bfa962 to cac37ff Compare January 12, 2026 18:01
@tahini tahini force-pushed the evolutionaryTransitNetworkDesign branch from 4013509 to 6e332e1 Compare January 22, 2026 01:08
@tahini tahini force-pushed the evolutionaryTransitNetworkDesign branch 2 times, most recently from 9dda198 to 100d441 Compare February 7, 2026 02:15
@tahini tahini force-pushed the evolutionaryTransitNetworkDesign branch 2 times, most recently from e623079 to 9a493e6 Compare February 20, 2026 15:22
@coderabbitai
Copy link

coderabbitai bot commented Feb 20, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch evolutionaryTransitNetworkDesign

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@tahini tahini force-pushed the evolutionaryTransitNetworkDesign branch from 705065f to ed722e0 Compare February 20, 2026 16:53
The types should not be partial, in the backend, they are meant to be
complete. Only the frontend will have partial types to support entering
the configuration, so the frontend will build their own types
accordingly.
When a configuration element is itself an object, it can use a `nested`
descriptor to provide a descriptor for the sub-fields it supports.
Make the demand in line with the one from batchRoute calculations.
Separate the simulation in 3 fields: demand, routing parameters for
calculation and additional evaluation options to calculate the cost of a
scenario. Add descriptors for each of those methods and update tests
accordingly.

In the backend, update the simulation method with the new parameters. It
does not work anymore. Pseudo-code has been written to describe how the
simulation method will have to run.
Type the parameters for a transit network job in general.

Add the specific types for the transit network design using the
evolutionary algorithm.

Add functions to create and replay such a job. Also add an empty
executor for the job and a wrapper for it on the workerpool.
tahini and others added 28 commits February 23, 2026 17:27
* Let the `nested` option type return a descriptor instead of a
  descriptor factory, to have singleton descriptors

* The main `OptionsComponent` will get the default option values at
  first load instead of callers. The default values will be set whenever
  the options descriptor changes.
Add some help texts and error to the `TransitNetworkDesignParameters`
descriptor.

Also add many help texts and errors to the
`EvolutionaryAlgorithmDescriptor`.
And translate labels of select data.
The 'askAs' gives an indication of the unit in which the data should be
asked from the user, for example, to ask a number of seconds in minutes.
The transit routing attributes of the network design are changed to be
seconds asked as minutes.
Instead of throwing simple strings, `TrError` objects are thrown in the
`getFilePath` method.
When simulating a scenario candidate using the OD trips approach, we
sample the original demand file to contain only a certain ratio of the
data.

For each selected record, a random time is selected as departure time
between 8 and 9 am. This time data is added to the demand parameters of
the simulation job, as it may not be present in the main file.

For now, each file row has a "sample ratio" probability of being
included in the final file, which means the file sample may not
represent exactly the sample ratio because of the randomness induced.
batch csv demand type has changed for the batch calculation job. We
create a similar demande file for the OdTripSimulationMethod type.

For sake of simplicity, for now, we keep the whole CsvFileAndMapper type
instead of just the field mapping, like in the batch calculation, as it
would require a different backend and frontend type with the options
descriptor. When we clean the option descriptor classes, we can make
sure the case is supported and the options descriptor type apply only to
the options configuration and allow for subsequent types in the backend.
Update test files to align with refactored network design and simulation
method interfaces:

- Update OdTripSimulationFromCsvAttributes mocks to include required
  `projection` field and all required fieldMappings properties
- Update TransitNetworkDesignParameters mocks with new required fields:
  minTimeBetweenPassages, numberOfLinesMin, numberOfLinesMax,
  nonSimulatedServices, linesToKeep
- Update i18n keys from colon (:) to dot (.) separators to match new
  format (e.g., transit:networkDesign.parameters.*)
- Fix ExecutableJobUtils test to expect TrError instead of plain string
- Update OdTripSimulationMethod tests for API changes: descriptor
  properties, type 'seconds' instead of 'integer', updated mapping
  descriptor keys
- Apply code style fixes: arrow functions, trailing semicolons, spacing
* Rename the `TrRoutingBatch` class to `TrRoutingBatchExecutor` and
  export it

* Make the `handleResults` method public so it can be called from the
  outside with any visitor.

* The `batchRoute` main function of the file remains a wrapper for the
  job execution and default result processing to generate files, but it
  is now responsible for handling the default visitor class, such that
  the executor class itself does not know which result visitor will be
  used.
…n results

Replace the `OdTripSimulation#processResults` method by a
`OdTripFitnessVisitor` class, which handles each result independendly
and keeps track of final results.

Also fixes a bug where any unrouted trip would result in `null` values
for many metrics.
And properly type them to identify the discrepancies between the actual
fields and what is expected.

Fixes the `null` fitness issue, with proper field calls.

Also use the non-routable taxi od trip fitness function in case there is
no routing found.
fitness functions need to be real ones, not empty strings in the tests.
This type represents a value between 0 and 1, but suggests that UIs or
CLI ask for it as a percentage, ie as a value between 0 and 100, to make
the user's life easier.

Use a formatted input widgets in frontend, so ask to convert to/from a
value between 0 and 1 and a percentage.
…n file

This lets the db queries import them without creating circular
dependencies.

Also add the timeBetweenPassages, outbound and inbound path IDs to the
`LineLevelOfService` and `ResultSerialization` types as this will be
required for saving the results.
This adds 3 tables to store each candidate's results for the genetic
algorithm transit network design:

* `tr_network_design_gal_results` stores the total fitness for each
  candidate of each generation
* `tr_network_design_gal_simulation_results` saves the details for each
  simulation methods of candidates, storing its fitness score and data.
* `tr_network_design_gal_candidate_lines` store the lines used by each
  candidate, as well as the number of vehicles used.

Add the database queries and test to save/stream the results.
After each generation, save the results of each candidate and simulation
to the database.

At the end of the job's execution, produce 2 output files:

* A candidate line file, which describes for each generation/candidates,
  the lines that have been used and how many vehicles for each.

* A simulation result file, which describes for each
  generation/candidates, the simulation method used, its fitness and
  some data.
For simplicity and given the number of schedules generated, the
simulations only create schedules for a few hours during a day. But when
saving a scenario, in order to simulate it with real data, the schedules
need to span the whole day.

This adds the collection manager to the network design job, as it is
required for the schedules generation.

Also, it saves the scenarios, services and modified lines to the main
cache after saving, so they are right away available to the user for
calculations.
`ErrorMessage` has been moved and renamed to `TranslatableMessage`

Also run `yarn format`
All the fields that are not the ones used to create the OD trip (id,
coordinates and time) are saved in the trip's `data` field. It is also
saved along with the result in the batch results table.

This will allow various result visitor to make use of this data, without
having to re-read the csv file. For example, to weight the results with
a weighting factor column, or calculate the cost according to some
additional socio-demographic data available, like age or gender.
Now that all the extra data is available in the result, we can get the
expansion factor if the field is set. It defaults to 1 if not set or if
it is an incorrect number format.
The `decimal` knex data type converts by default to a `numeric(8,2)` in
postgres, effectively making maxing the value to 6 digits with 2
decimals. We use `double` instead to support any floating point value for
the fitness score, as it can be quite high for large simulations, for
example, with many thousands OD trip pairs, the value can be in the
millions or tens of millions. This converts to `double precision` in postgres.
Get more information when the cache collection reading fails and the job
ID in completion status update.
The main cache directory may have been reset when the task is resumed,
so we need to create the symlink in that case also.
@tahini tahini force-pushed the evolutionaryTransitNetworkDesign branch from b91e8bf to 181e6a0 Compare February 23, 2026 22:33
In order to determine for large sample if the current sampling approach
(where each line has x% chance of being in the sample, instead of
exactly x% of the file) can cause result biases, we add to the
simulation results the number of lines effectively in the sample file
and the total weight that it represents. From that information, we can
decide how urgent it is to change the sampling algorithm (see the FIXME
in `OdTripSimulation#sampleOdTripFile` function).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants