scipy:发出通过参数以优化。shgo函数

发布于 2025-02-11 11:00:27 字数 2794 浏览 2 评论 0原文

我正在尝试使用Scipy中实现的SHGO算法,但是当目标函数需要多个参数时,我遇到了麻烦。如果我正确理解错误,我不会按预期将其他参数(参数)传递给目标函数,但是,我看不出我的语法是错误的。 有人可以解释错误的根本原因以及如何解决吗?

以下是我面临的问题的可再现例子。
“图像显示在Python代码中实现的问题的数学公式”

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.
Image presenting the mathematical formulation of the problem implemented in the Python code

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 技术交流群。

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

发布评论

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

评论(2

风吹过旳痕迹 2025-02-18 11:00:27

正如您发现的那样,问题是a shgo 中的错误。

您可以通过避免使用args参数来避免shgo中的错误。而不是使用args,请使用fobj的包装器,该包装在封闭中捕获y y z 。一种简单的方法是使用lambda表达式:从shgofunc = 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 the args parameter. Instead of using args, use a wrapper of fobj that captures y and z in a closure. A simple way to do that is with a lambda expression: change the first argument of shgo from func=fobj to func=lambda x, y=y, z=z: fobj(x, y, z), and remove the args parameter from the call.

橘虞初梦 2025-02-18 11:00:27

问题是sum是一种方法,而不是数组的属性。

如果您加上目标函数

def fobj(x, y, z):
    return (x+y+z).sum()

,则它应该有效,开发版本有错误(很快就会更新)。

该方法似乎也不是很健壮,对于sum(x)= 14,它只有一个解决方案,这可能是一个问题,因为有效的搜索空间是0维空间,但是即使我将其放松到诸如sum(x)之类的东西上= 12该方法无法提供解决方案。

在这里,您有一个更完整的示例

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], [3,4,5,6]))
cons = {'type': 'eq', 'fun': lambda x: x.sum() - 9}
min_kwargs = {'method': 'SLSQP', 'options': {'maxiter': 10000, 'disp': True}}
ret = opt.shgo(func=lambda x: fobj(x, y, z), bounds=bnds, args=(), constraints=cons, 
               minimizer_kwargs=min_kwargs, options={'disp': True})

The problem is that sum is a method, not a property of the array.

It should work if you make your objective function

def fobj(x, y, z):
    return (x+y+z).sum()

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

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], [3,4,5,6]))
cons = {'type': 'eq', 'fun': lambda x: x.sum() - 9}
min_kwargs = {'method': 'SLSQP', 'options': {'maxiter': 10000, 'disp': True}}
ret = opt.shgo(func=lambda x: fobj(x, y, z), bounds=bnds, args=(), constraints=cons, 
               minimizer_kwargs=min_kwargs, options={'disp': True})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文