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
path_project   = "/home/kr/forschung/projects/FreeE-Bus/"
path_system    = "data/work/system_public/"
path_jl_envnmt = "code/julia/current/"

cd(path_project)     # make path_project the working directory
using OhMyREPL, Revise, Pkg, Dates, DataFrames, CSV, Plots
Pkg.activate(path_jl_envnmt)
import ElectricVehicles as EV
  Activating project at `~/forschung/projects/FreeE-Bus/code/julia/current`

Spitzenlastreduktion

Simulation

Ego-Infra als Vergleichsbasis

# load and check data:
file_analysis = "output/kr_ego_infra/analysis_input_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(path_project, path_system, file_analysis, verbose=true);
data, aux = EV.generate_data_and_aux(analysis);
Loading analysis file ... finshed.
Loading csv data ... 
  Loading overwrite file locations_with_ESS.csv for locations ... 
  Loading overwrite file missing for locations_active_baseloads ... finshed.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Selected given schedules.
Making auxiliary tables ... finished.
# apply algorithm ego-infra:
analysis["algorithm"]["name"] = "ego_infra"
analysis["write analysis.json"] = true;
res = EV.apply_algorithm(data, aux, analysis);
Applying algo ego_infra:

  Computing results ...  finished.

  Saving analysis.json ... finished.
# plot results: location power
EV.plot_power_res_output(res["output"], "locations_powers", display_plot=true);
# 15-minutes averaged power:
EV.plot_power_res_output(res["output"], "locations_active_powers", display_plot=true);
# analyze results:
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:
EV.save2csv_res_output(analysis, res["output"], "locations_powers");
EV.save2csv_res_output(analysis, res["output"], "locations_charging_powers");
EV.save2csv_res_output(analysis, res["output"], "locations_charging_powers");
EV.save2csv_res_output(analysis, res["output"], "locations_active_powers");
EV.save2csv_res_output(analysis, res["output"], "locations_active_baseloads");
EV.save2csv_res_output(analysis, res["output"], "vehicles_charging_powers");
EV.save2csv_res_output(analysis, res["output"], "charging_stations_powers");
EV.save2csv_res_output(analysis, res["output"], "charging_points_powers");
EV.save2csv_res_output(analysis, res["output"], "vehicles_2_locations");
EV.save2csv_res_output(analysis, res["output"], "vehicles_2_charging_stations");
EV.save2csv_res_output(analysis, res["output"], "vehicles_2_charging_points");
EV.save2csv_res_output(analysis, res["output"], "vehicles_soc_abs");
EV.save2csv_res_output(analysis, res["output"], "vehicles_soc_rel");

MILP

# load and check data:
file_analysis = "output/kr_milp_peak_power/analysis_input_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(path_project, path_system, file_analysis, verbose=true);
data, aux = EV.generate_data_and_aux(analysis);
Loading analysis file ... finshed.
Loading csv data ... 
  Loading overwrite file locations_with_ESS.csv for locations ... 
  Loading overwrite file missing for locations_active_baseloads ... finshed.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Selected given schedules.
Making auxiliary tables ... finished.
# configure and apply algorithm MILP:
analysis["algorithm"]["parameters"]["objective"] = "minimize peak power"
analysis["algorithm"]["parameters"]["solver"] = "Cbc"  # Cbc, Gurobi, HiGHS
analysis["algorithm"]["parameters"]["time limit (sec)"] = 60;
analysis["write analysis.json"] = true;

res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:

  Computing results ...

    - using given VH2CP assignments ... 

    - building optimization model ... finished.

    - optimizing with solver Cbc ... finished in 3.42 seconds

      status: OPTIMAL

      optimal value = 434.03

      finished.

  Saving analysis.json ... finished.

Presolve 314 (-312883) rows, 2582 (-15549) columns and 6455 (-52209) elements

Perturbing problem by 0.001% of 0.25819889 - largest nonzero change 0.00080818575 ( 0.31300899%) - largest zero change 0.00010019088

0  Obj 1.5904188 Primal inf 90618.737 (54)

81  Obj 6.5211549 Primal inf 287630.89 (128)

140  Obj 367.86914 Primal inf 60960.301 (124)

194  Obj 413.86521 Primal inf 37983.548 (97)

253  Obj 441.10255 Primal inf 19866.291 (78)

334  Obj 441.79862 Primal inf 5094.4877 (38)

389  Obj 441.80762

Optimal - objective value 434.02652

After Postsolve, objective 434.02652, infeasibilities - dual 0 (0), primal 0 (0)

Optimal objective 434.0265235 - 389 iterations time 0.192, Presolve 0.18
# plot results:
EV.plot_power_res_output(res["output"], "locations_active_powers", display_plot=true);
# analyze results:
EV.analyse_objectives(analysis, aux, res)
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:    1116.55 EUR
- total   :    1116.55 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 %
# save results to csv:
EV.save2csv_res_output(analysis, res["output"], "locations_powers");
EV.save2csv_res_output(analysis, res["output"], "locations_active_powers");
EV.save2csv_res_output(analysis, res["output"], "locations_charging_powers");
EV.save2csv_res_output(analysis, res["output"], "locations_active_baseloads");
EV.save2csv_res_output(analysis, res["output"], "vehicles_soc_abs");
EV.save2csv_res_output(analysis, res["output"], "vehicles_soc_rel");
EV.save2csv_res_output(analysis, res["output"], "charging_points_powers");

