|
| 1 | +# Copyright 2015, Vincent Leclere, Francois Pacaud and Henri Gerard |
| 2 | +# This Source Code Form is subject to the terms of the Mozilla Public |
| 3 | +# License, v. 2.0. If a copy of the MPL was not distributed with this |
| 4 | +# file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| 5 | +############################################################################# |
| 6 | +# Solving an decision hazard battery storage problem using multiprocessed |
| 7 | +# dynamic programming. |
| 8 | +# |
| 9 | +# to launch (with N processes) |
| 10 | +# $ julia -p N battery_storage_parallel.jl |
| 11 | +# |
| 12 | +# PROBLEM DESCRIPTION |
| 13 | +# For t = 1..T, we want to satisfy a deterministic energy demand d_t using: |
| 14 | +# - a random renewable energy unit with production (at time t) W_t |
| 15 | +# - a battery with stock (at time t) S_t |
| 16 | +# - a quantity G_{t} bought on the market for a deterministic price c_t |
| 17 | +# The decision variable is the quantity U_t of energy stored (or discharged) in |
| 18 | +# the battery, is decided knowing the uncertainty W_0,...,W_t. |
| 19 | +# We want to minimize the money spent on buying electricity (cost are deterministic) : |
| 20 | +# min E[\sum_{t=0}^T c_t * G_{t}] |
| 21 | +# d_t + U_t <= W_t + G_t (a) |
| 22 | +# S_{t+1} = S_t + r (U_t)^+ + 1/r (U_t)^- (b) |
| 23 | +# Smin <= S_t <= Smax (c) |
| 24 | +# G_t >= 0 (d) |
| 25 | +# |
| 26 | +# (a) : more production than demand (excess is wasted) |
| 27 | +# (b) : dynamic of the stock with a charge coefficient r |
| 28 | +# (c) : limits on the battery |
| 29 | +# (d) : we don't sell electricity |
| 30 | + |
| 31 | + |
| 32 | + |
| 33 | + |
| 34 | +import StochDynamicProgramming, Distributions |
| 35 | +println("library loaded") |
| 36 | + |
| 37 | +# We have to define the instance on all the workers (processes) |
| 38 | +@everywhere begin |
| 39 | + |
| 40 | + run_sdp = true |
| 41 | + |
| 42 | + ######## Stochastic Model Parameters ######## |
| 43 | + const N_STAGES = 50 |
| 44 | + const COSTS = rand(N_STAGES) |
| 45 | + const DEMAND = rand(N_STAGES) |
| 46 | + |
| 47 | + const CONTROL_MAX = 0.5 |
| 48 | + const CONTROL_MIN = 0 |
| 49 | + |
| 50 | + const STATE_MAX = 1 |
| 51 | + const STATE_MIN = 0 |
| 52 | + |
| 53 | + const XI_MAX = 0.3 |
| 54 | + const XI_MIN = 0 |
| 55 | + const N_XI = 10 |
| 56 | + # initial stock |
| 57 | + const S0 = 0.5 |
| 58 | + |
| 59 | + # charge and discharge efficiency parameters |
| 60 | + const rho_c = 0.98 |
| 61 | + const rho_dc = 0.97 |
| 62 | + |
| 63 | + # create law of noises |
| 64 | + proba = 1/N_XI*ones(N_XI) # uniform probabilities |
| 65 | + xi_support = collect(linspace(XI_MIN,XI_MAX,N_XI)) |
| 66 | + xi_law = StochDynamicProgramming.NoiseLaw(xi_support, proba) |
| 67 | + xi_laws = StochDynamicProgramming.NoiseLaw[xi_law for t in 1:N_STAGES-1] |
| 68 | + |
| 69 | + # Define dynamic of the stock: |
| 70 | + function dynamic(t, x, u, xi) |
| 71 | + return [ x[1] + 1/rho_dc * min(u[1],0) + rho_c * max(u[1],0) ] |
| 72 | + end |
| 73 | + |
| 74 | + # Define cost corresponding to each timestep: |
| 75 | + function cost_t(t, x, u, xi) |
| 76 | + return COSTS[t] * max(0, DEMAND[t] + u[1] - xi[1]) |
| 77 | + end |
| 78 | + |
| 79 | + function constraint(t, x, u, xi) |
| 80 | + return( (x[1] <= s_bounds[1][2] )&(x[1] >= s_bounds[1][1])) |
| 81 | + end |
| 82 | + |
| 83 | + function finalCostFunction(x) |
| 84 | + return(0) |
| 85 | + end |
| 86 | + |
| 87 | + ######## Setting up the SPmodel |
| 88 | + s_bounds = [(STATE_MIN, STATE_MAX)] |
| 89 | + u_bounds = [(CONTROL_MIN, CONTROL_MAX)] |
| 90 | + spmodel = StochDynamicProgramming.StochDynProgModel(N_STAGES, s_bounds, |
| 91 | + u_bounds, |
| 92 | + [S0], |
| 93 | + cost_t, |
| 94 | + finalCostFunction, |
| 95 | + dynamic, |
| 96 | + constraint, |
| 97 | + xi_laws) |
| 98 | + |
| 99 | + scenarios = StochDynamicProgramming.simulate_scenarios(xi_laws,1000) |
| 100 | + |
| 101 | + stateSteps = [0.01] |
| 102 | + controlSteps = [0.001] |
| 103 | + infoStruct = "HD" # noise at time t is not known before taking the decision at time t |
| 104 | + |
| 105 | + paramSDP = StochDynamicProgramming.SDPparameters(spmodel, stateSteps, |
| 106 | + controlSteps, infoStruct) |
| 107 | +end |
| 108 | + |
| 109 | +Vs = StochDynamicProgramming.solve_DP(spmodel,paramSDP, 1) |
| 110 | + |
| 111 | +lb_sdp = StochDynamicProgramming.get_bellman_value(spmodel,paramSDP,Vs) |
| 112 | +println("Value obtained by SDP: "*string(lb_sdp)) |
| 113 | +costsdp, states, stocks = StochDynamicProgramming.sdp_forward_simulation(spmodel,paramSDP,scenarios,Vs) |
| 114 | +println(mean(costsdp)) |
| 115 | + |
0 commit comments