You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scipy约束最小化未遵守等式约束问题咨询

Why Your L-BFGS-B Solution Doesn't Satisfy the Sum-to-1 Constraint (and Fixes)

Let's cut to the chase: the L-BFGS-B optimizer in SciPy ignores your equality constraint entirely. Here's why, and how to fix it:

The Root Cause

L-BFGS-B is built exclusively for optimization problems with only bound constraints (like your 0 ≤ q_i ≤ 1 limits). It has no support for equality or inequality constraints—any constraints parameter you pass to it will be silently ignored. That’s exactly why your solution’s elements don’t sum to 1: the constraint was never applied in the first place.

Fix 1: Switch to an Optimizer That Supports Constraints

The simplest, most reliable fix is to use SciPy's SLSQP method, which natively handles both equality and bound constraints. Here’s how to adjust your code:

import numpy as np
from scipy.optimize import minimize

def EV(q, P):
    return (-1)*np.sum(100 * q * (2*P - 1))

# Replace with your actual P and initial guess X0
P = np.random.rand(12)  # Example given 12D array
X0 = np.ones(12) / 12   # Initial uniform distribution (sum=1)

# Define constraints and bounds
cons = {'type': 'eq', 'fun': lambda q: np.sum(q) - 1}
bds = [(0, 1)] * 12

# Use SLSQP instead of L-BFGS-B
result = minimize(
    EV,
    X0,
    args=(P,),
    method='SLSQP',
    bounds=bds,
    constraints=cons,
    tol=1e-8  # Optional: tighten tolerance for stricter constraint satisfaction
)

# Verify the solution
print(f"Sum of optimized q: {np.sum(result.x):.8f}")
print(f"Optimization success: {result.success}")

SLSQP will enforce your sum-to-1 rule while respecting the 0-1 bounds on each element. For most use cases, this is the best approach.

Fix 2: Reparameterize Variables to Eliminate the Equality Constraint

If you specifically need to use L-BFGS-B (e.g., for performance with large-scale problems), you can reparameterize your variables to embed the sum-to-1 constraint directly into the objective function. Since sum(q) = 1, you only need 11 independent variables—derive the 12th as q_12 = 1 - sum(q_1 ... q_11).

For a cleaner fit with L-BFGS-B, use a softmax transformation to automatically enforce the probability simplex (sum=1, all elements ≥0):

import numpy as np
from scipy.optimize import minimize

def EV_softmax(z, P):
    # Convert unconstrained z values to valid q via softmax
    q = np.exp(z) / np.sum(np.exp(z))
    return (-1)*np.sum(100 * q * (2*P - 1))

# Example inputs
P = np.random.rand(12)
X0_softmax = np.zeros(12)  # Simple initial guess

# Use L-BFGS-B with loose bounds for z (softmax handles the simplex)
result = minimize(
    EV_softmax,
    X0_softmax,
    args=(P,),
    method='L-BFGS-B',
    bounds=[(-10, 10)]*12
)

# Convert back to the original q variable
q_opt = np.exp(result.x) / np.sum(np.exp(result.x))
print(f"Sum of optimized q: {np.sum(q_opt):.8f}")

The softmax transformation ensures q automatically meets the sum-to-1 and non-negativity rules, so you don’t need any constraints at all—perfect for L-BFGS-B’s bound-only design.

Key Takeaways

  • L-BFGS-B does not support equality/inequality constraints—only use it for problems with variable bounds.
  • For constrained problems, SLSQP is the standard go-to method in SciPy.
  • If you must use L-BFGS-B, reparameterize variables to embed constraints into the objective function (like softmax for simplex rules).

内容的提问来源于stack exchange,提问作者Davide Floriello

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:54:22