【问题标题】:Minimization python function which is constant on small intervals最小化python函数,它在小间隔上是恒定的
【发布时间】:2018-09-05 18:41:50
【问题描述】:

我想最小化具有边界和约束的区域上的凸函数,因此我尝试将scipy.optimize.minimizeSLSQP 选项一起使用。但是,我的功能仅在离散点定义。线性插值似乎不是一种选择,因为以所有值计算我的函数会花费太多时间。作为一个最小的工作示例,我有:

from scipy.optimize import minimize
import numpy as np

f=lambda x : x**2

N=1000000
x_vals=np.sort(np.random.random(N))*2-1
y_vals=f(x_vals)

def f_disc(x, x_vals, y_vals):
    return y_vals[np.where(x_vals<x)[-1][-1]]

print(minimize(f_disc, 0.5, method='SLSQP', bounds = [(-1,1)], args = (x_vals, y_vals)))

产生以下输出:

     fun: 0.24999963136767756
     jac: array([ 0.])
 message: 'Optimization terminated successfully.'
    nfev: 3
     nit: 1
    njev: 1
  status: 0
 success: True
       x: array([ 0.5])

我们当然知道这是错误的,但是f_disc 的定义欺骗了优化器,使其相信它在给定索引处是恒定的。对于我的问题,我只有f_disc 并且无权访问f。此外,拨打f_disc 可能需要一分钟。

【问题讨论】:

  • 您能描述一下您要解决的问题吗?我什至无法绘制你的函数来感受我们在这里看到的内容......另外,x_valsy_vals 都是单调递增的,所以它们中的 min 不会只是第一个值?
  • SLSQP 确实期望平滑函数。
  • @NilsWerner :该函数只是f(x)=x**2,在这种情况下,最小值应该是最接近零的x值。 @ErwinKalvelagen:我可以使用其他一些优化方法,我也可以给出约束和界限吗?
  • 那么x_vals[np.argmin(y_vals)]呢?
  • 问题是np.argmin(y_vals) 要求我们为所有x_vals 计算f(x),这正是我们无法做到的。您应该假设只给出了函数f_disc,并且每次调用f_disc 都需要很长时间。

标签: python numpy optimization scipy minimization


【解决方案1】:

如果您的函数不平滑,基于梯度的优化技术将会失败。当然你可以使用不基于梯度的方法,但是这些通常需要更多的函数评估。

这里有两个可行的选项。

nelder-mead method 不需要渐变,但它的缺点是无法处理边界或约束:

print(minimize(f_disc, 0.5, method='nelder-mead', args = (x_vals, y_vals)))

 #  final_simplex: (array([[ -4.44089210e-16], [  9.76562500e-05]]), array([  2.35756658e-12,   9.03710082e-09]))
 #            fun: 2.3575665763730149e-12
 #        message: 'Optimization terminated successfully.'
 #           nfev: 32
 #            nit: 16
 #         status: 0
 #        success: True
 #              x: array([ -4.44089210e-16])

differential_evolution 是一个优化器,不对平滑度做任何假设。它不能只处理边界;它需要它们。但是,它比 nelder-mead 需要更多的功能评估。

print(differential_evolution(f_disc, bounds = [(-1,1)], args = (x_vals, y_vals)))

#     fun: 5.5515134011907119e-13
# message: 'Optimization terminated successfully.'
#    nfev: 197
#     nit: 12
# success: True
#       x: array([  2.76298719e-06])

【讨论】:

    猜你喜欢
    • 2014-02-14
    • 1970-01-01
    • 2011-01-30
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    相关资源
    最近更新 更多