MILP

Julia Environment

Die Analysen wurden mit der Open Source Programmiersprache Julia und mit unterschiedlichen MILP-Solvern erstellt.

  • Wikipedia beschreibt Julia so: “Julia ist eine höhere Programmiersprache, die vor allem für numerisches und wissenschaftliches Rechnen entwickelt wurde und auch als Allzweck-Programmiersprache verwendet werden kann, bei gleichzeitiger Wahrung einer hohen Ausführungsgeschwindigkeit.”
  • Solver Cbc: Open Source
  • Solver HiGHS: Open Source
  • Solver Gurobi: kommerziell, akademische Lizenz
using Revise
using Pkg
Pkg.activate(joinpath(@__DIR__, "../../packages/OpenEVFleet.jl"))
import OpenEVFleet as EV
  Activating project at `~/forschung/gitlab/open-ev-fleet/packages/OpenEVFleet.jl`
# cd to git root directory:
cd(joinpath(@__DIR__, "../..")) 
print("working directory: ", pwd())
working directory: /home/kr/forschung/gitlab/open-ev-fleet

Spitzenlastreduktion

Infra_LoadBalancing

file_analysis = "data/private/vbz/output/KR_Infra_LoadBalancing/analysis_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(file_analysis, verbose=true);
Loading analysis file ... finished.
EV.print_analysis(analysis)
{
  "data config": {
    "input directory": "data/private/vbz/input/vbz_02_d37v_1d/",
    "output directory": "data/private/vbz/output/KR_Infra_LoadBalancing/vbz_02_d37v_1d/",
    "input overwrites": {
      "prices.csv": {}
    },
    "input selection": {
      "time window": {
        "start": "2024-03-18 05:57:00",
        "end": "2024-03-19 05:56:00"
      }
    },
    "input deselection": {}
  },
  "algorithm": {
    "name": "ego_infra",
    "description": "This algorithm computes a simulation including the charging infrastructure..",
    "reproducible execution": {
      "command working directory": "open-ev-fleet/packages/OpenEVFleet.jl/",
      "command line": "julia run_analysis.jl PATH_TO/analysis.json"
    },
    "parameters": {
      "use locations_active_baseloads": false
    }
  },
  "verbose": true,
  "write json": true
}
data, aux = EV.generate_data_and_aux(analysis);
Loading csv data ... finished.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Making auxiliary tables ... finished.
res = EV.apply_algorithm(data, aux, analysis);
Applying algo ego_infra:
  Computing results ...  finished.
  Saving analysis.json ... finished.
EV.plot_power_res_output(res["output"], "locations_powers")
# 15-minutes averaged power:
EV.plot_power_res_output(res["output"], "locations_active_powers")
EV.analyse_objectives(analysis, aux, res)
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.000 MW
- charging:   1.100 MW
- total:      1.100 MW
costs at location 0:
- baseload:       0.00 EUR
- ESS:            0.00 EUR
- charging:    1727.45 EUR
- total   :    1727.45 EUR
energies at location 0:
- baseload:      0.000 MWh
- ESS:           0.000 MWh
- charging:      7.989 MWh
- total   :      7.989 MWh
No vehicle is broke down.
Minimum SOC_rel: 32.69 % by VH_ID 652
Mean minimum SOC_rel over all vehicles: 50.54 %
# save results to csv files:
EV.save2csv_res_output(analysis, res["output"])
Saving results to csv ...finished.

MILP_Assigned_PeakLoad

file_analysis = "data/private/vbz/output/KR_MILP_Assigned_PeakLoad/analysis_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(file_analysis);
analysis["algorithm"]["parameters"]["solver"] = "HiGHS";  # Cbc, Gurobi, HiGHS
data, aux = EV.generate_data_and_aux(analysis);
res = EV.apply_algorithm(data, aux, analysis);
Loading analysis file ... finished.
Loading csv data ... finished.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
No data config input overwrites found.
Making auxiliary tables ... finished.
Applying algo MILP:
  Computing results ...
    - using given VH2CP assignments ... 
    - building optimization model ... finished.
    - optimizing with solver HiGHS ... finished in 0.19 seconds
      status: OPTIMAL
      optimal value = 434.03
      finished.
  Saving analysis.json ... finished.
