使用scipy最小化一个包含非变参数的函数

4 投票
3 回答
11865 浏览
提问于 2025-04-18 16:34

我想用 scipy.optimize 模块来最小化一个函数。假设我的函数是 f(x,a)

def f(x,a):
 return a*x**2

在固定的 a 值下,我想要最小化 f(x,a),也就是让 x 的值变得更好。

使用 scipy,我可以导入一个叫 fmin 的函数(我用的是旧版的 scipy: v.0.9.0),给它一个初始值 x0,然后进行优化(文档):

from scipy.optimize import fmin
x0 = [1]
xopt = fmin(f, x0, xtol=1e-8)

但是这样会失败,因为 f 需要两个参数,而 fmin 只传了一个(其实我连 a 是什么都还没定义)。如果我这样做:

from scipy.optimize import fmin
x0 = [1]
a = 1
xopt = fmin(f(x,a), x0, xtol=1e-8)

计算也会失败,因为“x 没有定义”。不过,如果我定义了 x,那就没有可以优化的参数了。

我该怎么做才能让非变动参数作为函数的参数使用呢?

3 个回答

0

对于你的情况,Warren 提出的标准解决方案可能是最合适的选择。

不过,值得注意的是,你也可以优化类的成员函数。在这种情况下,你可以使用类中的变量作为参数。这在你的代码已经是基于对象的时候特别有用,添加一个成员函数来进行优化是很有意义的。

在你的例子中,这种(有点过于复杂的)解决方案是:

class FunctionHolder(object):
    def __init__(self,a):
        self.a=a
    def f(self, x):
        return x*self.a

f1=FunctionHolder(1)
scipy.optimize.minimize(f1.f, x0)
3

这里提到的 args 参数可能是个不错的选择,但还有另一种方法,有时候也很有用。首先,你需要写一个包装函数,这个函数会接收一个函数和一个值 a 作为输入,然后返回一个新的函数,这个新函数中的 a 是固定的。

def fix_a(f, a):
    def f_with_fixed_a(x):
        return f(x, a)
return f_with_fixed_a

然后你可以这样调用 fmin:

xopt = fmin(fix_a(f, a), x0, xtol=1e-8)

如果你只是想传入一个固定的 a,那么使用 fmin 的 args 关键字可能显得有点啰嗦,但这种方法更灵活,可以处理更复杂的情况(比如如果你想让 a 成为 x 的某个函数)。

8

在文档字符串中了解一下 fmin 函数的 args 参数,具体可以查看这里,然后使用它。

a = 1
x0 = 1
xopt = fmin(f, x0, xtol=1e-8, args=(a,))

撰写回答