Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从预定义集为scipy.optimize选择变量_Python_Optimization_Minimization_Scipy Optimize - Fatal编程技术网

Python 从预定义集为scipy.optimize选择变量

Python 从预定义集为scipy.optimize选择变量,python,optimization,minimization,scipy-optimize,Python,Optimization,Minimization,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,

我试图用三个输入变量最小化一个函数,其中两个是有界的,一个必须从一组值中选择。为了确保从预定义的值集中选择第三个变量,我引入了以下约束:

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_测试的打印结果时,很明显该条件没有被强制执行-可能条件定义不正确

我想知道是否有人有任何想法来确保第三个变量可以从集合中选择

注:选择shgo方法的目的是为了引入和更改约束。此外,如果满足此条件,我愿意使用其他优化包


谢谢你的帮助

不等式约束不是这样工作的

如本节所述,它们的定义如下:

g(x) <= 0
也许您应该尝试以允许在整个
Z
范围内使用不等式约束的方式来定义问题

但是让我们看看它是如何工作的

等式约束定义为

h(x) == 0
所以你可以用

def Cond_1(x):
    if x[2] in Z:
        return numpy.zeros_like(x)
    else:
        return numpy.ones_like(x) * 1.0 # maybe multiply with some scalar?
其思想是返回一个数组
[0.0,0.0,0.0]
,如果找到该数字,则该数组满足等式约束。否则返回
[1.0,1.0,1.0]
,表示不满意

注意事项

1.) 您可能需要对此进行调整,以返回类似
[0.0,0.0,1.0]
的数组,向优化器显示您不满意的维度,以便优化器只需调整单个维度即可做出更好的猜测

(二) 您可能必须返回大于1.0的值才能声明不满足的相等约束。这取决于实施情况。优化器可能认为1.0很好,因为它接近0.0。因此,也许你必须尝试一些
[0.0,0.0,999.0]

这就解决了尺寸标注的问题。但是仍然找不到任何数字做的关于上面提到的浮点数的事情

但我们可以试着像这样解决这个问题

import numpy as np

Z = np.array([-1, -0.8, -0.6, -0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8, 1])

def Cond_1(x):

    # how close you want to get to the numbers in your array
    tolerance = 0.001 
    delta = np.abs(x[2] - Z)
    print(delta)
    print(np.min(delta) < tolerance)

    if np.min(delta) < tolerance:

        return np.zeros_like(x)

    else:

        # maybe you have to multiply this with some scalar
        # I have no clue how it is implemented
        # we need a value stating to the optimizer "NOT THIS ONE!!!"
        return np.ones_like(x) * 1.0


sol = np.array([0.5123, 0.234, 0.2])
print(Cond_1(sol)) # True

sol = np.array([0.5123, 0.234, 0.202])
print(Cond_1(sol)) # False
将numpy导入为np
Z=np.数组([-1,-0.8,-0.6,-0.4,-0.2,0.2,0.4,0.6,0.8,1])
def Cond_1(x):
#您希望接近数组中的数字的距离有多近
公差=0.001
δ=np.abs(x[2]-Z)
打印(增量)
打印(np.最小值(增量)<公差)
如果np.最小值(增量)<公差:
返回np.zero_like(x)
其他:
#也许你得用一些标量乘以这个
#我不知道它是如何实施的
#我们需要一个值向优化器声明“不是这个!!!”
返回np.ones_(x)*1.0
sol=np.数组([0.5123,0.234,0.2])
打印(条件1(溶胶))#真实
sol=np.数组([0.5123,0.234,0.202])
打印(条件1(溶胶))#错误
下面是一些关于优化的建议。为了确保它以可靠的方式工作,请尝试在不同的初始值开始优化。如果与边界一起使用,全局优化算法可能没有初始值。优化器以某种方式将空间离散化

如何检查优化的可靠性并获得更好的总体结果:

  • 优化整个区域
    [-512,512]
    (适用于所有三维)

  • 尝试其中的1/2:
    [-512,0]
    [0512]
    (8个子优化,每个维度2个)

  • 尝试其中的三分之一:
    [-512,-171]
    [-171170]
    [170512]
    (27个子优化,每个维度3个)

  • 现在比较收敛的结果,看看完整的全局优化是否发现了相同的结果

  • 如果全局优化器没有找到“真实”最小值,而是找到了子优化:

    • 你的目标函数在整个领域都太难了
    • 尝试其他全局优化器
    • 调整参数(可能是等式约束的999)
    • 我经常使用子优化作为正常过程的一部分,而不仅仅是用于测试。特别是黑盒问题
请参阅以下答案:


非常感谢您的回答,这似乎很有效!!
import numpy as np

Z = np.array([-1, -0.8, -0.6, -0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8, 1])

def Cond_1(x):

    # how close you want to get to the numbers in your array
    tolerance = 0.001 
    delta = np.abs(x[2] - Z)
    print(delta)
    print(np.min(delta) < tolerance)

    if np.min(delta) < tolerance:

        return np.zeros_like(x)

    else:

        # maybe you have to multiply this with some scalar
        # I have no clue how it is implemented
        # we need a value stating to the optimizer "NOT THIS ONE!!!"
        return np.ones_like(x) * 1.0


sol = np.array([0.5123, 0.234, 0.2])
print(Cond_1(sol)) # True

sol = np.array([0.5123, 0.234, 0.202])
print(Cond_1(sol)) # False