【问题标题】:struggling minimizing non linear function努力最小化非线性函数
【发布时间】:2018-04-17 16:27:52
【问题描述】:

我期待用 3 个参数(x1x2x3)最小化非线性函数

我的信息来源是:

我不属于数学领域,所以如果我使用了不正确的措辞/表达方式,请先原谅我。

这是我的代码:

import numpy as np
from scipy.optimize import minimize

def rosen(x1,x2,x3):
    return np.sqrt(((x1**2)*0.002)+((x2**2)*0.0035)+((x3**2)*0.0015)+(2*x1*x2*0.015)+(2*x1*x3*0.01)+(2*x2*x3*0.02))

我认为第一步到这里还不错..

然后需要说明:

x0 : ndarray
Initial guess. len(x0) is the dimensionality of the minimization problem.

鉴于我在最小化函数中声明了 3 个参数,我将声明一个 3 dim 数组,例如这样?

x0=np.array([1,1,1])

res = minimize(rosen, x0)
print(res.x)

不想要的输出是:

rosen() missing 2 required positional arguments: 'x2' and 'x3'

我不太明白我应该在哪里陈述位置参数。

除此之外,我想为x1,x2,x3 的输出值设置一些界限。

我试过了

res = minimize(rosen, x0,  bounds=([0,None]),options={"disp": False})

还有哪些输出:

ValueError: length of x0 != length of bounds

那么我应该如何表达res 内的界限呢?

所需的输出只是根据函数的最小值为x1,x2,x3 输出一个数组,其中每个值都是最小值 0,如边界中所述,并且args 加起来为 1。

【问题讨论】:

    标签: numpy scipy


    【解决方案1】:

    函数定义

    仔细阅读文档,例如为您的函数定义:

    有趣:可调用

    The objective function to be minimized. Must be in the form f(x, *args). The
    optimizing argument, x, is a 1-D array of points, and args is a tuple of any
    additional fixed parameters needed to completely specify the function.
    

    您的函数应该采用一维数组,而您为多变量方法实现多参数!

    变化:

    def rosen(x1,x2,x3):
        return np.sqrt(((x1**2)*0.002)+((x2**2)*0.0035)+((x3**2)*0.0015)+(2*x1*x2*0.015)+(2*x1*x3*0.01)+(2*x2*x3*0.02))
    
    def rosen(x):
        x1,x2,x3 = x # unpack vector for your kind of calculations
        return np.sqrt(((x1**2)*0.002)+((x2**2)*0.0035)+((x3**2)*0.0015)+(2*x1*x2*0.015)+(2*x1*x3*0.01)+(2*x2*x3*0.02))
    

    应该可以。这有点repair-something-to-keep-my-other-code 的方法,但在这个例子中不会有太大的伤害。通常你在 1d-array-input 假设上实现你的函数定义!

    界限

    再次来自文档:

    边界:序列,可选

    Bounds for variables (only for L-BFGS-B, TNC and SLSQP). (min, max) pairs for each
    element in x, defining the bounds on that parameter. Use None for one of min or max
    when there is no bound in that direction.
    

    所以你需要n_vars 对!通过使用列表理解很容易实现,从x0 中推断出必要的信息。

    res = minimize(rosen, x0,  bounds=[[0,None] for i in range(len(x0))],options={"disp": False})
    

    使变量总和为 1 / 约束

    您的评论暗示您希望变量总和为 1。然后您需要使用等式约束(只有 1 个求解器支持此和不等式约束;另一个只有不等式约束;其余没有约束;求解器如果没有明确给出,将自动选择)。

    看起来有点像:

    cons = ({'type': 'eq', 'fun': lambda x:  sum(x) - 1})  # read docs to understand!
                                                           # to think about:
                                                           # sum vs. np.sum
                                                           # (not much diff here)
    res = minimize(rosen, x0,  bounds=[[0,None] for i in range(len(x0))],options={"disp": False}, constraints=cons)
    

    对于 x 非负的情况,约束通常称为概率单纯形。

    (未经测试的代码;概念上正确!)

    【讨论】:

    • 非常感谢!我还有 1 个问题:无论如何我可以声明(例如在 res 中作为参数)args x1,x2,x3add 的添加最多为 1?我能找到它
    • 是的,通过使用约束。查找示例。在这种情况下(eq-constraints),只剩下 1 个要使用的求解器,并将自动选择,SLSQP。约束通常比其他部分更麻烦(因为很多人忽略了平滑度和 co;但是你的称为概率单纯形很简单,我认为示例也有这个!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多