用纸浆蟒蛇求解模型

问题描述

我一直在努力解决以下问题: 我将一些值存储在变量 returns 中,我想将它们乘以权重( x_vars ),以求乘积的总和并获得变量 target_return 。如下式:

$$\sum_{i=0}^{n}(returns_i\cdot x_var_i)  = target_return$$

我正在为返回的答案而苦苦挣扎,因为它说x_13 =1。但这是不正确的。我已经尝试使用常规约束和弹性来做到这一点,但我没有正确的答案。我可以容忍误差为0.01%。

有猜到吗?

谢谢

import pulp as plp
# Name model
# set variables   
target_return = 0.0204185791833761
returns = [0.025865338474480914,0.031617753987556174,0.017530329404997325,-0.0008543358059154293,0.010510143115372461,0.012048338516174262,0.04959181591738604,0.06059545751936519,0.05926623356137273,0.058971753714631814,0.03442022388647947,0.013688974565667422,0.02104075216985901,-0.0021299262578251543,0.017882182143459602,0.018964184657020766,0.005792320704504306,0.018823216764509265,-0.0015860431556348198,0.008352716776521163,0.030728674721250515,0.016529301951210496,0.0184734317514465,-0.0008822232596910062,0.010912806711330658,0.023530497410194418,0.0378090116601979,0.009456335242604919,0.005556382185357922,0.020013334218681678,0.05852489326632937,0.047988175193893645,0.016134386609760742,0.014350880108888964,0.006756782462879585]

# Initialize model
prob=plp.LpProblem("Find Weights Model",plp.LpMinimize)
x_vars=plp.LpVariable.dicts("x",range(0,len(returns)),1)
for index in range(len(returns)):
    x_vars[index].setInitialValue(0.5)

#Set problem
prob += plp.lpSum([x_vars[i] for i in x_vars]) == 1

#Set constrain
constrain=plp.LpConstraint(plp.lpSum(
    [returns[i]*x_vars[i] for i in range(0,len(returns))]),rhs=target_return)
# To use standard constrain uncomment following line
#prob.addConstraint(constrain)
# To use elastic constrain uncomment following line
elastic_constrain=constrain.makeElasticSubProblem(penalty = 500000,proportionFreeBoundList  =[0.001,0.0001])
prob.extend(elastic_constrain) 


prob.solve(plp.PULP_CBC_CMD(msg=True,warmStart=True))
final_weights={}
for v in prob.variables():
    final_weights[v.name]=v.varValue

print("Status:",plp.LpStatus[prob.status])

final_weights

可能的解决方案:

solution1 = [0.00962135141677065,0.00962135141677065,0.0277264834687149,0.0297957188693739,0.0324961558793471,0.030826881062523,0.0306009427392119,0.0250863577897657,0.0234700849350161,0.0236653284777789,0.0237085827820698,0.0273148420035226,0.0303599573647406,0.0292800893464517,0.0326835213770196,0.0297440370126145,0.0295851066643113,0.0315198597719625,0.0296058126214705,0.0326036329340179,0.0311437752841399,0.0278570759221869,0.0299427552142207,0.0296571910611703,0.0325002521378998,0.0307677356659276,0.0289143823239777,0.0268170787933395,0.0309816698637205,0.0315545156635921,0.0294310019878726,0.023774220455596,0.0253219090166822,0.0300007623180508,0.0302627332639599]

solution2 = [0.0291039150753347,0.0291039150753347,0.028739103831572,0.0296325128619877,0.0307984495156388,0.0300777243941537,0.0299801757193628,0.027599206714805,8.34695965451632E-05,0.0269856659961344,0.0270043421537945,0.0285613748092319,0.0298761263170002,0.0294098868961038,0.0308793458966854,0.0296102001652331,0.0295415791679557,0.0303769265588311,0.0295505206943934,0.0308448536374279,0.0302145485146196,0.0287954885757358,0.0296959977222549,0.0295727013961937,0.030800217918514,0.0300521885203749,0.0292519883685474,0.0283464607865791,0.0301445556616913,0.030391887092054,0.0294750434895131,0.0270326804365011,0.0277009088398652,0.0297210421051448,0.0298341506415484]

在excel中,我使用以下配置获得了解决方案:

enter image description here

解决方法

我认为您从纸浆(CBC)中获得的解决方案是正确的,只是与Excel中的解决方案不同。要确认遵守约束条件,您可以执行以下操作:

solution3 = [x.value() for x in x_vars.values()]

# objective: 0.0204185791833761
sum(val*returns[i] for i,val in enumerate(solution1))
# 0.02053629325573023
sum(val*returns[i] for i,val in enumerate(solution3))
# 0.02039816058427895

# constraint:
sum(val for i,val in enumerate(solution1))
# 0.9782431569057903
sum(val for i,val in enumerate(solution3))
# 0.999999999

实际上,纸浆的解离目标更近,并且对sum()= 1的约束要尊重得多。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...