Как оптимизировать несколько переменных с optimize.minimize? - PullRequest
0 голосов
/ 08 октября 2019

Я пытаюсь оптимизировать функцию со многими переменными.

Я использовал функцию optimize.minimize с несколькими решателями. например, Nelder-Mead (см. здесь)

'Пауэлл' (см. здесь)

'CG' (см. здесь)

'BFGS' (см. здесь)

'Ньютон-CG' (см. Здесь)

'L-BFGS-B' (см. Здесь)

'TNC' (см. Здесь)

'COBYLA '(см. Здесь)

import scipy.optimize as optimize import numpy as np

""" test no 146"""
A = 0.1/730     # WACC / days
OI_init = 800
WAMC_init = 690

n=28
def f(params):
    # print(params)  # <-- you'll see that params is a NumPy array

    y=np.zeros(n)   #need to define first
    x=np.zeros(n)
    z=np.zeros(n)
    OI=np.zeros(n)
    OI[0] = OI_init
    cons = np.ones(n)*100
    wamc = np.ones(n)*690
    #WAMC[0] = WAMC_init

    x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10],x[11],x[12],x[13],\
    x[14],x[15],x[16],x[17],x[18],x[19],x[20],x[21],x[22],x[23],x[24],x[25],x[26],x[27],\
    y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],\
    y[14],y[15],y[16],y[17],y[18],y[19],y[20],y[21],y[22],y[23],y[24],y[25],y[26],y[27],\
    z[0],z[1],z[2],z[3],z[4],z[5],z[6],z[7],z[8],z[9],z[10],z[11],z[12],z[13],\
    z[14],z[15],z[16],z[17],z[18],z[19],z[20],z[21],z[22],z[23],z[24],z[25],z[26],z[27],\
    = params # <-- for readability you may wish to assign names to the component variables

    return A*((2*OI[0] + x[0] + y[0] + z[0] - cons[0])/\
            (OI_init + x[0] + y[0]+z[0]) * (OI_init*wamc[0] + 688*x[0] \
            + 713*y[0]+627*z[0]))  + 688*x[0] + 713*y[0]+627*z[0] \
              + sum ([A*(((2*(OI[i-1] + x[i-1] + y[i-1] + z[i-1] - cons[i-1]) + x[i] + y[i] + z[i] - cons[i]))/\
            ((OI[i-1] + x[i-1] + y[i-1] + z[i-1] - cons[i-1]) + x[i] + y[i]+z[i]) * ((OI[i-1] + x[i-1] + y[i-1] + z[i-1] - cons[i-1])*wamc[i-1] + 688*x[i] \
            + 713*y[i]+627*z[i]))  + 688*x[i] + 713*y[i]+627*z[i] for i in range (1,n)])

a = (0,250) #bounds x
b = (0,300) #bounds y
c = (0,300) #bounds z

d = (a*28+b*28+c*28)
e=[(d[a], d[a+1]) for a in range(0,len(d),2)]
bnds = tuple(e)
initial_guess = np.ones(n*3)
cons = ({'type': 'ineq', 'fun': lambda x:  x[0] + x[1] + x[2]+ x[3] + x[4] + \
         x[5] + x[6] + x[7] + x[8] + x[9] + x[10] +x[11] +x[12]+x[13]+x[14]+ \
         x[15]+x[16]+x[17]+x[18]+x[19]+x[20]+x[21] +x[22]+x[23] +x[24]+x[25] +x[26]+x[27]- 1800},\
        {'type': 'ineq', 'fun': lambda y:  y[0] + y[1] + y[2]+ y[3] + y[4] + \
         y[5] + y[6] + y[7] + y[8] + y[9] + y[10] +y[11] +y[12]+y[13]+y[14]+ \
         y[15]+y[16]+y[17]+y[18]+y[19]+y[20]+y[21] +y[22]+y[23] +y[24]+y[25] +y[26]+y[27] - 600},
        {'type': 'ineq', 'fun': lambda z:  z[0] + z[1] + z[2]+ z[3] + z[4] + \
         z[5] + z[6] + z[7] + z[8] + z[9] + z[10] +z[11] +z[12]+z[13]+z[14]+ \
         z[15]+z[16]+z[17]+z[18]+z[19]+z[20]+z[21] +z[22]+z[23] +z[24]+z[25] +z[26]+z[27] - 600}) 

result = optimize.minimize(f, initial_guess,method='COBYLA', bounds=bnds,constraints=cons,options={'rhobeg': 1.0, 'maxiter': 50000, 'disp': False, 'catol': 0.0002})
#result = optimize.minimize(f, initial_guess,method='Nelder-Mead' , bounds=bnds,constraints=cons)

if result.success:
    fitted_params = result.x
    print(fitted_params)
else:
    raise ValueError(result.message)

Я ожидаю, что значение для каждого параметра будет находиться в пределах указанных границ (например, 0- 250 для x, 0-300 для y и т. Д.) Однако возвращаемые значения являются следующими:

[64.36575819 64.36140615 64.1978667 64.19795296 66.70698926 64.19744574 64.1996505 64.20011174 64.1983 534 64.199390 64.1671 641 591 591 591 591 581 591 591 591 591 591 591 591 591 591 599199199529199599599170599599599599599599599570560570570560570500570570500570570500570570570570570570570570570570570599599599599000000000000000000000057064.19952948 64.19959002 64.19906142 64.19570926 64.19864776 64.19758665 64.19937635 64.16204073 -220,54936485 -220,5465085 -220,81683226 -220,25854439 -220,82215693 -220,44374353 -220,6326799 -218,76761632 -220,88232356 -221,06507529 -220,90425765 -220,44294542 -220,60071103 -221,05849399 -220,70571828 -221,12106582 -221,1196567 -221,53333488 -220,82655726 -220,59355591 -221,58765192 -221,04768086 -220,90414376 -220,25808954 -220,71251054 -221,34281041 -222,89489171 -220,46492692 -193,80092262 -193,83038434 -193,52419382 -193,6330308 -193,80679929 -194,88399831 -194,1795782 -193,8016101 -194.17360397 -194,06095671 -194,19153064 -193,76369698 -194,12841897 -193,46745685 -193,77441914 -194,17699638 -193,92509365 -193,70122136 -193,971702 -194,11101313 -194,17535903 -193,98580005 -193,47109855 -193,47078731 -193,41173464 -193,52010863 -195,12203737 -193,3681346]

1025 * есть только хнаходятся в пределах границы, но у, а z принимает отрицательные значения.

любая помощь будет принята с благодарностью. Заранее спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...