Vergleich: Simulation - Heuristik - MILP

file_paths = Dict(
    # "sim_bado" => joinpath(path_system, "output/bado_ego_infra_lb/vbz_02_d37v_1d/locations_active_powers.csv"),
    "simulation" => joinpath(path_system, "output/kr_ego_infra/vbz_02_d37v_1d/locations_active_powers.csv"),
    "heuristic" => joinpath(path_system, "output/bado_heuristics_eb/vbz_02_d37v_1d/locations_active_powers.csv"),
    "MILP" => joinpath(path_system, "output/kr_milp_peak_power/vbz_02_d37v_1d/locations_active_powers.csv")
    )
EV.plot_LC_powers_comparison(file_paths)

MILP mit opt. Ladepunktzuweisung

# load and check data:
file_analysis = "output/kr_milp_peak_power_CP-opt/analysis_input_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(path_project, path_system, file_analysis, verbose=true);
data, aux = EV.generate_data_and_aux(analysis);
Loading analysis file ... finshed.
Loading csv data ... 
  Loading overwrite file locations_with_ESS.csv for locations ... 
  Loading overwrite file missing for locations_active_baseloads ... finshed.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Selected given schedules.
Making auxiliary tables ... finished.
# configure and apply algorithm MILP:
analysis["algorithm"]["parameters"]["objective"] = "minimize peak power"
analysis["algorithm"]["parameters"]["solver"] = "Gurobi"  # Cbc, Gurobi, HiGHS
analysis["algorithm"]["parameters"]["time limit (sec)"] = 3*60;
analysis["write analysis.json"] = true;

res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:

  Computing results ...

    - building optimization model ... Set parameter Username

Set parameter LicenseID to value 2737330

Academic license - for non-commercial use only - expires 2026-11-13

finished.

    - optimizing with solver Gurobi ... finished in 34.17 seconds

      status: OPTIMAL

      optimal value = 434.03

      finished.

  Saving analysis.json ... finished.
# plot results:
EV.plot_power_res_output(res["output"], "locations_active_powers", display_plot=true);
# analyze results:
EV.analyse_objectives(analysis, aux, res)
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:    1117.94 EUR
- total   :    1117.94 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 %
# save results to csv:
EV.save2csv_res_output(analysis, res["output"], "locations_powers");
EV.save2csv_res_output(analysis, res["output"], "locations_active_powers");
EV.save2csv_res_output(analysis, res["output"], "locations_charging_powers");
EV.save2csv_res_output(analysis, res["output"], "locations_active_baseloads");
EV.save2csv_res_output(analysis, res["output"], "vehicles_soc_abs");
EV.save2csv_res_output(analysis, res["output"], "vehicles_soc_rel");
EV.save2csv_res_output(analysis, res["output"], "charging_points_powers");

MILP mit ESS

# load and check data:
file_analysis = "output/kr_milp_peak_power_ESS/analysis_input_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(path_project, path_system, file_analysis, verbose=true);
data, aux = EV.generate_data_and_aux(analysis);
Loading analysis file ... finshed.
Loading csv data ... 
  Loading overwrite file locations_with_ESS.csv for locations ... 
  Loading overwrite file missing for locations_active_baseloads ... finshed.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Selected given schedules.
Making auxiliary tables ... finished.
# configure and apply algorithm MILP:
analysis["algorithm"]["parameters"]["objective"] = "minimize peak power"
analysis["algorithm"]["parameters"]["solver"] = "Cbc"  # Cbc, Gurobi, HiGHS
analysis["algorithm"]["parameters"]["time limit (sec)"] = 60;
analysis["write analysis.json"] = true;

res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:

  Computing results ...

    - using given VH2CP assignments ... 

    - building optimization model ... finished.

    - optimizing with solver Cbc ... finished in 0.33 seconds

      status: OPTIMAL

      optimal value = 387.77

      finished.

  Saving analysis.json ... finished.

Presolve 511 (-313081) rows, 2961 (-15563) columns and 7226 (-52421) elements

Perturbing problem by 0.001% of 0.25819889 - largest nonzero change 0.00080818575 ( 0.31300899%) - largest zero change 0.00010019088

0  Obj 1.6855479 Primal inf 170871.34 (238)

85  Obj 5.5728604 Primal inf 82531.242 (221)

170  Obj 6.1013478 Primal inf 77684.93 (223)

255  Obj 257.74763 Primal inf 80395.306 (203)

340  Obj 267.4738 Primal inf 131670.63 (188)

425  Obj 268.36529 Primal inf 178395.4 (193)

510  Obj 365.86342 Primal inf 57370.754 (154)

595  Obj 395.87405 Primal inf 81223.995 (124)

680  Obj 408.40017 Primal inf 92307.154 (112)

765  Obj 412.22553 Primal inf 12069.811 (42)

822  Obj 412.90458

Optimal - objective value 387.76701

After Postsolve, objective 387.76701, infeasibilities - dual 0 (0), primal 0 (0)

