【问题标题】:Using a vector of constraints to a scipy.optimize function对 scipy.optimize 函数使用约束向量
【发布时间】:2018-06-02 07:33:08
【问题描述】:

我想使用scipy.optimize 库使用约束向量进行约束优化。特别是,我提供了一个 3d 坐标向量 r0N 点——因此是一个大小为 N x 3 的矩阵——作为函数的输入。坐标是笛卡尔坐标,我希望冻结所有 y 依赖。所以这意味着我需要将我的N x 3 矩阵的第二列保持为一个常数,例如y0。如何定义这样的约束列表?

具体来说,让我们考虑一下 COBYLA 算法 (https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_cobyla.html#scipy.optimize.fmin_cobyla)。我尝试了以下构造:

cons = []
for i in range(xyz0.shape[0]):
    def f(x):
        return x[i,1]-xyz0cyl[i,1]
    cons.append(f)
fmin_cobyla(energy, xyz0, cons, rhoend=1e-7)

并得到错误:

41 for i in range(xyz0.shape[0]):
42     def f(x):
---> 43         return x[i,1]-xyz0cyl[i,1]
 44     cons.append(f)
 45 

IndexError: too many indices for array

发生了什么事?

【问题讨论】:

  • Multidim 数组被展平为一维,因为minimize 仅将序列作为约束。

标签: python optimization scipy


【解决方案1】:

你的方法在很多方面都是错误的。

首先,minimize 将序列作为约束,因此您的 Nx3 数组在传递给约束函数之前首先被展平,从而为您留下一个只有一维的数组。因此,除了 reshape 约束函数内的数组到原始 Nx3 之外,您不能使用元组进行索引;对于大 N 来说可能相当昂贵:

return x.reshape(-1, 3)[i,1] - xyz0cyl[i,1]

其次,Python 中的闭包是后期绑定;在 for 循环完成后,所有约束函数都将使用 i 的最后一个值。您只会在修复第一个错误后才发现优化没有按预期进行。请参阅How do lexical closures work? 了解更多信息。

更好的方法是让 y 轴(即第 1 列)在能量函数中保持静止,或者简单地将 Nx2 矩阵传递给 fmin_cobyla

【讨论】:

  • 我会尝试冻结 y 轴。但是,如果我必须使用约束,我可以写 def f(x, i = i): 而不是 def f(x): 吗?这会解决词汇闭包问题吗?
  • @ap21 是的,这会解决它。
  • 当您说使 y 轴静止时,您的意思是在每次评估能量函数时将其设置为常数向量吗?或者更智能的东西?
猜你喜欢
  • 2015-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多