In [ ]:
%matplotlib inline
import matplotlib.pyplot as plt
import scipy.optimize
In [ ]:
plt.plot([1, 2, 3], [10, 30, 20], "o-")
plt.xlabel("Unit of time (t)")
plt.ylabel("Price of one unit of energy (c)")
plt.title("Cost of energy on the market")
plt.show();
TODO: put pictures and explanations from my PhD
In [ ]:
# Price of energy on the market
price = [10, 30, 20]
plt.plot(price);
In [ ]:
stock_max = 100 # battery capacity
In [ ]:
# Coefficients of the linear objective function to be minimized
p = -np.array(price)
# 2-D array which, when matrix-multiplied by x, gives the values of the upper-bound inequality constraints at x.
A = [[-1, 0, 0],
[ 1, 0, 0],
[-1, -1, 0],
[ 1, 1, 0],
[-1, -1, -1],
[ 1, 1, 1]]
# 1-D array of values representing the upper-bound of each inequality constraint (row) in A.
b = [stock_max, 0, stock_max, 0, stock_max, 0]
# Sequence of (min, max) pairs for each element in x, defining the bounds on that parameter.
# Use None for one of min or max when there is no bound in that direction.
# By default bounds are (0, None) (non-negative).
# If a sequence containing a single tuple is provided, then min and max will be applied to all variables in the problem.
x0_bounds = (None, None)
x1_bounds = (None, None)
x2_bounds = (None, None)
bounds = (x0_bounds, x1_bounds, x2_bounds)
scipy.optimize.linprog(p, A_ub=A, b_ub=b, bounds=bounds)
In [ ]:
# Cost of energy on the market
#price = [10, 30, 20] # -> -100, 100, 0
#price = [10, 30, 10, 30] # -> [-100., 100., -100., 100.]
#price = [10, 30, 10, 30, 30] # -> [-100., 100., -100., 100., 0.]
#price = [10, 20, 30, 40] # -> [-100., 0., 0., 100.]
price = [10, 30, 20, 50]
price = [10, 30, 20, 50]
plt.plot(price);
In [ ]:
p = -np.array(price)
In [ ]:
A = np.repeat(np.tril(np.ones(len(price))), 2, axis=0)
A[::2, :] *= -1
A
In [ ]:
b = np.zeros(A.shape[0])
b[::2] = stock_max
b
In [ ]:
bounds = tuple((None, None) for _p in price)
bounds
In [ ]:
%%time
res = scipy.optimize.linprog(p, A_ub=A, b_ub=b, bounds=bounds) # , method='revised simplex'
In [ ]:
res
In [ ]:
res.x.round(decimals=2)