Я хочу минимизировать следующую функцию:
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 всегда имеет четную длину):
Для каждой пары в list (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.
Есть ли способ реализовать это?