scipy.minimize似乎没有遵守约束

时间:2018-06-01 07:34:33

标签: python scipy mathematical-optimization

scipy.minimize似乎没有遵守约束。 这是一个简单的例子,其中约束用于防止对数中的负参数,但最小化函数不符合:

import math
from scipy.optimize import minimize

def obj(x,b):
    print "obj x",x
    return math.log(x-b)

def constr(x,b):
    print "constr x",x
    return x-b

x=3.1
b=3
a=minimize(obj,x,args=(b),constraints={'type': 'ineq', 'fun':constr,'args':[b]})

输出是:

constr x [ 3.1]
obj x [ 3.1]
constr x [ 3.1]
obj x [ 3.1]
obj x [ 3.10000001]
constr x [ 3.1]
constr x [ 3.10000001]
obj x [ 3.]
Traceback (most recent call last):
File "scipy_minimize_constraints.py", line 19, in 
a=minimize(obj,x,args=(b),constraints={'type': 'ineq', 'fun':constr,'args':[b]})
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/optimize/_minimize.py", line 495, in minimize
constraints, callback=callback, **options)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/optimize/slsqp.py", line 378, in _minimize_slsqp
fx = func(x)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 292, in function_wrapper
return function(*(wrapper_args + args))
File "scipy_minimize_constraints.py", line 9, in obj
return math.log(x-b)
ValueError: math domain error

python2.7 Scipy版本1.0.0

我做错了吗?

2 个答案:

答案 0 :(得分:2)

约束

SELECT c.table_name, c.column_name
  FROM INFORMATION_SCHEMA.COLUMNS c
  WHERE c.column_name IN ('W','X','Y','Z')
ORDER BY c.table_name ASC, c.column_name ASC

结果为def constr(x,b): return x-b 非负),但允许x-b >= 0。如果x-b = 0,则log(x-b)未定义。你需要引入一些epsilon,如:

x-b = 0

不会抛出你的错误。

但可能存在一个更重要的问题:我真的不认为求解器(这里的SLSQP)保证它的迭代是可行的!可能会出现问题。在您的简单示例中,要采用的方法是将约束转换为边界。这当然不那么具有表现力(并不总是可行;但对于你的小例子而言),但这些界限在迭代中得到尊重!

eps = 1e-12
def constr(x,b):
    return x-b-eps

(当然:不要使用最小化进行单维优化。最小化数量。)

答案 1 :(得分:-1)

我不知道scipy的最小化是如何起作用的,但我认为你没有遵循约束条件是正确的。

如果在obj(x,b)中,我尝试打印x - b,那么当它抛出错误时,我会得到最后一个循环的负输出。

但这并不奇怪。你最小化的函数基本上是log(z),约束为z> 0.这不会很慢收敛......:p

编辑:将关键字参数“tol”(误差容差)设置为大约0.1,以便最小化器消除错误(如minimize(..., tol=0.1)中所示)。我仍然不知道为什么它首先如此重要。

编辑(因为我仍然无法发表评论): @sascha,这是有道理的,但为什么函数甚至评估x-b的负值?为了更好地优化其中的解决方案,最小化功能是否在其约束之外“测试”? (如果我将此问作为一个新问题,请告诉我。)