Optimal objective 387.7670142 - 822 iterations time 0.092, Presolve 0.08
# plot results:
EV.plot_power_res_output(res["output"], "locations_active_powers", display_plot=true);
# analyze results:
EV.analyse_objectives(analysis, aux, res)
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.388 MW
- charging:   1.171 MW
- total:      0.388 MW
costs at location 0:
- baseload:       0.00 EUR
- ESS:          766.04 EUR
- charging:    1843.56 EUR
- total   :    1238.43 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 %
# plot results:

col_names = ["start_time", "0"]
ch = res["output"]["locations_charging_powers"][:, col_names]
es = res["output"]["locations_ESS_powers"][:, col_names]
to = res["output"]["locations_active_powers"][:, col_names]
times = res["output"]["locations_powers"][:, :start_time]
time_start = floor(minimum(times), Hour(1))
time_end =   ceil(maximum(times), Hour(1))
ticks = time_start:Hour(1):time_end

# legend = false
legend = :bottom      
plt = plot(size=(600, 400), xticks=ticks)
plot!(plt, es[:,1], es[:,2], linewidth=2,    
    linecolor=:brown, xrot=30, grid=:on, fmt=:svg, left_margin=5Plots.mm, bottom_margin=10Plots.mm, seriestype=:steppost, legend=legend, label="ES")
plot!(plt, to[:,1], to[:,2], linewidth=2,    
    linecolor=:blue, xrot=30, grid=:on, fmt=:svg, left_margin=5Plots.mm, bottom_margin=10Plots.mm, seriestype=:steppost, legend=legend, label="total")
xt = xticks(plt)
# ticks_format = "dd HH:MM"
ticks_format = "HH:MM"
xticks!(plt, xt[1][1], Dates.format.(DateTime.(xt[1][2]), ticks_format))
xaxis!(plt, rotation=45)
xlabel!(plt, "time")
ylabel!(plt, "power (kW)")
res["output"]
Dict{Any, Any} with 11 entries:
  "locations_charging_powers"  => 197×2 DataFrame…
  "locations_ESS_energy_rel"   => 197×2 DataFrame…
  "locations_active_powers"    => 98×2 DataFrame…
  "locations_active_baseloads" => 197×2 DataFrame…
  "locations_ESS_energy_abs"   => 197×2 DataFrame…
  "charging_points_powers"     => 197×71 DataFrame…
  "vehicles_soc_rel"           => 197×38 DataFrame…
  "vehicles_soc_abs"           => 197×38 DataFrame…
  "locations_ESS_powers"       => 197×2 DataFrame…
  "prices"                     => 197×4 DataFrame…
  "locations_powers"           => 197×2 DataFrame

MILP mit Baseload

# load and check data:
file_analysis = "output/kr_milp_peak_power_baseload/analysis_input_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(path_project, path_system, file_analysis, verbose=true);
data, aux = EV.generate_data_and_aux(analysis);
Loading analysis file ... finshed.
Loading csv data ... 
  Loading overwrite file locations_with_ESS.csv for locations ... 
  Loading overwrite file locations_active_baseloads_synth.csv for locations_active_baseloads ... finshed.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Selected given schedules.
Making auxiliary tables ... finished.
# configure and apply algorithm MILP:
analysis["algorithm"]["parameters"]["objective"] = "minimize peak power"
analysis["algorithm"]["parameters"]["solver"] = "Cbc"  # Cbc, Gurobi, HiGHS
analysis["algorithm"]["parameters"]["time limit (sec)"] = 60;
analysis["write analysis.json"] = true;

res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:

  Computing results ...

    - using given VH2CP assignments ... 

    - building optimization model ... finished.

    - optimizing with solver Cbc ... finished in 0.55 seconds

      status: OPTIMAL

      optimal value = 2350.00

      finished.

  Saving analysis.json ... finished.

Presolve 311 (-312886) rows, 2572 (-15559) columns and 6432 (-52232) elements

Perturbing problem by 0.001% of 0.25819889 - largest nonzero change 0.00067422627 ( 0.26112671%) - largest zero change 0.00010019088

0  Obj 2357.5437 Primal inf 90465.078 (58)

81  Obj 2361.2271 Primal inf 39267.818 (58)

162  Obj 2361.4285 Primal inf 4585.7108 (42)

212  Obj 2361.4329

Optimal - objective value 2350

After Postsolve, objective 2350, infeasibilities - dual 0 (0), primal 0 (0)

Optimal objective 2350 - 212 iterations time 0.082, Presolve 0.08
# plot results:

col_names = ["start_time", "0"]
bl = res["output"]["locations_active_baseloads"][:, col_names]
ch = res["output"]["locations_charging_powers"][:, col_names]
to = res["output"]["locations_active_powers"][:, col_names]
times = res["output"]["locations_powers"][:, :start_time]
time_start = floor(minimum(times), Hour(1))
time_end =   ceil(maximum(times), Hour(1))
ticks = time_start:Hour(1):time_end

# legend = false
legend = :bottom      
plt = plot(size=(600, 400), xticks=ticks)
plot!(plt, bl[:,1], bl[:,2], linewidth=2,    
    linecolor=:brown, xrot=30, grid=:on, fmt=:svg, left_margin=5Plots.mm, bottom_margin=10Plots.mm, seriestype=:steppost, legend=legend, label="baseload", ls=:dash)
