在 DocPlex 中将线性表达式传递给二次形式时出错
Error Passing a Linear Expression to a Quadratic Form in DocPlex
我有一个带有“主动风险”术语的 cplex/docplex 模型。我相信我搞砸了 Pandas 和 DocPlex 的组合,但我担心我正在尝试做一些不可能的事情。
该术语应该只是二次形式 (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)
报错
AttributeError: 'LinearExpr' object has no attribute '_index'
有趣的是,像下面这样的东西起作用了。所以我可以将所有变量移动为差异,但我会尽可能避免这种情况,因为这会使优化中的其他复杂术语变得不那么清晰。
# 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
问题来自于两个事件的结合:
Model.quad_sum
需要变量,而不是表达式,如文档中所述
- 出于性能原因,class
AdvModel
禁用参数类型检查。但这可以重新启用。
为 AdvModel 重新启用类型检查(例如调用 AdvModel(checker='on')会产生正确的错误消息:
docplex.mp.utils.DOcplexException: Expecting an iterable returning variables, docplex.mp.LinearExpr(Target_AAA-0.250) was passed at position 0
要计算表达式的二次形式,请使用 Model.sum()
,如:
#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)
产生
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
我有一个带有“主动风险”术语的 cplex/docplex 模型。我相信我搞砸了 Pandas 和 DocPlex 的组合,但我担心我正在尝试做一些不可能的事情。
该术语应该只是二次形式 (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)
报错
AttributeError: 'LinearExpr' object has no attribute '_index'
有趣的是,像下面这样的东西起作用了。所以我可以将所有变量移动为差异,但我会尽可能避免这种情况,因为这会使优化中的其他复杂术语变得不那么清晰。
# 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
问题来自于两个事件的结合:
Model.quad_sum
需要变量,而不是表达式,如文档中所述- 出于性能原因,class
AdvModel
禁用参数类型检查。但这可以重新启用。
为 AdvModel 重新启用类型检查(例如调用 AdvModel(checker='on')会产生正确的错误消息:
docplex.mp.utils.DOcplexException: Expecting an iterable returning variables, docplex.mp.LinearExpr(Target_AAA-0.250) was passed at position 0
要计算表达式的二次形式,请使用 Model.sum()
,如:
#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)
产生
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