Skip to main content

eflips-opt


Part of the eFLIPS/simBA list of projects.


This repository contains code for optimizing (electric) bus networks. The following optimization problems are considered:

  • Depot-Rotation Matching: Given a set of depots and a set of rotations, find the optimal assignment of rotations to depots.
  • Vehicle Scheduling: Given a set of trips, find the set of rotations (vehicle blocks) that serves all trips with the minimum number of vehicles, optionally respecting battery and duration limits.
  • Smart Charging (eflips.opt.smart_charging): After a simulation, smooth the depot charging events to reduce peak power.

Installation

  1. Clone the repository

    git clone git@github.com:mpm-tu-berlin/eflips-opt.git
    
  2. Install the packages listed in poetry.lock and pyproject.toml into your Python environment. Notes:

    • Python 3.10 to 3.13 is supported.
    • Using the poetry package manager is recommended. It can be installed according to the instructions listed here.
  3. In order to use the Depot-Rotation Matching, it is recommended to install the Gurobi solver. The solver can be installed by following the instructions listed here. The solver can be used with a license for academic purposes. If you do not have a license, you can request one here.

Usage

Depot-Rotation Matching

Example scripts for the Depot-Rotation Matching problem can be found in the examples/depot_rotation_matching directory. The general usage is as follows:

from eflips.opt.depot_rotation_matching import DepotRotationOptimizer

# Initialize the optimizer
optimizer = DepotRotationOptimizer(session, SCENARIO_ID)

# Create a depot input. Both existing and new depots can be added.
user_input_depot = [
   {
       "depot_station": 103281393,
       "capacity": 300,
       "vehicle_type": [84, 86, 87, 90],
   },  # Indira-Gandhi-Str
   {
       "name": "Suedost",
       "depot_station": (13.497371828836501, 52.46541010322369),
       "capacity": 260,
       "vehicle_type": [82, 84, 85, 86, 87, 90],
   },  # Südost
]
optimizer.get_depot_from_input(user_input_depot)
optimizer.data_preparation()
optimizer.optimize(time_report=True)
optimizer.write_optimization_results(delete_original_data=True)

Vehicle Scheduling

The scheduling problem is formulated as a directed acyclic graph: nodes are trips, edges are feasible connections between trips, weighted by the waiting time. The minimum number of rotations is a minimum path cover of this graph, which is computed by the Rust solver eflips-schedule-rust. Per-trip weights (e.g. the state-of-charge used by each trip) let the solver keep each rotation within the battery capacity and a maximum duration.

from datetime import timedelta
from eflips.opt.scheduling import (
    passenger_trips_by_vehicle_type,
    create_graph,
    solve,
    write_back_rotation_plan,
)

# Create one schedule per vehicle type, so trips of e.g. 12m and 18m buses are not mixed
trips_by_vt = passenger_trips_by_vehicle_type(scenario, session)
for vehicle_type, trips in trips_by_vt.items():
    if not trips:
        continue
    # delta_socs: optional {trip_id: fraction of the battery used by the trip}
    graph = create_graph(trips, maximum_schedule_duration=timedelta(hours=24))
    rotation_graph = solve(graph, maximum_schedule_duration=timedelta(hours=24))

    # Replace the scenario's original rotations with the new ones
    write_back_rotation_plan(rotation_graph, session)
session.commit()

create_graph() has further parameters for break times and for preferring connections on the same line. visualize_with_dash_cytoscape(graph) shows a graph in the browser.

Development

We utilize the GitHub Flow branching structure. This means that the main branch is always deployable and that all development happens in feature branches. The feature branches are merged into main via pull requests.

We use black for code formatting. You can use pre-commit to ensure the code is formatted correctly before committing. You are also free to use other methods to format the code, but please ensure that the code is formatted correctly before committing.

Please make sure that your poetry.lock and pyproject.toml files are consistent before committing. You can use poetry check to check this. This is also checked by pre-commit.

Each pull request must increase the version number in pyproject.toml (CI checks it against PyPI), following Semantic Versioning: patch for changes without API changes, minor for backwards-compatible API changes such as new features, major for breaking changes. Every merge to main is published to PyPI.

Tests need a PostgreSQL/PostGIS database, given in DATABASE_URL. All data in it is deleted.

DATABASE_URL=postgresql://user:password@localhost/database PYTHONPATH=tests:. poetry run pytest

License

This project is licensed under the AGPLv3 license - see the LICENSE file for details.

Funding Notice

This code was developed as part of the project eBus2030+ funded by the Federal German Ministry for Digital and Transport (BMDV) under grant number 03EMF0402.

Metadata

Release files for eflips-opt 1.0.14

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for eflips-opt 1.0.14
File Size Uploaded Provenance Actions
eflips_opt-1.0.14.tar.gz 43.8 kB With provenance Details for eflips_opt-1.0.14.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for eflips-opt 1.0.14
File Interpreter ABI Platform Actions
eflips_opt-1.0.14-py3-none-any.whl Python 3 none any Details for eflips_opt-1.0.14-py3-none-any.whl

Total release size: 88.6 kB

Release files / eflips_opt-1.0.14.tar.gz

Download URL eflips_opt-1.0.14.tar.gz
Size 43.8 kB
Tags Source
SHA-256 checksum
How to use checksums
77cab718589b35d78a0aae858def67ea0f9eb1a75af43c78512ec6e94d3497c9
BLAKE2b-256 checksum
How to use checksums
8d7ae348036d79c7f79b0ba7a3a618a352cd5026ca82e5f39539c46edf432bef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Release files / eflips_opt-1.0.14-py3-none-any.whl

Download URL eflips_opt-1.0.14-py3-none-any.whl
Size 44.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
980e2b870be2fecd28b96fa8b640cec9c1db359cdb092f8674b228a54c12e9fa
BLAKE2b-256 checksum
How to use checksums
87e87c5aec8f40c41493da5c22c919980c75d2a943210ff9938637809553e1f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Security for eflips-opt 1.0.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for eflips_opt-1.0.14.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.14 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page