使用 scipy.minimize 迭代约束
Iterating constraints with scipy.minimize
我正在尝试最小化具有 2 个变量 x[0]、x[1] 的函数。 A、B 和 C 是尺寸为 10x10 的数据框。当我不使用约束时,优化会按预期工作,但我也关心受约束的情况。对于受约束的情况,我想要
A.iloc[i,j]*x[0]*B.iloc[i,j]*x[1]*C.iloc[i,j]
对于 i 和 j 的所有组合都等于或大于零。为此,我按以下方式定义了约束:
cons=[]
def f(a):
def g(x):
return A.iloc[i,j]*x[0]*B.iloc[i,j]*x[1]*C.iloc[i,j]
return g
for i in range (10):
for j in range(10):
cons.append({'type':'ineq', 'fun': f(t)})
虽然我获得了正确数量的约束(即 len(cons) = 100),但优化结果不满足我想到的约束,这意味着它会导致 x[0]、x [1] 和 x[2]
A.iloc[i,j]*x[0]*B.iloc[i,j]*x[1]*C.iloc[i,j]
对于许多 j,i 小于零。我已经确定 result.success = True,因此可以排除优化突然停止的潜在问题。在寻找这个问题的解决方案时,我发现 也有人试图在 scipy 中迭代约束,但他们只迭代了一个范围而不是两个范围,我无法修改他们的解决方案适用于我的案例。
您的函数 f
没有任何意义,因为函数 g
不依赖于 a
。如果你真的想要 f
到 return 一个新函数取决于索引 i
和 t
,f
应该是两个索引的函数:
cons=[]
def f(t, i):
def g(x):
return A.iloc[t,i]+(x[0]*B.iloc[t,i]+x[1]*C.iloc[t,i]+x[2]*D.iloc[t,i])/33
return g
for t in range (72):
for i in range(33):
cons.append({'type':'ineq', 'fun': f(t, i)})
另请注意,由于 lambda 表达式,您可以轻松地动态定义约束函数:
cons = []
for t in range(72):
for i in range(33):
cons.append({'type': 'ineq', 'fun': lambda x, t=t, i=i: A.iloc[t,i]+(x[0]*B.iloc[t,i]+x[1]*C.iloc[t,i]+x[2]*D.iloc[t,i])/33})
我正在尝试最小化具有 2 个变量 x[0]、x[1] 的函数。 A、B 和 C 是尺寸为 10x10 的数据框。当我不使用约束时,优化会按预期工作,但我也关心受约束的情况。对于受约束的情况,我想要
A.iloc[i,j]*x[0]*B.iloc[i,j]*x[1]*C.iloc[i,j]
对于 i 和 j 的所有组合都等于或大于零。为此,我按以下方式定义了约束:
cons=[]
def f(a):
def g(x):
return A.iloc[i,j]*x[0]*B.iloc[i,j]*x[1]*C.iloc[i,j]
return g
for i in range (10):
for j in range(10):
cons.append({'type':'ineq', 'fun': f(t)})
虽然我获得了正确数量的约束(即 len(cons) = 100),但优化结果不满足我想到的约束,这意味着它会导致 x[0]、x [1] 和 x[2]
A.iloc[i,j]*x[0]*B.iloc[i,j]*x[1]*C.iloc[i,j]
对于许多 j,i 小于零。我已经确定 result.success = True,因此可以排除优化突然停止的潜在问题。在寻找这个问题的解决方案时,我发现
您的函数 f
没有任何意义,因为函数 g
不依赖于 a
。如果你真的想要 f
到 return 一个新函数取决于索引 i
和 t
,f
应该是两个索引的函数:
cons=[]
def f(t, i):
def g(x):
return A.iloc[t,i]+(x[0]*B.iloc[t,i]+x[1]*C.iloc[t,i]+x[2]*D.iloc[t,i])/33
return g
for t in range (72):
for i in range(33):
cons.append({'type':'ineq', 'fun': f(t, i)})
另请注意,由于 lambda 表达式,您可以轻松地动态定义约束函数:
cons = []
for t in range(72):
for i in range(33):
cons.append({'type': 'ineq', 'fun': lambda x, t=t, i=i: A.iloc[t,i]+(x[0]*B.iloc[t,i]+x[1]*C.iloc[t,i]+x[2]*D.iloc[t,i])/33})