scipy:发出通过参数以优化。shgo函数
我正在尝试使用Scipy中实现的SHGO算法,但是当目标函数需要多个参数时,我遇到了麻烦。如果我正确理解错误,我不会按预期将其他参数(参数)传递给目标函数,但是,我看不出我的语法是错误的。 有人可以解释错误的根本原因以及如何解决吗?
以下是我面临的问题的可再现例子。
import numpy as np
import scipy.optimize as opt
def fobj(x, y, z):
return (x+y+z).sum()
x0 = np.array([0.5, 0.5, 0.5, 0.5])
y = np.array([1, 3, 5, 7])
z = np.array([10, 20, 30, 40])
bnds = list(zip([0, 1, 2, 3], [2, 3, 4, 5]))
cons = {'type': 'eq', 'fun': lambda x: x.sum() - 14}
min_kwargs = {'method': 'SLSQP', 'options': {'maxiter': 100, 'disp': True}}
ret = opt.shgo(func=fobj, bounds=bnds, args=(y, z), constraints=cons, minimizer_kwargs=min_kwargs, options={'disp': True})
当运行以下追溯显示时。
Splitting first generation
Traceback (most recent call last):
File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 630, in __getitem__
return self.cache[x]
KeyError: (0, 0, 0, 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\path\lib\site-packages\scipy\optimize\_shgo.py", line 420, in shgo
shc.construct_complex()
File "C:\path\lib\site-packages\scipy\optimize\_shgo.py", line 733, in construct_complex
self.iterate()
File "C:\path\lib\site-packages\scipy\optimize\_shgo.py", line 876, in iterate
self.iterate_complex()
File "C:\path\lib\site-packages\scipy\optimize\_shgo.py", line 895, in iterate_hypercube
self.HC = Complex(self.dim, self.func, self.args,
File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 25, in __init__
self.n_cube(dim, symmetry=symmetry)
File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 76, in n_cube
self.C0.add_vertex(self.V[origintuple])
File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 634, in __getitem__
xval = Vertex(x, bounds=self.bounds,
File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 557, in __init__
self.f = func(x_a, *func_args)
File "C:\path\lib\site-packages\scipy\optimize\_optimize.py", line 466, in function_wrapper
fx = function(np.copy(x), *(wrapper_args + args))
TypeError: fobj() takes 3 positional arguments but 5 were given
我不明白为什么typeError被提高。这是说5个参数而不是3个参数已传递给目标函数fobj
,但据我所知,我只通过(y,z)
,这样我就可以'看看他们是如何5!
请注意,我还尝试将本地最小化字典重写为min_kwargs = {'method':'slsqp','args':(x0),'options':{'maxiter':'axciTer':'axciter':100,'disp' :true}}
,但我一直面临相同的错误。我确定我错误地传达了这些论点,但是我不明白如何做正确的事情。任何帮助将不胜感激。
I am using: Python 3.10.5, Numpy 1.22.4, and SciPy 1.8.1.
I am trying to use the SHGO algorithm implemented in SciPy, but I have trouble when the objective function takes more than one argument. If I understand the error correctly, I am not passing the additional arguments (parameters) to the objective function as expected, however, I don't see where my syntax is wrong. Can someone explain what the root cause of the error is and how to fix it?
Below is a reproducible example of the issue I am facing.
import numpy as np
import scipy.optimize as opt
def fobj(x, y, z):
return (x+y+z).sum()
x0 = np.array([0.5, 0.5, 0.5, 0.5])
y = np.array([1, 3, 5, 7])
z = np.array([10, 20, 30, 40])
bnds = list(zip([0, 1, 2, 3], [2, 3, 4, 5]))
cons = {'type': 'eq', 'fun': lambda x: x.sum() - 14}
min_kwargs = {'method': 'SLSQP', 'options': {'maxiter': 100, 'disp': True}}
ret = opt.shgo(func=fobj, bounds=bnds, args=(y, z), constraints=cons, minimizer_kwargs=min_kwargs, options={'disp': True})
When run the following traceback is shown.
Splitting first generation
Traceback (most recent call last):
File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 630, in __getitem__
return self.cache[x]
KeyError: (0, 0, 0, 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\path\lib\site-packages\scipy\optimize\_shgo.py", line 420, in shgo
shc.construct_complex()
File "C:\path\lib\site-packages\scipy\optimize\_shgo.py", line 733, in construct_complex
self.iterate()
File "C:\path\lib\site-packages\scipy\optimize\_shgo.py", line 876, in iterate
self.iterate_complex()
File "C:\path\lib\site-packages\scipy\optimize\_shgo.py", line 895, in iterate_hypercube
self.HC = Complex(self.dim, self.func, self.args,
File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 25, in __init__
self.n_cube(dim, symmetry=symmetry)
File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 76, in n_cube
self.C0.add_vertex(self.V[origintuple])
File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 634, in __getitem__
xval = Vertex(x, bounds=self.bounds,
File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 557, in __init__
self.f = func(x_a, *func_args)
File "C:\path\lib\site-packages\scipy\optimize\_optimize.py", line 466, in function_wrapper
fx = function(np.copy(x), *(wrapper_args + args))
TypeError: fobj() takes 3 positional arguments but 5 were given
I don't get why the TypeError is raised. It's saying that 5 arguments rather than 3 were passed to the objective function fobj
, but as far as I can understand I am only passing (y, z)
, so I can't see how they are 5!
Note that I tried also to re-write the local minimizer dictionary as min_kwargs = {'method': 'SLSQP', 'args': (x0), 'options': {'maxiter': 100, 'disp': True}}
, but I kept facing the same error. I am sure I am passing the arguments incorrectly, but I can't understand how to do it right. Any help will be greatly appreciated.
I am using: Python 3.10.5, Numpy 1.22.4, and SciPy 1.8.1.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如您发现的那样,问题是a
shgo
中的错误。您可以通过避免使用
args
参数来避免shgo
中的错误。而不是使用args
,请使用fobj
的包装器,该包装在封闭中捕获y
y z 。一种简单的方法是使用lambda
表达式:从shgo
从func = func = fobj
更改第一个参数x,y = y,z = z:fobj(x,y,z),然后从呼叫中删除args
参数。As you discovered, the problem is a bug in
shgo
.You can avoid the bug in
shgo
by avoiding the use of theargs
parameter. Instead of usingargs
, use a wrapper offobj
that capturesy
andz
in a closure. A simple way to do that is with alambda
expression: change the first argument ofshgo
fromfunc=fobj
tofunc=lambda x, y=y, z=z: fobj(x, y, z)
, and remove theargs
parameter from the call.问题是
sum
是一种方法,而不是数组的属性。如果您加上目标函数
,则它应该有效,开发版本有错误(很快就会更新)。
该方法似乎也不是很健壮,对于sum(x)= 14,它只有一个解决方案,这可能是一个问题,因为有效的搜索空间是0维空间,但是即使我将其放松到诸如sum(x)之类的东西上= 12该方法无法提供解决方案。
在这里,您有一个更完整的示例
The problem is that
sum
is a method, not a property of the array.It should work if you make your objective function
Additionally, there is the bug on the development version (updates on this soon).
The method seems not very robust as well, for sum(x) = 14, it has only one solution this could be a problem because the valid search space is 0-dimensional, but even if I relax it to things like sum(x) = 12 the method can't give the solution.
Here you have a more complete working example