Невозможно минимизировать требуемый параметр - PullRequest
0 голосов
/ 20 сентября 2019

Я занимался этим часами, хотя раньше никогда не использовал минимизацию.Попытка найти минимальное значение для sig, а также соответствующее значение w1 и w2 для этого sig.мое ограничение в том, что w1 + w2 = 1 и w1 и w2 оба положительны.Я передаю некоторые случайные значения для x0, например x0 = [0.1, 0.9], но вместо того, чтобы минимизировать его, он просто посылает мне вычисленное значение для sig для этих x0 значений, но на самом деле это не сводит к минимуму.

ожидаетсяw1 = 0.389085, w2 = 0.61091, sig = 0.0001639

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

def objective(x,s1,s2,cov):
    w1=x[0]
    w2=x[1]
    std1=s1
    std2=s2
    covar=cov
    sig=(w1**2)*(std1**2)+(w2**2)*(std2**2)+(2*w1*w2*cov)
    return sig #find the lowest possible answer for this given w1+w2=1
#also the values of the given w1 and w2 for which sig is lowest

def ad(x):
    return x[0]+x[1]

def constraint(x):
    return 1-ad(x)

cons=({'type':'eq','fun':constraint})
w1=0.4
w2=0.6
x0=np.array([w1,w2])
std_dev1=0.016131666748327497
std_dev2=0.014246969689996261
co=0.000102553
sol=minimize(objective,x0,method='SLSQP',constraints=cons,args(std_dev1,std_dev2,co))
print(sol)

Редактировать: я успешно смог получить нужные данные, предоставив ввод для w1 и w2, которые не удовлетворяют ограничению, не знал об этомранее. Я добавил другое ограничение, так как хочу, чтобы значения w1 и w2 были между (0 и 1), но всякий раз, когда я использую bounds, я получаю вывод objective, где w1принимает значение 0 и w2 принимает значение 1, что не является наиболее оптимальным решением.

def objective(x,s1,s2,cov):
    w1=x[0]
    w2=x[1]
    std1=s1
    std2=s2
    covar=cov
    sig=(w1**2)*(std1**2)+(w2**2)*(std2**2)+(2*w1*w2*cov)
    return sig
#def ad(x):
#    return x[0]+x[1]
def constraint(x):
    return 1-x[0]-x[1]
def constraint2(x):
    return 1-x[0]**2-x[1]**2
cons=({'type':'eq','fun':constraint,},
        {'type':'ineq','fun':constraint2})
w1=100
w2=0
bnds=((0.0,1.0),(0.0,1.0))
x0=np.array([w1,w2])
std_dev1=0.016131666748327497
std_dev2=0.014246969689996261
co=0.000102553
sol=minimize(objective,x0,method='SLSQP',constraints=cons,args=(std_dev1,std_dev2,co))
print(sol.x)
print(sol.fun)

Примечание: -В приведенном выше коде я определяю bnds, но фактически не используюэто с аргументом bounds. Я заметил, что всякий раз, когда я использую bounds, код заканчивает тем, что возвращает мне значение w1 и w2 с минимальными и максимальными bounds и сам по себе не идет впередразработать оптимальное решение.Читая далее, я думаю, что это проблема численного дифференцирования Gradient без учета границ, которые я не могу понять.

Не стесняйтесь объяснять, как это не дает мне хорошее решение, когда я это делаюв конечном итоге ставить аргументы bounds.

sol=minimize(objective,x0,method='SLSQP',constraints=cons,args=(std_dev1,std_dev2,co),bounds=bnds)
...