用纸浆求解模型 python

Solving Model with pulp python

我一直在努力解决以下问题: 我有一些值存储在变量 returns 中,我想将它们乘以权重 (x_vars)求乘积之和,得到变量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)), 0, 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 中,我使用以下配置获得了解决方案:

我认为你从 pulp (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

事实上,pulp 的解更接近 objective 并且更好地遵守 sum()=1 的约束。