plot!(plt, to[:,1], to[:,2], linewidth=2,    
    linecolor=:blue, xrot=30, grid=:on, fmt=:svg, left_margin=5Plots.mm, bottom_margin=10Plots.mm, seriestype=:steppost, legend=legend, label="total")
xt = xticks(plt)
# ticks_format = "dd HH:MM"
ticks_format = "HH:MM"
xticks!(plt, xt[1][1], Dates.format.(DateTime.(xt[1][2]), ticks_format))
xaxis!(plt, rotation=45)
xlabel!(plt, "time")
ylabel!(plt, "power (kW)")
# analyze results:
EV.analyse_objectives(analysis, aux, res)
peak active powers at location 0:
- baseload:   2.350 MW
- ESS:        0.000 MW
- charging:   1.650 MW
- total:      2.350 MW
costs at location 0:
- baseload:    5391.88 EUR
- ESS:            0.00 EUR
- charging:    2329.21 EUR
- total   :    6095.02 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: 39.37 %
# save results to csv:
EV.save2csv_res_output(analysis, res["output"], "locations_powers");
EV.save2csv_res_output(analysis, res["output"], "locations_active_powers");
EV.save2csv_res_output(analysis, res["output"], "locations_charging_powers");
EV.save2csv_res_output(analysis, res["output"], "locations_active_baseloads");
EV.save2csv_res_output(analysis, res["output"], "vehicles_soc_abs");
EV.save2csv_res_output(analysis, res["output"], "vehicles_soc_rel");
EV.save2csv_res_output(analysis, res["output"], "charging_points_powers");

TODOs

Kostenminimierung

Energiekosten

# load and check data:
file_analysis = "output/kr_milp_energy-costs/analysis_input_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(path_project, path_system, file_analysis, verbose=true);
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);

EV.plot_prices(aux["prices"])
Loading analysis file ... finshed.
Loading csv data ... 
  Loading overwrite file locations_with_ESS.csv for locations ... 
  Loading overwrite file missing for locations_active_baseloads ... finshed.
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
Selected given schedules.
Making auxiliary tables ... finished.
# configure analysis and apply algorithm MILP:
analysis["algorithm"]["parameters"]["objective"] = "minimize costs"
analysis["algorithm"]["parameters"]["solver"] = "Cbc"  # Cbc, Gurobi, HiGHS
analysis["algorithm"]["parameters"]["time limit (sec)"] = 60;
analysis["write analysis.json"] = true;
res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:

  Computing results ...

    - using given VH2CP assignments ... 

    - building optimization model ... finished.

    - optimizing with solver Cbc ... finished in 0.29 seconds

      status: OPTIMAL

      optimal value = 559.05

      finished.

  Saving analysis.json ... finished.

Presolve 506 (-313083) rows, 2796 (-15531) columns and 9422 (-64138) elements

Perturbing problem by 0.001% of 0.04342983 - largest nonzero change 4.9964993e-05 ( 0.48998075%) - largest zero change 4.9947383e-05

0  Obj -15.307724 Primal inf 31268.198 (370)

85  Obj -14.009274 Primal inf 58404.684 (364)

170  Obj 190.32572 Primal inf 61604.323 (334)

255  Obj 262.14556 Primal inf 68882.891 (299)

340  Obj 459.77823 Primal inf 29823.984 (257)

425  Obj 487.30547 Primal inf 22812.402 (221)

510  Obj 542.32442 Primal inf 13239.557 (178)

595  Obj 550.51575 Primal inf 7175.0778 (125)

680  Obj 561.03423 Primal inf 213.11334 (48)

710  Obj 561.2477

Optimal - objective value 559.05304

After Postsolve, objective 559.05304, infeasibilities - dual 0 (0), primal 0 (0)

Optimal objective 559.0530413 - 710 iterations time 0.072, Presolve 0.06
# analyze results:
EV.analyse_objectives(analysis, aux, res)
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.000 MW
- charging:   3.970 MW
- total:      3.970 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: 0.71 % by VH_ID 475
Mean minimum SOC_rel over all vehicles: 44.79 %
# 15-minutes averaged power:
EV.plot_power_res_output(res["output"], "locations_active_powers", display_plot=true);

Energie- und Leistungskosten

# load and check data:
file_analysis = "output/kr_milp_costs/analysis_input_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(path_project, path_system, file_analysis, verbose=true);
analysis["data config"]["input overwrites"]["prices.csv"]["energy_price_sell"] = 0.03
analysis["data config"]["input overwrites"]["prices.csv"]["power_price"] = 10 # per month
data, aux = EV.generate_data_and_aux(analysis);

EV.plot_prices(aux["prices"])
Loading analysis file ... finshed.
Loading csv data ... 
  Loading overwrite file locations_with_ESS.csv for locations ... 
  Loading overwrite file missing for locations_active_baseloads ... finshed.
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
Selected given schedules.
Making auxiliary tables ... finished.
# configure analysis and apply algorithm MILP:
analysis["algorithm"]["parameters"]["objective"] = "minimize costs"
analysis["algorithm"]["parameters"]["solver"] = "Cbc"  # Cbc, Gurobi, HiGHS
analysis["algorithm"]["parameters"]["time limit (sec)"] = 60;
analysis["write analysis.json"] = true;
res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:

  Computing results ...

    - using given VH2CP assignments ... 

    - building optimization model ... finished.

    - optimizing with solver Cbc ... finished in 0.36 seconds

      status: OPTIMAL

      optimal value = 813.08

      finished.

  Saving analysis.json ... finished.