EV.plot_power_res_output(res["output"], "locations_active_powers")
EV.analyse_objectives(analysis, aux, res)
EV.save2csv_res_output(analysis, res["output"])
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.000 MW
- charging:   0.434 MW
- total:      0.434 MW
costs at location 0:
- baseload:       0.00 EUR
- ESS:            0.00 EUR
- charging:    1121.67 EUR
- total   :    1121.67 EUR
energies at location 0:
- baseload:      0.000 MWh
- ESS:           0.000 MWh
- charging:      7.990 MWh
- total   :      7.990 MWh
No vehicle is broke down.
Minimum SOC_rel: 32.69 % by VH_ID 652
Mean minimum SOC_rel over all vehicles: 50.54 %
Saving results to csv ...finished.

Vergleich: Simulation - Heuristik - MILP

path = "data/private/vbz/output/"
file_paths = Dict(
    "simulation" => joinpath(path, "KR_Infra_LoadBalancing/vbz_02_d37v_1d/locations_active_powers.csv"),
    "heuristic"  => joinpath(path, "BADO_Heuristic_MinLoad/vbz_02_d37v_1d/locations_active_powers.csv"),
    "MILP"       => joinpath(path, "KR_MILP_Assigned_PeakLoad/vbz_02_d37v_1d/locations_active_powers.csv")
)
EV.plot_LC_powers_comparison(file_paths);

MILP_Assigned_PeakLoad + Baseload

file_analysis = "data/private/vbz/output/KR_MILP_Assigned_PeakLoad_Baseload/analysis_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(file_analysis);
analysis["algorithm"]["parameters"]["solver"] = "HiGHS";  # Cbc, Gurobi, HiGHS
data, aux = EV.generate_data_and_aux(analysis);
res = EV.apply_algorithm(data, aux, analysis);
Loading analysis file ... finished.
Loading csv data ... 
  Loading overwrite file locations_active_baseloads_synth.csv for locations_active_baseloads ... finished.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Making auxiliary tables ... finished.
Applying algo MILP:
  Computing results ...
    - using given VH2CP assignments ... 
    - building optimization model ... finished.
    - optimizing with solver HiGHS ... finished in 0.2 seconds
      status: OPTIMAL
      optimal value = 2350.00
      finished.
  Saving analysis.json ... finished.
EV.plot_power_res_output(res["output"], "locations_active_powers")
EV.analyse_objectives(analysis, aux, res)
EV.save2csv_res_output(analysis, res["output"])
peak active powers at location 0:
- baseload:   2.350 MW
- ESS:        0.000 MW
- charging:   1.700 MW
- total:      2.350 MW
costs at location 0:
- baseload:    5391.88 EUR
- ESS:            0.00 EUR
- charging:    2379.13 EUR
- total   :    6095.65 EUR
energies at location 0:
- baseload:     37.038 MWh
- ESS:           0.000 MWh
- charging:      7.990 MWh
- total   :     45.028 MWh
No vehicle is broke down.
Minimum SOC_rel: 1.18 % by VH_ID 651
Mean minimum SOC_rel over all vehicles: 38.79 %
Saving results to csv ...finished.
EV.plot_LC_powers_parts_res_output(res["output"], "0");

MILP_Assigned_PeakLoad + ESS

file_analysis = "data/private/vbz/output/KR_MILP_Assigned_PeakLoad_ESS/analysis_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(file_analysis);
analysis["algorithm"]["parameters"]["solver"] = "HiGHS";  # Cbc, Gurobi, HiGHS
data, aux = EV.generate_data_and_aux(analysis);
res = EV.apply_algorithm(data, aux, analysis);
Loading analysis file ... finished.
Loading csv data ... finished.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
No data config input overwrites found.
Making auxiliary tables ... finished.
Applying algo MILP:
  Computing results ...
    - using given VH2CP assignments ... 
    - building optimization model ... finished.
    - optimizing with solver HiGHS ... finished in 0.21 seconds
      status: OPTIMAL
      optimal value = 408.86
      finished.
  Saving analysis.json ... finished.
EV.plot_power_res_output(res["output"], "locations_active_powers")
EV.analyse_objectives(analysis, aux, res)
EV.save2csv_res_output(analysis, res["output"])
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.409 MW
- charging:   0.880 MW
- total:      0.409 MW
costs at location 0:
- baseload:       0.00 EUR
- ESS:          552.26 EUR
- charging:    1559.97 EUR
- total   :    1130.26 EUR
energies at location 0:
- baseload:      0.000 MWh
- ESS:           0.000 MWh
- charging:      7.990 MWh
- total   :      7.990 MWh
No vehicle is broke down.
Minimum SOC_rel: 32.69 % by VH_ID 652
Mean minimum SOC_rel over all vehicles: 50.54 %
Saving results to csv ...finished.
EV.plot_power_res_output(res["output"], "locations_powers")
EV.plot_power_res_output(res["output"], "locations_ESS_powers")

