小区间上常数的最小化python函数

2024-04-18 21:23:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我想最小化一个有边界和约束的区域上的凸函数,因此我尝试使用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)))

产生以下输出:

^{pr2}$

我们当然知道这是错误的,但是f_disc的定义欺骗了优化器相信它在给定索引下是常量。对于我的问题,我只有f_disc,没有f的权限。此外,一次调用f_disc可能需要一分钟的时间。在


Tags: 函数import区域定义选项np时间random
1条回答
网友
1楼 · 发布于 2024-04-18 21:23:50

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

这里有两个可行的选择。

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])

^{}是一个优化器,它对平滑度没有任何假设。它不能只处理边界;它需要边界。然而,它需要比nelder mead更多的功能评估。

^{pr2}$

相关问题 更多 >