Presolve 644 (-312945) rows, 2851 (-15476) columns and 12235 (-61325) elements

Perturbing problem by 0.001% of 0.17937048 - largest nonzero change 0.00081745734 ( 0.46915173%) - largest zero change 0.00010011211

0  Obj -15.293944 Primal inf 31349.982 (370)

87  Obj 91.694836 Primal inf 55186.995 (437)

174  Obj 134.08864 Primal inf 59555.521 (402)

255  Obj 162.09265 Primal inf 52053.997 (379)

311  Obj 296.35472 Primal inf 457685.83 (379)

390  Obj 373.62902 Primal inf 65216.661 (335)

477  Obj 553.87646 Primal inf 44868.081 (303)

564  Obj 628.59314 Primal inf 102130.28 (304)

651  Obj 652.07728 Primal inf 33041.247 (267)

738  Obj 743.11001 Primal inf 26951.387 (207)

825  Obj 797.54011 Primal inf 12321.577 (156)

912  Obj 813.88956 Primal inf 1829.7909 (71)

986  Obj 817.61598

Optimal - objective value 813.08152

After Postsolve, objective 813.08152, infeasibilities - dual 0 (0), primal 0 (0)

Optimal objective 813.0815236 - 986 iterations time 0.102, Presolve 0.08
# analyze results:
EV.analyse_objectives(analysis, aux, res)
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 %
# 15-minutes averaged power:
EV.plot_power_res_output(res["output"], "locations_active_powers", display_plot=true);

Energie- und Leistungskosten mit opt. Ladepunktzuweisung

# load and check data:
file_analysis = "output/kr_milp_costs_CP-opt/analysis_input_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(path_project, path_system, file_analysis, verbose=true);
analysis["data config"]["input overwrites"]["prices.csv"]["energy_price_sell"] = 0.03
analysis["data config"]["input overwrites"]["prices.csv"]["power_price"] = 10 # per month
data, aux = EV.generate_data_and_aux(analysis);
# EV.plot_prices(aux["prices"])
Loading analysis file ... finshed.
Loading csv data ... 
  Loading overwrite file locations_with_ESS.csv for locations ... 
  Loading overwrite file missing for locations_active_baseloads ... finshed.
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
Selected given schedules.
Making auxiliary tables ... finished.
# configure analysis and apply algorithm MILP:
analysis["algorithm"]["parameters"]["objective"] = "minimize costs"
analysis["algorithm"]["parameters"]["solver"] = "Gurobi"  # Cbc, Gurobi, HiGHS
analysis["algorithm"]["parameters"]["time limit (sec)"] = 3*60;
analysis["write analysis.json"] = true;
res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:

  Computing results ...

    - building optimization model ... Set parameter Username

Set parameter LicenseID to value 2737330

Academic license - for non-commercial use only - expires 2026-11-13

finished.

    - optimizing with solver Gurobi ... finished in 37.21 seconds

      status: OPTIMAL

      optimal value = 813.08

      finished.

  Saving analysis.json ... finished.

Energie- und Leistungskosten mit ESS

# load and check data:
file_analysis = "output/kr_milp_costs_ESS/analysis_input_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(path_project, path_system, file_analysis, verbose=true);
analysis["data config"]["input overwrites"]["prices.csv"]["energy_price_sell"] = 0.03
analysis["data config"]["input overwrites"]["prices.csv"]["power_price"] = 10 # per month
data, aux = EV.generate_data_and_aux(analysis);
# EV.plot_prices(aux["prices"])
Loading analysis file ... finshed.
Loading csv data ... 
  Loading overwrite file locations_with_ESS.csv for locations ... 
  Loading overwrite file missing for locations_active_baseloads ... finshed.
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
Selected given schedules.
Making auxiliary tables ... finished.
# configure analysis and apply algorithm MILP:
analysis["algorithm"]["parameters"]["objective"] = "minimize costs"
analysis["algorithm"]["parameters"]["solver"] = "Cbc"  # Cbc, Gurobi, HiGHS
analysis["algorithm"]["parameters"]["time limit (sec)"] = 60;
analysis["write analysis.json"] = true;
res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:

  Computing results ...

    - using given VH2CP assignments ... 

    - building optimization model ... finished.

    - optimizing with solver Cbc ... finished in 0.35 seconds

      status: OPTIMAL

      optimal value = 780.10

      finished.

  Saving analysis.json ... finished.

Presolve 917 (-313067) rows, 3268 (-15452) columns and 13474 (-61461) elements

Perturbing problem by 0.001% of 0.17937048 - largest nonzero change 0.00081745734 ( 0.48392368%) - largest zero change 0.00010011211

0  Obj -739.4043 Primal inf 88221.018 (434)

93  Obj -737.66916 Primal inf 74981.496 (458)

