在DocPlex中将线性表达式传递给二次形式时出错 [英] Error Passing a Linear Expression to a Quadratic Form in DocPlex

查看:70
本文介绍了在DocPlex中将线性表达式传递给二次形式时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个cplex/docplex模型,其模型具有活动风险".学期.我相信我搞砸了Pandas和DocPlex的组合,但是我担心自己正在尝试做一些不可能的事情.

该术语应仅为二次形式(Target-Optimal)\ Sigma(Target-Optimal).

从docplex.mp.advmodel

 导入AdvModel来自numpy导入身份从pandas import Series,DataFrame型号= AdvModel()资产= ['AAA','BBB','CCC','DDD']最优=系列(1/4,资产)协方差= DataFrame(identity(4)* 0.10,index =资产,column =资产)目标=系列(model.continuous_var_list(资产,名称='目标',lb = 0,ub = 1),索引=资产)active_risk = model.quad_matrix_sum(协方差,目标-最佳)/2打印(active_risk) 

给出错误

  AttributeError:'LinearExpr'对象没有属性'_index' 

有趣的是,类似以下内容的作品.因此,我可以将所有变量都移为差值,但是我尝试尽可能避免这种情况,因为这样会使优化中的其他复杂术语变得不太清楚.

 #lb,ub现在很复杂差异=系列(model.continuous_var_list(资产,名称='目标',lb = lb,ub = ub),索引=资产)model.quad_matrix_sum(协方差,差)/2 

解决方案

问题来自两个事件的结合:

  1. Model.quad_sum 需要变量,而不是表达式,如文档中所述
  2. 出于性能原因,类 AdvModel 禁用参数的类型检查.但这可以重新启用.

重新启用AdvModel的类型检查(例如,调用AdvModel(checker ='on')会产生正确的错误消息:

  docplex.mp.utils.DOcplexException:期望返回的迭代变量docplex.mp.LinearExpr(Target_AAA-0.250)在位置0处传递 

要对表达式计算二次形式,请按以下方式使用 Model.sum():

  #active_risk = model.quad_matrix_sum(协方差,目标-最佳)/2大小= len(资产)active_risk = model.sum(covariances.iloc [i,j] *(target [i]-优化[i])*(target [j]-优化[j])适用于范围(大小)中的i适用于范围(大小)中的j)打印(active_risk) 

产生

0.100Target_AAA ^ 2 + 0.100Target_BBB ^ 2 + 0.100Target_CCC ^ 2 + 0.100Target_DDD ^ 2-0.050Target_AAA-0.050Target_BBB-0.050Target_CCC-0.050Target_DDD + 0.025

I have a cplex/docplex model with an "active risk" term. I believe I'm messing up the mix of Pandas and DocPlex, but I'm worried I'm trying to do something impossible.

The term should just be the quadratic form (Target-Optimal) \Sigma (Target-Optimal).

from docplex.mp.advmodel import AdvModel
from numpy import identity
from pandas import Series, DataFrame

model = AdvModel()
assets = ['AAA', 'BBB', 'CCC', 'DDD']
optimal = Series(1 / 4, assets)
covariances = DataFrame(identity(4) * 0.10, index=assets, columns=assets)

target = Series(model.continuous_var_list(assets, name='Target', lb=0, ub=1), index=assets)

active_risk = model.quad_matrix_sum(covariances, target - optimal) / 2
print(active_risk)

giving the error

AttributeError: 'LinearExpr' object has no attribute '_index'

Interestingly, something like the following works. So I could shift all the variables to be the difference but I'm trying to avoid this if possible as that would make other complicated terms in the optimization less clear.

# lb, ub are complicated now
difference = Series(model.continuous_var_list(assets, name='Target', lb=lb, ub=ub), index=assets)
model.quad_matrix_sum(covariances, difference) / 2

解决方案

The problem comes from the conjonction of two events:

  1. Model.quad_sum expects variables, not expressions, as indicated in the documentation
  2. For performance reasons, class AdvModel disables type-checking of arguments. But this can be re-enabled.

Re-enabling type-checking for AdvModel (e.g. calling AdvModel(checker='on') yields the right error message:

docplex.mp.utils.DOcplexException: Expecting an iterable returning variables, docplex.mp.LinearExpr(Target_AAA-0.250) was passed at position 0

To compute a quadratic form over expressions, use Model.sum() as in:

#active_risk = model.quad_matrix_sum(covariances, target - optimal) / 2
size = len(assets)
active_risk = model.sum(covariances.iloc[i,j] * (target[i] - optimal[i]) * (target[j] - optimal[j])
                        for i in range(size) for j in range(size))

print(active_risk)

which yields

0.100Target_AAA^2+0.100Target_BBB^2+0.100Target_CCC^2+0.100Target_DDD^2-0.050Target_AAA-0.050Target_BBB-0.050Target_CCC-0.050Target_DDD+0.025

这篇关于在DocPlex中将线性表达式传递给二次形式时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