Kostenminimierung

MILP_Assigned_Cost

Zero Power Prices

file_analysis = "data/private/vbz/output/KR_MILP_Assigned_Cost/analysis_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(file_analysis);
analysis["algorithm"]["parameters"]["solver"] = "HiGHS";  # Cbc, Gurobi, HiGHS
analysis["data config"]["input overwrites"]["prices.csv"]["energy_price_sell"] = 0.03;
analysis["data config"]["input overwrites"]["prices.csv"]["power_price"] = 0.0;
data, aux = EV.generate_data_and_aux(analysis);
Loading analysis file ... finished.
Loading csv data ... finished.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Overwriting in prices.csv energy_price_sell to 0.03
Overwriting in prices.csv power_price to 0.0
Making auxiliary tables ... finished.
EV.plot_prices(aux["prices"])
res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:
  Computing results ...
    - using given VH2CP assignments ... 
    - building optimization model ... finished.
    - optimizing with solver HiGHS ... finished in 0.22 seconds
      status: OPTIMAL
      optimal value = 559.05
      finished.
  Saving analysis.json ... finished.
EV.plot_power_res_output(res["output"], "locations_active_powers")
EV.analyse_objectives(analysis, aux, res)
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.000 MW
- charging:   3.070 MW
- total:      3.070 MW
costs at location 0:
- baseload:       0.00 EUR
- ESS:            0.00 EUR
- charging:     559.05 EUR
- total   :     559.05 EUR
energies at location 0:
- baseload:      0.000 MWh
- ESS:           0.000 MWh
- charging:      7.990 MWh
- total   :      7.990 MWh
No vehicle is broke down.
Minimum SOC_rel: 1.18 % by VH_ID 651
Mean minimum SOC_rel over all vehicles: 45.00 %

Non-Zero Power Prices

analysis["data config"]["input overwrites"]["prices.csv"]["power_price"] = 10.0;
data, aux = EV.generate_data_and_aux(analysis);
res = EV.apply_algorithm(data, aux, analysis);
EV.plot_power_res_output(res["output"], "locations_active_powers")
EV.analyse_objectives(analysis, aux, res)
EV.save2csv_res_output(analysis, res["output"])
Loading csv data ... finished.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Overwriting in prices.csv energy_price_sell to 0.03
Overwriting in prices.csv power_price to 10.0
Making auxiliary tables ... finished.
Applying algo MILP:
  Computing results ...
    - using given VH2CP assignments ... 
    - building optimization model ... finished.
    - optimizing with solver HiGHS ... finished in 0.41 seconds
      status: OPTIMAL
      optimal value = 813.08
      finished.
  Saving analysis.json ... finished.
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.000 MW
- charging:   0.543 MW
- total:      0.543 MW
costs at location 0:
- baseload:       0.00 EUR
- ESS:            0.00 EUR
- charging:     813.08 EUR
- total   :     813.08 EUR
energies at location 0:
- baseload:      0.000 MWh
- ESS:           0.000 MWh
- charging:      7.990 MWh
- total   :      7.990 MWh
No vehicle is broke down.
Minimum SOC_rel: 32.69 % by VH_ID 652
Mean minimum SOC_rel over all vehicles: 50.54 %
Saving results to csv ...finished.

MILP_Assigned_Cost + ESS

file_analysis = "data/private/vbz/output/KR_MILP_Assigned_Cost_ESS/analysis_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(file_analysis);
analysis["algorithm"]["parameters"]["solver"] = "HiGHS";  # Cbc, Gurobi, HiGHS
analysis["data config"]["input overwrites"]["prices.csv"]["energy_price_sell"] = 0.03;
analysis["data config"]["input overwrites"]["prices.csv"]["power_price"] = 10.0;  # 0.0
data, aux = EV.generate_data_and_aux(analysis);
res = EV.apply_algorithm(data, aux, analysis);
Loading analysis file ... finished.
Loading csv data ... finished.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Overwriting in prices.csv energy_price_sell to 0.03
Overwriting in prices.csv power_price to 10.0
Making auxiliary tables ... finished.
Applying algo MILP:
  Computing results ...
    - using given VH2CP assignments ... 
    - building optimization model ... finished.
    - optimizing with solver HiGHS ... finished in 0.23 seconds
      status: OPTIMAL
      optimal value = 795.39
      finished.
  Saving analysis.json ... finished.
