Scipy最小化熊猫df中的约束

时间:2018-12-04 17:43:07

标签: python optimization scipy

我正在尝试运行https://www.chromium.org/developers/gn-build-configuration中的最小化过程。在pdf文件的第16页的第6页上可以看到该方程。

我有一个如下所示的数据框

 df = pd.DataFrame({'h_t':[7.06398,6.29948,5.04570,6.20774,4.80106],           
'p_atm':[101057.772801,101324.416001,101857.702401,101724.380801,101991.024001],
    'q_p':[5.768132,3.825600,2.772215,5.830429,2.619304],
    'q_s':[2.684433,3.403679,2.384275,1.008078,2.387106],
    'tdg_f':[117.678100,110.131579,108.376963,103.669725,113.594771],
    'tdg_tw':[121.052635,119.710907,114.921463,112.156868,115.444900],
    'temp_water':[11.92,19.43,16.87,7.45,11.83]})

我有一个约束说下面的函数必须为正,其中b1和b3是我正在优化的系数。

def q_ge(q_p,q_s,b1,b3):   
    return min(q_p,(b1*q_s+b3))

我在下面写下了约束,但是不确定是否正确。

def constraint_q_ge(x):
    b1,b2,b3=x
    power_flow = df.apply(lambda x:q_ge(x['q_p'],x['q_s'],b1,b3), axis = 1)
    const = power_flow<0
    return -const.sum()

这是正确的吗?我在所有行上运行该函数,并检查是否小于0并将其求和。该总和的负数应大于或等于0。即使单个值小于0,也不能满足此约束条件。

编辑:

下面是完整的问题。

from scipy.constants import g as gravity
from sklearn.metrics import mean_squared_error
from math import sqrt
from scipy.optimize import minimize
import warnings

try:
    from numpy import any as _any
except ImportError:
    def _any(arg):
        if arg is True:
            return True
        if arg is False:
            return False
        return any(arg)

def water_density(T=None, T0=None, units=None, a=None,
                  just_return_a=False, warn=True):
    if units is None:
        K = 1
        m = 1
        kg = 1
    else:
        K = units.Kelvin
        m = units.meter
        kg = units.kilogram
    if T is None:
        T = 298.15*K
    m3 = m**3
    if a is None:
        a = (-3.983035*K,  # C
             301.797*K,  # C
             522528.9*K*K,  # C**2
             69.34881*K,  # C
             999.974950*kg/m3)
    if just_return_a:
        return a
    if T0 is None:
        T0 = 273.15*K
    t = T - T0
    if warn and (_any(t < 0*K) or _any(t > 40*K)):
        warnings.warn("Temperature is outside range (0-40 degC)")
    return a[4]*(1-((t + a[0])**2*(t + a[1]))/(a[2]*(t + a[3])))


def celsius_to_kelvin(t_celsius):
    return t_celsius+273.15


def tailwater(h_t, temp_water, p_atm):
    t_water_kelvin = celsius_to_kelvin(temp_water)
    rho = water_density(t_water_kelvin)
    g = gravity
    return (1+(rho*g*h_t)/(2*p_atm))

def tailwater_tdg(q_s,q_p,x, h_t,temp_water,p_atm,tdg_f):
    b1,b2,b3=x
    A = ((q_s+b1*q_s+b3)/(q_s+q_p))
    B = tailwater(h_t, temp_water, p_atm)
    C = ((q_p-b1*q_s-b3)/(q_s+q_p))

    return 100*A*B*b2+tdg_f*C

def q_ge(q_p,q_s,b1,b3):
    return min(q_p,(b1*q_s+b3))


def rmse(y, y_hat):
    return sqrt(mean_squared_error(y,y_hat))

def objective(x):
    y_hat = df.apply(lambda r:tailwater_tdg(q_s=r['q_s'],q_p=r['q_p'],x=x, h_t=r['h_t'],temp_water=r['temp_water'],p_atm=r['p_atm'],tdg_f=r['tdg_f']), axis = 1)
    y = df['tdg_tw']
    return rmse(y, y_hat)

#constraints and bounds for optimization model.  See reference for more information
def constraint_q_ge(x):
    b1,b2,b3=x
    power_flow = df.apply(lambda x:q_ge(x['q_p'],x['q_s'],b1,b3), axis = 1)
    const = power_flow<0
    return -const.sum()

constraints = [{'type':'ineq', 'fun':constraint_q_ge}]          
bounds = [(-500,10000),(.00001,10000),(-500,10000)]
x0=[1,1,1]
sol = minimize(objective, x0, method = 'SLSQP',constraints = constraints, bounds = bounds,options={'disp':True, 'maxiter':100})

0 个答案:

没有答案