186  Obj -736.52169 Primal inf 237092.78 (500)

279  Obj -543.8154 Primal inf 349500.77 (534)

372  Obj -432.45157 Primal inf 375416.81 (513)

465  Obj -344.24038 Primal inf 193242.99 (541)

558  Obj -300.20131 Primal inf 4065061.4 (564)

637  Obj -224.10099 Primal inf 958475.28 (528)

730  Obj -171.6655 Primal inf 232562.01 (487)

823  Obj -148.11832 Primal inf 191628.06 (458)

916  Obj -27.417744 Primal inf 7284755.4 (456)

1009  Obj 283.03961 Primal inf 243051.77 (423)

1102  Obj 413.24023 Primal inf 98445.329 (337)

1195  Obj 556.62632 Primal inf 347822.14 (326)

1288  Obj 601.49756 Primal inf 305019.19 (325)

1381  Obj 614.33814 Primal inf 353446.41 (314)

1474  Obj 619.39043 Primal inf 93152.697 (247)

1567  Obj 691.97282 Primal inf 500860.3 (263)

1660  Obj 712.54187 Primal inf 27134.871 (189)

1753  Obj 753.46802 Primal inf 474422.73 (238)

1846  Obj 764.69596 Primal inf 16489.165 (165)

1939  Obj 790.15797 Primal inf 421633.22 (223)

2032  Obj 793.2451 Primal inf 401573.29 (209)

2125  Obj 796.28612 Primal inf 3597.4882 (66)

2209  Obj 797.69141

Optimal - objective value 780.09625

After Postsolve, objective 780.09625, infeasibilities - dual 0 (0), primal 0 (0)

Optimal objective 780.0962463 - 2209 iterations time 0.132, Presolve 0.08
# analyze results:
EV.analyse_objectives(analysis, aux, res)
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.480 MW
- charging:   0.786 MW
- total:      0.480 MW
costs at location 0:
- baseload:       0.00 EUR
- ESS:          283.38 EUR
- charging:     940.59 EUR
- total   :     780.10 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 %
# 15-minutes averaged power:
EV.plot_power_res_output(res["output"], "locations_active_powers", display_plot=true);

Energie- und Leistungskosten mit ESS und PV

# load and check data:
file_analysis = "output/kr_milp_costs_ESS-PV/analysis_input_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(path_project, path_system, file_analysis, verbose=true);
analysis["data config"]["input overwrites"]["prices.csv"]["energy_price_sell"] = 0.03
analysis["data config"]["input overwrites"]["prices.csv"]["power_price"] = 10 # per month
data, aux = EV.generate_data_and_aux(analysis);

EV.plot_baseloads(aux["locations_active_baseloads"])
Loading analysis file ... finshed.
Loading csv data ... 
  Loading overwrite file locations_with_ESS.csv for locations ... 
  Loading overwrite file locations_active_baseloads_synth_PV.csv for locations_active_baseloads ... finshed.
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
Selected given schedules.
Making auxiliary tables ... finished.
# configure analysis and apply algorithm MILP:
analysis["algorithm"]["parameters"]["objective"] = "minimize costs"
analysis["algorithm"]["parameters"]["solver"] = "Cbc"  # Cbc, Gurobi, HiGHS
analysis["algorithm"]["parameters"]["time limit (sec)"] = 60;
analysis["write analysis.json"] = true;
res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:

  Computing results ...

    - using given VH2CP assignments ... 

    - building optimization model ... finished.

    - optimizing with solver Cbc ... finished in 0.31 seconds

      status: OPTIMAL

      optimal value = 530.92

      finished.

  Saving analysis.json ... finished.

Presolve 917 (-313067) rows, 3268 (-15452) columns and 13474 (-61461) elements

Perturbing problem by 0.001% of 0.17937048 - largest nonzero change 0.00081745734 ( 0.48392368%) - largest zero change 0.00010011211

0  Obj -853.55083 Primal inf 88221.018 (434)

93  Obj -851.81569 Primal inf 73059.819 (454)

186  Obj -850.66982 Primal inf 233193.81 (488)

279  Obj -626.04628 Primal inf 368832.49 (503)

372  Obj -543.98345 Primal inf 217527.1 (481)

465  Obj -423.38 Primal inf 274290.93 (488)

558  Obj -382.61425 Primal inf 209612.41 (462)

651  Obj -207.96318 Primal inf 167993.6 (428)

744  Obj -15.086305 Primal inf 238125.03 (391)

833  Obj 95.926695 Primal inf 50047.313 (310)

926  Obj 215.01946 Primal inf 739207.64 (318)

1019  Obj 299.29267 Primal inf 36963.654 (217)

1108  Obj 411.02909 Primal inf 496342.01 (256)

1201  Obj 427.64045 Primal inf 22914.225 (162)

1289  Obj 524.06945 Primal inf 27868.163 (130)

1382  Obj 546.93598 Primal inf 1010.4578 (21)

1416  Obj 547.35414

Optimal - objective value 530.91856

After Postsolve, objective 530.91856, infeasibilities - dual 0 (0), primal 0 (0)

