動機
・ずっとエネルギーマネージメント系の仕事でお金を稼ぎたいと思っていた。
・仕事で触れる機会もないので、まずは自分でやってみた。
・数理最適化も勉強してみたかった。
感想
・pulpは使いやすそう。
・制約式をきれいに書く方法がわからない。もっと手早く書ける気がする。
・電力の同時同量原則を守るようにすると、実行可能解がでない。。。
コード
qiita.py
#もし入ってなければpulpのインストールから
!pip install pulp
#問題を定義
import pulp
problem = pulp.LpProblem('エネマネ', pulp.LpMinimize)#数理モデル定義
#解く問題は”24時間の電力コスト最小化”
#電力ソースは自社発電機と電力市場購入
#発電機は、発電量と稼働コストが異なるものが6台(u_i,i=1~6).購入したら、期間(t=1~24まで)中ずっと電力を供給してくれる。
#電力市場購入は、発電量と購入コストが異なるものが3つ。(x1_t,x2_t,x3_t,t=1~24).各時間で購入する必要がある。
#今回の問題は、”バイナリ変数x_1_t,x_2_t,x_3_t,u_i(t=1~24, i=1~6)をうまく設定して、コストが最小になるようにしてね”という問題になる。(変数が1で購入、変数が0で非購入扱い)
#変数を定義
#電力市場購入
x1 = [ pulp.LpVariable( 'x1_{}'.format( i ),cat=pulp.LpBinary) for i in range(1,25) ]
x2 = [ pulp.LpVariable( 'x2_{}'.format( i ),cat=pulp.LpBinary) for i in range(1,25) ]
x3 = [ pulp.LpVariable( 'x3_{}'.format( i ),cat=pulp.LpBinary) for i in range(1,25) ]
#発電機購入
u = [ pulp.LpVariable( 'u_{}'.format( i ),cat=pulp.LpBinary) for i in range(1,7) ]
#制約式用の係数を作る
#市場購入電力のコスト,どの時間でも一定とした。
c1 = [10 for i in range(1,25)]
c2 = [15 for i in range(1,25)]
c3 = [20 for i in range(1,25)]
#発電機の購入コスト
cG=[90, 130, 160, 170, 250, 280]
#発電機発電量
kwh_G ={5, 6, 8, 10, 15, 20}
#市場電力の電力量は制約式を作る際に手打ちした。もっと上手い書き方がある気がする。。。
#電力需要
kwh_Demand=[23, 23, 25, 25, 28, 33, 43, 43, 48, 53, 63, 69, 65, 60, 53, 48, 55, 63, 61, 53, 43, 33, 28, 25]
#電力需要の可視化
import matplotlib.pyplot as plt
time = [i for i in range(1,25)]
plt.bar(time, kwh_Demand, tick_label=time)
#目的関数をセット
#コスト最小化したいので、コストの式を入れる
problem += pulp.lpDot( c1, x1 ) + pulp.lpDot( c2, x2 ) +pulp.lpDot( c3, x3 ) +pulp.lpDot( cG, u )
#制約関数をセット
#購入電力について、x1=5kWh,x2=10kWh,x3=20kWhと置いた。
for i in range(24):
problem += 5*x1[i] + 10*x2[i] + 20*x3[i] + pulp.lpDot( u, kwh_G ) >= d[i]
problem += x1[i] + x2[i] + x3[i] <= 1
#制約式と目的関数の確認
print(problem)
# 解く
result = problem.solve()
#解けているか確認。result=1でないと解けていない。
print("result=",result)
# 結果を出力
print('objective value: {}'.format(pulp.value(problem.objective)))
print('solution')
for i in range(len(x1)):
print('x1_{} = {}'.format( i+1, pulp.value(x1[i]) ))
print('x2_{} = {}'.format( i+1, pulp.value(x2[i]) ))
print('x3_{} = {}'.format( i+1, pulp.value(x3[i]) ))
for i in range(len(u)):
print('u_{} = {}'.format( i+1, pulp.value(u[i]) ))
githubにコードを上げています。
ご参考にさせていただいたサイト