Scipy Minimize - Невозможно минимизировать целевую функцию

Я пытаюсь оптимизировать функцию, чтобы найти максимальное значение rev_tot используя scipy свести к минимуму. Вот 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 не показывает изменений в исходном значении. Я не могу понять, почему минимизация не происходит.

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)
Различные решатели решают одни проблемы лучше, чем другие. Измените свой решатель на "Nelder-Mead". Выход:

[63.07910156]

введите описание изображения здесь

Решение 2)
Увеличьте ваше возвращаемое значение с return 1000000/rev_tot для решателя "SLSQP". Выход:

[63.07110511]

введите описание изображения здесь

Другие вопросы по тегам