使用 scipy.minimize 迭代约束

发布于 2025-01-12 21:16:33 字数 891 浏览 0 评论 0原文

我正在尝试最小化具有 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]

等于或大于零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]

小于零。我已经确定result.success = True,因此可以排除优化突然停止的潜在问题。在寻找此问题的解决方案时,我发现 在这种情况下,有人试图在 scipy 中迭代约束,但他们只迭代一个范围而不是两个范围,我无法修改他们的解决方案以使其工作对于我的情况。

I am trying to minimize a function with 2 variables x[0],x[1]. A, B, and C are dataframes with dimensions 10x10. The optimization works as intended when I don't use constraints, however I also care for the constrainted case. For the constrainted case, I want

A.iloc[i,j]*x[0]*B.iloc[i,j]*x[1]*C.iloc[i,j]

to be equal to or greater than zero for all combinations of i and j. To achieve this, I have defined constraints in the following way:

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)})

While I am getting the right number of constraints (i.e. len(cons) = 100), the optimization results do not satisfy the constraints that I had in mind, meaning it results in values for x[0], x[1] and x[2] for which

A.iloc[i,j]*x[0]*B.iloc[i,j]*x[1]*C.iloc[i,j]

is smaller than zero for many j,i. I have ascertained that result.success = True, so the optimization suddenly stopping can be ruled out as a potential problem. While looking for a solution to this problem, I have found this case of someone trying to iterate constraints in scipy aswell, but they only iterated over one range rather than over two and I was not able to modify their solution to work for my case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

橪书 2025-01-19 21:16:33

您的函数 f 没有任何意义,因为函数 g 不依赖于 a。如果您确实希望 f 根据索引 it 返回一个新函数,则 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}) 

Your function f doesn't make any sense since the function g doesn't depend on a. If you really want f to return a new function depending on the indices i and t, f should be a function of the two indices:

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)})

Note also that you could easily define the constraint functions on the fly thanks to lambda expressions:

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}) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文