我正在尝试使用具有三个输入变量的scipy.optimize
最小化一个函数,其中两个是有界的,并且必须从一组值中选择一个。为了确保从预定义的值集中选择第三个变量,我引入了以下约束:
from scipy.optimize import rosin, shgo
import numpy as np
# Set from which the third variable to be optimized can hold
Z = np.array([-1, -0.8, -0.6, -0.4, -0.2, 0, 0.2, 0.4, 0.6, 0,8, 1])
def Reson_Test(x): # arbitrary objective function
print (x)
return rosen(x)**2 - np.sin(x[0])
def Cond_1(x):
if x[2] in Z:
return 1
else:
return -1
bounds = [(-512,512),]*3
conds = ({'type': 'ineq' , 'fun' : Cond_1})
result = shgo(Rosen_Test, bounds, constraints=conds)
print (result)
但是,当查看Rosen_Test
的打印结果时,很明显条件没有得到执行-可能条件定义不正确?
我想知道是否有人有想法确保可以从集合中选择第三个变量。
注:选择shgo方法的目的是可以引入约束并且可以更改约束。另外,如果满足此条件,我也可以使用其他优化程序包
感谢您的帮助!
不平等约束不是那样工作的。
如docs中所述,它们定义为
g(x) <= 0
并且您需要编写g(x)
这样的作品。在您的情况下并非如此。您只返回一个维度的单个标量。您需要返回具有(3,)
形状的三个维度的向量。
在您的情况下,您可以尝试使用等式约束,因为这样可以使黑客行为略好。但是我仍然不确定它是否会工作,因为这些优化器不能那样工作。
还有另外两个原因导致您的方法不起作用:
使用in
不适用于numpy,您必须使用np.in1d
([https://docs.scipy.org/doc/numpy/reference/generated/numpy.in1d.html?highlight=in1d#numpy.in1d)代替
由于优化器使用浮点数,因此优化时可能永远不会在数组中找到一个数字
也许您应该尝试以允许在Z
的整个范围上使用不等式约束的方式来定义问题。
但是让我们看看它如何工作:
等式约束定义为
h(x) == 0
所以您可以使用
def Cond_1(x):如果Z中的x [2]:返回numpy.zeros_like(x)其他:返回numpy.zeros_like(x)
return 1
else:
return -1
正在进行中,需要保存...
constr_func = lambda x:np.array([x [0] ** 3-x [1] ** 2-1-1x [0],x [2]])
x0 = [0.,0.,0。]] >>
nonlin_con = NonlinearConstraint(constr_func,0.,np.inf)
也请参见以下答案:
Scipy.optimize Inequality Constraint - Which side of the inequality is considered?