This repository contains code for replicating the results of the following paper:
Niklas Åkerblom & Morteza Haghir Chehreghani (2023). A Combinatorial Semi-Bandit Approach to Charging Station Selection for Electric Vehicles. Transactions on Machine Learning Research (TMLR).
Please cite us in the following way you use the code for new publications:
@article{
akerblom2023charging,
title={A Combinatorial Semi-Bandit Approach to Charging Station
Selection for Electric Vehicles},
author={Niklas {\AA}kerblom and Morteza {Haghir Chehreghani}},
journal={Transactions on Machine Learning Research},
issn={2835-8856},
year={2023},
url={https://openreview.net/forum?id=ndw90pkNM9}
}
The project is developed using Python 3.9, with the following dependencies and (tested) versions:
Dependency | Version |
---|---|
NumPy | 1.24.2 - 1.26.2 |
SciPy | 1.9.3 - 1.11.3 |
Matplotlib | 3.6.2 - 3.8.1 |
Pandas | 1.4.3 - 2.1.3 |
NetworkX | 2.8.8 - 3.2.1 |
pytest | 7.4.3 |
The simulation framework requires the user to provide a road network graph and a list of charging stations. Both need to be provided as CSV files. Each row in the road network graph CSV file represents an edge in the road network graph, in the following format:
from_id | from_y | from_x | to_id | to_y | to_x | mean_consumption | mean_time |
---|---|---|---|---|---|---|---|
... | ... | ... | ... | ... | ... | ... | ... |
The columns from_id
and to_id
contain the string
source and target vertex (node) IDs of each edge, respectively.
The columns from_y
and from_x
contain the float
Y (latitude) and X (longitude) coordinates of the source vertex,
with to_y
and to_x
containing the corresponding coordinate for the target vertex. The columns mean_consumption
and mean_time
contain the float
mean energy consumption (in joules
) and travel time (in seconds
) of the edge,
respectively.
Each row in the charging station list CSV file represents a distinct charging station, in the following format:
station_id | node_id | node_y | node_x | power |
---|---|---|---|---|
... | ... | ... | ... | ... |
The column station_id
should contain distinct string
IDs for all charging stations. The columns node_id
, node_y
and node_x
should contain the string
vertex ID and the float
Y and float
X coordinates of the closest road
graph vertex to each charging station. The power
column should contain the float
power (in watts
) provided by
each charging station.
While these files are not provided in this repository, the public data sources used in the paper are OpenStreetMap and Open Charge Map for the road graph and charging station list, respectively. The mean energy consumption can be computed using the formula in Eq. 15 of the paper, together speed, length and topology data from the road network graph. Similarly, the mean travel time can be computed using the length and maximum allowed speed of each edge in the road network graph.
Before the simulation can be started, it is necessary to preprocess the road graph and charging station list, using
the script charging_graph_preprocesser.py
in the eene-nav-bandit-sim
folder, with the following command line
arguments:
python charging_graph_preprocesser.py --road-graph-csv-path [road graph CSV path] --charging-station-csv-path [charging station CSV path]
This will produce three files, charging_graph_ids.csv
, complete_consumption_array.npy
and complete_time_array.npy
,
which will be saved to the output
folder (by default). The complete list of possible arguments to
charging_graph_preprocesser.py
is given below:
Argument | Type | Default Value | Description |
---|---|---|---|
--road-graph-csv-path | String | N/A | Road graph CSV path |
--charging-station-csv-path | String | N/A | Charging station CSV path |
--output-dir | String | "../output/" | Output directory |
--logging-level | String | "info" | Logging level (possible values: "debug" , "info" , "warning" , "error" , "critical" ) |
NOTE: Depending on the size of the road network graph and the number of charging stations, the preprocessing script may take several hours to complete.
To start the simulation, run the Python file sim_runner.py
in the eene-nav-bandit-sim
folder with the minimum
required set of command line arguments as follows:
python sim_runner.py --charging-station-csv-path [charging station CSV path] --start-node-id [start vertex ID] --end-node-id [end vertex ID]
Completing the simulation will produce a CSV file (results.csv
) containing instant and cumulative regret per
simulation iteration for each of the implemented exploration methods (Greedy
, Epsilon-Greedy
, Thompson Sampling
and BayesUCB
). In addition, a plot showing the cumulative regret per simulation iteration will be saved as
regret_plot.png
. The default output folder is output
. The complete list of possible arguments to sim_runner.py
is given below:
Argument | Type | Default Value | Description |
---|---|---|---|
--charging-station-csv-path | String | N/A | Charging station CSV path |
--start-node-id | String | N/A | Start vertex ID (must correspond to node_id of a charging station) |
--end-node-id | String | N/A | End vertex ID (must correspond to node_id of a charging station) |
--charging-graph-ids-csv-path | String | "../output/charging_graph_ids.csv" | Path to output charging_graph_ids.csv of preprocessing script |
--charging-consumption-npy-path | String | "../output/complete_consumption_array.npy" | Path to output complete_consumption_array.npy of preprocessing script |
--charging-time-npy-path | String | "../output/complete_time_array.npy" | Path to output complete_time_array.npy of preprocessing script |
--output-dir | String | "../output/" | Output directory |
--number-of-experiment-runs | Int | 5 | Number of times each exploration method will be run |
--experiment-horizon | Int | 100 | Number of simulation iterations in each experiment |
--start-seed | Int | 0 | Start random seed of simulation (incremented by 1 for each experiment run) |
--battery-capacity | Float | 252000000.0 | Battery capacity of simulation vehicle (in joules ) |
--min-power-factor | Float | 0.5 | Minimum power provided by each charging station, as factor of the specified level |
--power-scale | Float | 300.0 | Scaling factor for the power probability distribution of each charging station |
--charge-prior-param-ln-p0 | Float | 13.5 | Charging power prior distribution parameter ln_p0 (log(pi_0) in the paper) |
--charge-prior-param-q0 | Float | 300.0 | Charging power prior distribution parameter q0 (gamma_0 in the paper) |
--charge-prior-param-r0 | Float | 3.0 | Charging power prior distribution parameter r0 (xi_0 in the paper) |
--charge-prior-param-s0 | Float | 3.0 | Charging power prior distribution parameter s0 (xi_0 in the paper) |
--queue-prior-param-alpha0 | Float | 2.0 | Queue time prior distribution parameter alpha0 (alpha_0 in the paper) |
--queue-prior-param-beta0 | Float | 2400.0 | Queue time prior distribution parameter beta0 (beta_0 in the paper) |
--logging-level | String | "info" | Logging level (possible values: "debug" , "info" , "warning" , "error" , "critical" ) |
NOTE: Charging power prior distribution parameters r0
and s0
are merged to a single parameter xi_0
in the
paper. Examples of the input data format for sim_runner.py
can be found in the unit tests.
The code is provided "as is", but we welcome contributions as outlined in CONTRIBUTING.md.
The code is licensed under an Apache 2.0 license, copyright 2023 Volvo Car Corporation.
This work is funded by the Strategic Vehicle Research and Innovation Programme (FFI) of Sweden, through the project EENE (reference number: 2018-01937).