Как выразить квадратичную цель в Docplex на python

#python #cplex #docplex

Вопрос:

Если кто-нибудь может помочь ,я не могу выразить целевую функцию, это мой код:

 import numpy as np
def portfolio_return( weights, returns):
    return weights.T @ returns

def portfolio_vol( weights, covmatrix):
    return np.sqrt(weights.T @ covmatrix @ weights)

def sharp_ratio(er,covmat,w,rf = 0.01):
    r_p = portfolio_return(w, er)/100
    sigma_p = portfolio_vol(w,cov)/100
    return (r_p-rf)/sigma_p

w = mdl.integer_var_list(5,5,30, 'w')
mdl.add_constraint(mdl.sum(w) == 100)
mdl.minimize(-sharp_ratio(quartered_er, cov,np.array(w)))
 

Но я получаю эту ошибку:

цикл ufunc не поддерживает аргумент 0 типа QuadExpr, который не имеет вызываемого метода sqrt

Ответ №1:

Вы можете использовать numpy для некоторых вычислений после решения, но ограничения должны быть описаны с помощью функций из docplex.

Например, квадратичный пример из истории упрощения оптимизации с помощью python

 from docplex.mp.model import Model

mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40   nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40**2*500   nbbus30**2*400)

mdl.solve()

for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value)

import numpy as np
print("We bring ",np.array(
    [40,30])@np.array([nbbus40.solution_value,nbbus30.solution_value])
      ," kids to the zoo")
 

дает

 nbBus40  =  4.0
nbBus30  =  5.0
We bring  310.0  kids to the zoo
 

Комментарии:

1. Спасибо Алексу за повтор, у меня все еще есть проблема, потому что решатель ищет w как список, а целевая функция использует w.T, который можно вычислить, если w не является массивом. Не могли бы вы, пожалуйста, дать мне еще одно предложение?

2. Я удалил w.T из функции objectif, и я получаю эту ошибку : Не удается поднять 0.000w_0^2 0.000w_0*w_1 0.000w_0*w_2 0.000w_0*w_3 0.000w_0*w_4 0.000w_1^2 0.000w_1*w_2 0.000w_1*w_3 0.000w_1*w_4 0.000w_2^2 0.000w_2*w_3 0.000w_2*w_4 0.000w_3^2 0.000w_3*w_4 0.000w_4^2 в степени 0,5. Показатель переменной должен быть 0, 1 или 2.

3. это потому, что w объявлен как список : w = mdl.integer_var_list(5,5,30, ‘w’)

4. Model.minimize принимает линейные или квадратичные выражения, в Docplex нет оператора квадратного корня (на самом деле, в любом API CPLEX). Квадратичные выражения могут быть сформированы путем умножения линейных выражений или степенных выражений, как в x**2.