Optimal objective 530.918558 - 1416 iterations time 0.112, Presolve 0.08
# analyze results:
EV.analyse_objectives(analysis, aux, res)
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.480 MW
- charging:   0.786 MW
- total:      0.480 MW
costs at location 0:
- baseload:    -114.00 EUR
- ESS:          273.27 EUR
- charging:     940.64 EUR
- total   :     530.92 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 %

Energiekosten mit SOC-Nebenbedingung

# load and check data:
file_analysis = "output/kr_milp_energy-costs-soc/analysis_input_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(path_project, path_system, file_analysis, verbose=true);
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 ... finshed.
Loading csv data ... 
  Loading overwrite file locations_with_ESS.csv for locations ... 
  Loading overwrite file missing for locations_active_baseloads ... finshed.
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
Selected given schedules.
Making auxiliary tables ... finished.
# configure analysis and apply algorithm MILP:
analysis["algorithm"]["parameters"]["objective"] = "minimize costs"
analysis["algorithm"]["parameters"]["solver"] = "Cbc"  # Cbc, Gurobi, HiGHS
analysis["algorithm"]["parameters"]["time limit (sec)"] = 60;
analysis["write analysis.json"] = true;
res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:

  Computing results ...

    - using given VH2CP assignments ... 

    - building optimization model ... finished.

    - optimizing with solver Cbc ... finished in 0.3 seconds

      status: OPTIMAL

      optimal value = 559.05

      finished.

  Saving analysis.json ... finished.

Presolve 583 (-313006) rows, 2873 (-15454) columns and 9576 (-63984) elements

Perturbing problem by 0.001% of 0.04342983 - largest nonzero change 4.9885751e-05 ( 0.48131823%) - largest zero change 4.9884369e-05

0  Obj -14.678499 Primal inf 28914.349 (371)

86  Obj -13.377426 Primal inf 62038.108 (364)

172  Obj 170.86014 Primal inf 62665.764 (343)

258  Obj 244.44775 Primal inf 36637.107 (311)

344  Obj 279.7424 Primal inf 43258.306 (300)

430  Obj 408.66342 Primal inf 34466.25 (266)

516  Obj 467.18068 Primal inf 26877.847 (230)

602  Obj 530.13802 Primal inf 18568.428 (179)

688  Obj 552.76569 Primal inf 6929.9116 (131)

774  Obj 562.15796 Primal inf 583.86042 (51)

817  Obj 562.46603

Optimal - objective value 559.05304

After Postsolve, objective 559.05304, infeasibilities - dual 0 (0), primal 0 (0)

Optimal objective 559.0530413 - 817 iterations time 0.082, Presolve 0.08
# analyze results:
EV.analyse_objectives(analysis, aux, res)
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.000 MW
- charging:   4.102 MW
- total:      4.102 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: 20.00 % by VH_ID 651
Mean minimum SOC_rel over all vehicles: 45.61 %

TODOs

  • mit/ohne Baseload
  • mit/ohne PV
  • mit/ohne ESS

Geg. vs Opt. Ladepunktzuweisung

Gegebene Ladepunktzuweisung

# load and check data:
file_analysis = "output/kr_milp_peak_power-small/analysis_input_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(path_project, path_system, file_analysis, verbose=true);
analysis["data config"]["input overwrites"]["prices.csv"]["energy_price_sell"] = 0.03
analysis["data config"]["input overwrites"]["prices.csv"]["power_price"] = 10 # per month
data, aux = EV.generate_data_and_aux(analysis);
Loading analysis file ... finshed.
Loading csv data ... 
  Loading overwrite file locations_with_ESS.csv for locations ... 
  Loading overwrite file missing for locations_active_baseloads ... finshed.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Overwriting charging_power_max in locations.csv finished.
Overwriting in prices.csv energy_price_sell to 0.03
Overwriting in prices.csv power_price to 10.0
Selected given schedules.
Making auxiliary tables ... finished.
CS_p_max = 300.0
aux["charging_station_ID2charging_power_max"] = Dict(
    "1" => CS_p_max, "2" => CS_p_max, "3" => CS_p_max, 
    "4" => CS_p_max, "5" => CS_p_max, "6" => CS_p_max)
Dict{String, Float64} with 6 entries:
  "4" => 300.0
  "1" => 300.0
  "5" => 300.0
  "2" => 300.0
  "6" => 300.0
  "3" => 300.0
# configure and apply algorithm MILP:
analysis["algorithm"]["parameters"]["objective"] = "minimize costs"
analysis["algorithm"]["parameters"]["solver"] = "Gurobi"  # Cbc, Gurobi, HiGHS
analysis["algorithm"]["parameters"]["use given VH2CP assignments"] = true
analysis["algorithm"]["parameters"]["time limit (sec)"] = 3*60;
analysis["write analysis.json"] = true;

res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:

  Computing results ...

    - using given VH2CP assignments ... 

    - building optimization model ... Set parameter Username

Set parameter LicenseID to value 2737330

Academic license - for non-commercial use only - expires 2026-11-13

finished.

    - optimizing with solver Gurobi ... finished in 0.44 seconds

      status: OPTIMAL

      optimal value = 817.26

      finished.

  Saving analysis.json ... finished.
