私は scipy.optimize.minimize を使用して、複雑な貯水池最適化モデルを解決しています (問題は境界方程式と制約方程式の両方によって制約されているため、SQSLP と COBYLA)。1 日 (貯留) ごとに 1 つの決定変数があり、貯留層からの放出は目的関数内の貯留の変化の関数として計算されます。次に、ペナルティを最小限に抑えることを目的として、リリースとストレージのペナルティに基づくペナルティが適用されます (目的関数はすべてのペナルティの合計です)。このモデル内にいくつかの制約を追加して、ストレージの変更を決定変数 x(t+1) と x(t) の差である物理システム制限に制限し、その時間ステップ I( t)。これらの制約は、for ループを使用して制約辞書のリストに追加されます。この for ループの外側に追加された制約は、必要に応じて機能します。ただし、for ループ内で開始される時間に関する制約は、そうではありません。
明らかに問題は複雑なので、問題を説明するために単純なバージョンを再作成しました。この問題には 4 つの決定変数があり、定常状態 (I = 流入は x = 流出と等しくなければならない) および非負性 (つまり、流出 x は負にならない) の制約を使用して、目的関数 (関数と呼んでいます) を最小化しようとします。
import numpy as np
from scipy.optimize import minimize
def function(x):
return -1*(18*x[0]+16*x[1]+12*x[2]+11*x[3])
I=np.array((20,50,50,80))
x0=I
cons=[]
steadystate={'type':'eq', 'fun': lambda x: x.sum()-I.sum() }
cons.append(steadystate)
for t in range (4):
def const(x):
y=x[t]
return y
cons.append({'type':'ineq', 'fun': const})
out=minimize(function, x0, method="SLSQP", constraints=cons)
x=out["x"]
for ループで開始された制約は非負の制約ですが、最適化によって決定変数に負の値が与えられます。ただし、定常状態の制約には従います。
次のコードを使用して問題を計算すると、値が適切に制限されます。
import numpy as np
from scipy.optimize import minimize
def function(x):
return -1*(18*x[0]+16*x[1]+12*x[2]+11*x[3])
I=np.array((20,50,50,80))
x0=I
cons=[]
steadystate1={'type':'eq', 'fun': lambda x: x.sum()-I.sum() }
cons.append(steadystate1)
nonneg0 = {'type':'ineq', 'fun': lambda x: x[0]}
nonneg1= {'type':'ineq', 'fun': lambda x: x[1]}
nonneg2 = {'type':'ineq', 'fun': lambda x: x[2]}
nonneg3 = {'type':'ineq', 'fun': lambda x: x[3]}
cons.append(nonneg0)
cons.append(nonneg1)
cons.append(nonneg2)
cons.append(nonneg3)
out=minimize(function, x0, method="SLSQP", constraints=cons)
x=out["x"]
私が間違っているアイデアはありますか?他のアプリケーションでも同様に制約が開始されるのを見たことがあるので、それを理解することはできませんが、単純なものだと思います。このコードの本格的なバージョンでは何百もの制約を開始する必要があるため、2 番目の例のようにそれらを書き出すのは理想的ではありません。