A genetic algorithm that builds optimal overnight EV charging schedules to minimize electricity cost, using real hourly day-ahead prices and a stochastic model of departure-time uncertainty.
Electricity prices vary dramatically hour to hour — especially during the 2022 European energy crisis, where German day-ahead prices swung from −0.1 to 70 cents/kWh in a single day. A naive EV charger ignores this entirely. This project asks: can a genetic algorithm learn when to charge, given that you don't know exactly when you'll leave in the morning?
The GA evolves 24-hour charging schedules (one power value per hour) across 70 real days, optimizing for cost while ensuring the battery is full enough before a stochastically sampled departure time.
| Step | Description |
|---|---|
| Generation | 40 random schedules seeded via Dirichlet distribution |
| Fitness | Monte Carlo simulation of 100 departure times; cost + penalty if undercharged |
| Selection | Top 2 schedules become parents |
| Crossover | Single-point crossover at a random hour index |
| Mutation | 10% chance to shift energy between two hours (preserves total) |
| Repair | Clip to charger limit, zero out 9 AM–6 PM (car away), rescale to target energy |
| Next gen | Parents + offspring pool sorted by fitness; keep top 40 |
The loop runs for 30 generations with early stopping if fitness stalls for 5 consecutive generations.
Rather than assuming a fixed departure time, each fitness evaluation simulates 100 random departures drawn from a normal distribution (mean = 8 AM, σ = 30 min). If the battery isn't sufficiently charged by the simulated departure, a quadratic penalty is applied. This makes the GA robust to real-world timing uncertainty.
A perfect-foresight greedy algorithm serves as the upper bound: it sorts available hours by price and fills them cheapest-first until the energy target is met. This is unrealistic in practice (it requires knowing all future prices) but provides a meaningful efficiency ceiling.
Source: ENTSOE Day-Ahead Electricity Prices via kagglehub
- German day-ahead market prices, hourly resolution
- Time range: January 1 – March 11, 2022 (1,680 hours / 70 days)
- Price range: −0.105 to 70.0 cents/kWh
- Downloaded automatically on first run — no manual setup needed
The dataset captures the height of the European energy crisis, making price-aware charging especially impactful.
| Metric | Value |
|---|---|
| Total energy delivered | 2,100 kWh |
| GA average efficiency vs. greedy | 81% |
| Savings vs. fixed 40 cent/kWh rate | €511.51 over 70 days |
Open genetic-algorithm-ev-charging.ipynb in Google Colab or Jupyter and run all cells. The dataset is downloaded automatically via kagglehub.
pip install kagglehub pandas numpy matplotlibA Kaggle account (free) is required for kagglehub to authenticate on first download.
| Parameter | Value |
|---|---|
| Battery capacity | 40 kWh |
| Daily consumption | 30 kWh |
| Max charger power | 7 kW |
| Car away (no charging) | 9 AM – 6 PM |
- Negative price edge case: The dataset contains a small number of negative electricity prices (excess renewable generation). The greedy baseline does not handle these correctly, producing anomalous efficiency values (including negative percentages) on roughly 10 of the 70 days. The GA itself is unaffected.
- Hard-coded parameters: EV specs are defined inline across multiple cells rather than in a single config block.
- Stochastic fitness variance: Monte Carlo sampling means fitness scores have small random variance across evaluations — this is mitigated by averaging 100 samples but can cause minor ranking instability.
Niklas — Arcada coursework 2025