# analyze results:
EV.analyse_objectives(analysis, aux, res)
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.000 MW
- charging:   0.500 MW
- total:      0.500 MW
costs at location 0:
- baseload:       0.00 EUR
- ESS:            0.00 EUR
- charging:     817.26 EUR
- total   :     817.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 %

Optimierte Ladepunktzuweisung

# load and check data:
file_analysis = "output/kr_milp_peak_power-small/analysis_input_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(path_project, path_system, file_analysis, verbose=true);
analysis["data config"]["input overwrites"]["prices.csv"]["energy_price_sell"] = 0.03
analysis["data config"]["input overwrites"]["prices.csv"]["power_price"] = 10 # per month
data, aux = EV.generate_data_and_aux(analysis);
Loading analysis file ... finshed.
Loading csv data ... 
  Loading overwrite file locations_with_ESS.csv for locations ... 
  Loading overwrite file missing for locations_active_baseloads ... finshed.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Overwriting charging_power_max in locations.csv finished.
Overwriting in prices.csv energy_price_sell to 0.03
Overwriting in prices.csv power_price to 10.0
Selected given schedules.
Making auxiliary tables ... finished.
CS_p_max = 300.0
aux["charging_station_ID2charging_power_max"] = Dict(
    "1" => CS_p_max, "2" => CS_p_max, "3" => CS_p_max, 
    "4" => CS_p_max, "5" => CS_p_max, "6" => CS_p_max)
Dict{String, Float64} with 6 entries:
  "4" => 300.0
  "1" => 300.0
  "5" => 300.0
  "2" => 300.0
  "6" => 300.0
  "3" => 300.0
# configure and apply algorithm MILP:
analysis["algorithm"]["parameters"]["objective"] = "minimize costs"
analysis["algorithm"]["parameters"]["solver"] = "Gurobi"  # Cbc, Gurobi, HiGHS
analysis["algorithm"]["parameters"]["use given VH2CP assignments"] = false 
analysis["algorithm"]["parameters"]["time limit (sec)"] = 3*60;
analysis["write analysis.json"] = true;

res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:

  Computing results ...

    - building optimization model ... Set parameter Username

Set parameter LicenseID to value 2737330

Academic license - for non-commercial use only - expires 2026-11-13

finished.

    - optimizing with solver Gurobi ... finished in 43.29 seconds

      status: OPTIMAL

      optimal value = 815.82

      finished.

  Saving analysis.json ... finished.
# analyze results:
EV.analyse_objectives(analysis, aux, res)
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.000 MW
- charging:   0.500 MW
- total:      0.500 MW
costs at location 0:
- baseload:       0.00 EUR
- ESS:            0.00 EUR
- charging:     815.82 EUR
- total   :     815.82 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 %

Max Min SOC

# load and check data:
file_analysis = "output/kr_milp_min_soc/analysis_input_vbz_02_d37v_1d.json";
analysis = EV.make_analysis(path_project, path_system, file_analysis, verbose=true);
data, aux = EV.generate_data_and_aux(analysis);
Loading analysis file ... finshed.
Loading csv data ... 
  Loading overwrite file locations_with_ESS.csv for locations ... 
  Loading overwrite file missing for locations_active_baseloads ... finshed.
Checking data values ... All currently implemented data values checks passed.
Checking foreign keys (IDs) ... All foreign keys (IDs) checks passed.
Selected given schedules.
Making auxiliary tables ... finished.
# configure analysis and apply algorithm MILP:
analysis["algorithm"]["parameters"]["objective"] = "maximize minimum SOC rel"
analysis["algorithm"]["parameters"]["solver"] = "Cbc"  # Cbc, Gurobi, HiGHS
analysis["algorithm"]["parameters"]["time limit (sec)"] = 60;
analysis["write analysis.json"] = true;
res = EV.apply_algorithm(data, aux, analysis);
Applying algo MILP:

  Computing results ...

    - using given VH2CP assignments ... 

    - building optimization model ... finished.

    - optimizing with solver Cbc ... finished in 0.14 seconds

      status: OPTIMAL

      optimal value = 32.69

      finished.

  Saving analysis.json ... finished.

Presolve 452 (-169073) rows, 711 (-7764) columns and 1803 (-31766) elements

Perturbing problem by 0.001% of 0.084630219 - largest nonzero change 0.00063726768 ( 0.75300251%) - largest zero change 0.00047818689

0  Obj -3.4692791 Primal inf 216.67968 (102) Dual inf 0.083991951 (1)

84  Obj 27.5841 Primal inf 2930.5102 (185)

168  Obj 27.343964 Primal inf 91.642871 (27)

186  Obj 27.336928

Optimal - objective value 32.694231

After Postsolve, objective 32.694231, infeasibilities - dual 0 (0), primal 0 (0)

Optimal objective 32.69423077 - 186 iterations time 0.042, Presolve 0.04
# analyze results:
EV.analyse_objectives(analysis, aux, res)
peak active powers at location 0:
- baseload:   0.000 MW
- ESS:        0.126 MW
- charging:   1.080 MW
- total:      1.205 MW
costs at location 0:
- baseload:       0.00 EUR
- ESS:          178.70 EUR
- charging:    1864.36 EUR
- total   :    2043.07 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 636
Mean minimum SOC_rel over all vehicles: 44.38 %