我想最小化以下功能:
def objective(B, P, O):
return - (sum([(p * o - 1) * b for p, o, b in zip(P, O, B)]) /\
math.sqrt(sum([(1-p) * p * b**2 * o**2 for p, o, b in zip(P, O, B)])))
sol = minimize(objective, x0=bets, args=(P,O,), method='SLSQP', bounds=bnds, constraints=constr)
我想将以下约束添加到B = [1,2,3,4,5,6,....]
(B 始终具有偶数长度):
对于列表 (1,2), (3,4), (5,6)... (b1,b2) 中的每一对,在优化结束时,这两个值中的一个应该变为 0。所以从逻辑的角度来看:b1 + b2 = b1 xor b1 + b2 = b2
如果我把它写成一个约束,它看起来像这样:
def constb(B):
for i in range(0, len(B), 2):
b1, b2 = B[i:i+2]
if b1 == 0.0:
return b2 + b1 - b2
elif b2 == 0.0:
return b1 + b2 - b1
else:
return 42
约束如下所示:
constr = [{'type': 'ineq', 'fun': lambda x: sum(x) - 100},
{'type': 'eq', 'fun': constb}]
但它不起作用,因为我的配对最后看起来像这样(我的每个值的界限是(0,20)):
20.0 20.0
20.0 20.0
20.0 20.0
20.0 20.0
20.0 20.0
看起来算法默认在else
语句的约束中。我尝试将 B 初始化为 0,但随后出现 MathError,因为不能除以 0。
有没有办法实现这个?