Scipy Minimize - Unable to minimize objective function

谁都会走 提交于 2019-12-24 18:33:01

问题


I am trying to optimise a function to find max value of rev_tot using scipy minimise. Here obj_data is a list of probabilities, prem is a constant and inc can take any real value. Following is the code I have written for the objective function :

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

I want to find the inc value which will minimize 1/rev_tot(and thus maximising rev_tot. When I call:

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

the function runs, but solve.x shows no change in initial value. I am unable to figure out why the minimisation is not happening.


回答1:


Your problem is that the solver has to deal with tiny numbers due to your return 1/rev_tot. Hence changes over the x-axis are not well reflected in changes in y-values and the solver estimates that it has already converged:

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

Output:

[2.]

Solution 1)
Different solvers manage certain problems better than others. Change your solver to "Nelder-Mead". Output:

[63.07910156]

Solution 2)
Scale up your return value with return 1000000/rev_tot for solver "SLSQP". Output:

[63.07110511]



来源:https://stackoverflow.com/questions/51459467/scipy-minimize-unable-to-minimize-objective-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!