EV.plot_power_res_output(res["output"], "locations_active_powers");
EV.analyse_objectives(analysis, aux, res);
EV.save2csv_res_output(analysis, res["output"]);
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.500 MW
- charging:   0.880 MW
- total:      0.512 MW
costs at location 0:
- baseload:       0.00 EUR
- ESS:          218.18 EUR
- charging:     940.24 EUR
- total   :     795.39 EUR
energies at location 0:
- baseload:      0.000 MWh
- ESS:          -0.000 MWh
- charging:      7.990 MWh
- total   :      7.990 MWh
No vehicle is broke down.
Minimum SOC_rel: 32.69 % by VH_ID 652
Mean minimum SOC_rel over all vehicles: 50.54 %
Saving results to csv ...finished.

MILP_Assigned_Cost + ESS + Baseload

file_analysis = "data/private/vbz/output/KR_MILP_Assigned_Cost_ESS_Baseload/analysis_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(file_analysis);
analysis["algorithm"]["parameters"]["solver"] = "HiGHS";  # Cbc, Gurobi, HiGHS
analysis["data config"]["input overwrites"]["prices.csv"]["energy_price_sell"] = 0.03;
analysis["data config"]["input overwrites"]["prices.csv"]["power_price"] = 10.0;  # 0.0
data, aux = EV.generate_data_and_aux(analysis);
Loading analysis file ... finished.
Loading csv data ... 
  Loading overwrite file locations_active_baseloads_synth.csv for locations_active_baseloads ... finished.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Overwriting in prices.csv energy_price_sell to 0.03
Overwriting in prices.csv power_price to 10.0
Making auxiliary tables ... finished.
res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:
  Computing results ...
    - using given VH2CP assignments ... 
    - building optimization model ... finished.
    - optimizing with solver HiGHS ... finished in 0.21 seconds
      status: OPTIMAL
      optimal value = 4326.72
      finished.
  Saving analysis.json ... finished.
EV.plot_LC_powers_parts_res_output(res["output"], "0");
EV.analyse_objectives(analysis, aux, res);
EV.save2csv_res_output(analysis, res["output"]);
peak active powers at location 0:
- baseload:   2.350 MW
- ESS:        0.500 MW
- charging:   1.514 MW
- total:      2.064 MW
costs at location 0:
- baseload:    3847.91 EUR
- ESS:          234.55 EUR
- charging:    1093.38 EUR
- total   :    4326.72 EUR
energies at location 0:
- baseload:     37.038 MWh
- ESS:           0.000 MWh
- charging:      7.990 MWh
- total   :     45.028 MWh
No vehicle is broke down.
Minimum SOC_rel: 22.92 % by VH_ID 637
Mean minimum SOC_rel over all vehicles: 48.56 %
Saving results to csv ...finished.

MILP_Assigned_Cost + PV

file_analysis = "data/private/vbz/output/KR_MILP_Assigned_Cost_PV/analysis_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(file_analysis);
analysis["algorithm"]["parameters"]["solver"] = "HiGHS";  # Cbc, Gurobi, HiGHS
analysis["data config"]["input overwrites"]["prices.csv"]["energy_price_sell"] = 0.03;
analysis["data config"]["input overwrites"]["prices.csv"]["power_price"] = 10.0;  # 0.0
data, aux = EV.generate_data_and_aux(analysis);
Loading analysis file ... finished.
Loading csv data ... 
  Loading overwrite file locations_active_baseloads_synth_PV.csv for locations_active_baseloads ... finished.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Overwriting in prices.csv energy_price_sell to 0.03
Overwriting in prices.csv power_price to 10.0
Making auxiliary tables ... finished.
res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:
  Computing results ...
    - using given VH2CP assignments ... 
    - building optimization model ... finished.
    - optimizing with solver HiGHS ... finished in 0.21 seconds
      status: OPTIMAL
      optimal value = 579.82
      finished.
  Saving analysis.json ... finished.
EV.plot_LC_powers_parts_res_output(res["output"], "0");
EV.analyse_objectives(analysis, aux, res);
EV.save2csv_res_output(analysis, res["output"]);
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.000 MW
- charging:   0.663 MW
- total:      0.543 MW
costs at location 0:
- baseload:    -114.00 EUR
- ESS:            0.00 EUR
- charging:     872.11 EUR
- total   :     579.82 EUR
energies at location 0:
- baseload:     -3.800 MWh
- ESS:           0.000 MWh
- charging:      7.990 MWh
- total   :      4.190 MWh
No vehicle is broke down.
Minimum SOC_rel: 32.69 % by VH_ID 652
Mean minimum SOC_rel over all vehicles: 50.54 %
Saving results to csv ...finished.