【问题标题】:Scipy Minimize - Unable to minimize objective functionScipy Minimize - 无法最小化目标函数
【发布时间】:2018-07-22 19:17:33
【问题描述】:

我正在尝试优化一个函数以使用 scipy minimise 找到 rev_tot 的最大值。这里obj_data 是一个概率列表,prem 是一个常数,inc 可以取任何实际值。以下是我为目标函数编写的代码:

import numpy as np
import pandas as pd
import scipy
from scipy.optimize import minimize

def objective(x,*args):

    prem = args[0]
    prob = args[1]
    inc = x[0]


    rev_tot = 0
    rev = 0
    del_p = 0.2*(1-np.exp(-2*(1-np.exp(-inc/400))))
    for i in range(len(prob)):
        rev = (prob[i]*(1+del_p)*prem) - inc
        rev_tot = rev_tot + rev
    return 1/rev_tot


prem = 3300
par = [0.9,0.1,0.5,0.4]
x0 = np.array([3]) # initial guess
solve = minimize(objective,x0,args=(prem,par),method='SLSQP')
solve.x

我想找到inc 值,它将最小化1/rev_tot(从而最大化rev_tot。 当我打电话时:

minimize(objective,x0,args=(prem,par),method='SLSQP')

函数运行,但solve.x 显示初始值没有变化。我无法弄清楚为什么没有发生最小化。

【问题讨论】:

  • 这不是Minimal, Complete, and Verifiable example 并且缩进显然不符合预期。请编辑您的问题。
  • 先生。 T 给出了一个描述一个最小的、完整的和可验证的例子的链接。您已经向我们展示了您的目标函数,但您的示例并不完整且不可验证。如果可以在不进行编辑的情况下复制和运行代码以重现问题,那么有人会更容易帮助您。
  • 来自documentation of minimize:“要最小化的目标函数。fun(x, *args) -> float 其中 x 是一个形状为 (n,) 的一维数组,而 args 是一个固定参数的元组完全指定功能。” objective的参数不符合这种格式。
  • 谢谢,Shreyas,但它还没有完成。如果现在运行代码,minimize 将引发异常 TypeError: objective() missing 2 required positional arguments: 'inc' and 'prem'。我怀疑你错过了args=(inc, prem)。此外,minimize 的第二个参数是x0,这是最小化代码使用的初始猜测。你通过了inc,这几乎肯定是不正确的——也许你认为这样可以代替使用args。再看看minimize docstring 了解更多信息。
  • 你的代码适合我

标签: python optimization scipy minimize


【解决方案1】:

您的问题是,由于您的return 1/rev_tot,求解器必须处理微小的数字。因此,x 轴上的变化不能很好地反映在 y 值的变化中,求解器估计它已经收敛:

import numpy as np
import pandas as pd
import scipy
from scipy.optimize import minimize

def objective(x,*args):

    prem = args[0]
    prob = args[1]
    inc = x[0]

    rev_tot = 0
    rev = 0
    del_p = 0.2*(1-np.exp(-2*(1-np.exp(-inc/400))))
    for i in range(len(prob)):
        rev = (prob[i]*(1+del_p)*prem) - inc
        rev_tot = rev_tot + rev
    return 1/rev_tot

prem = 3300
par = [0.9,0.1,0.5,0.4]
x0 = np.array([2]) # initial guess
solve = minimize(objective,x0,args=(prem,par),method='SLSQP')
x_min = solve.x
print(x_min)
#plot your function to visualize the outcome
x_func = np.linspace(1, 100, 1000)
y_func = []
for item in x_func:
    y_func.append((objective(np.asarray([item]), prem, par)))

y_min = objective(np.asarray([x_min]), prem, par)

plt.plot(x_func, y_func)
plt.plot(x_min, y_min, "ro")
plt.show()

输出:

[2.]

解决方案 1)
Different solvers manage certain problems better than others. 将您的求解器更改为“Nelder-Mead”。输出:

[63.07910156]

解决方案 2)
使用 return 1000000/rev_tot 为求解器“SLSQP”扩大您的回报值。输出:

[63.07110511]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-13
    • 2019-09-01
    • 1970-01-01
    • 2019-05-17
    • 2016-05-27
    • 2018-01-30
    • 2015-02-18
    相关资源
    最近更新 更多