如何为skopt中gp_minimize的100维寻优添加非递增维度约束?
Nice question! When working with gp_minimize from skopt, handling non-increasing constraints (each dimension's value ≤ the previous one) requires a workaround since the function treats all dimensions as independent by default. The most efficient approach here is to transform your optimization variables so that the constrained space maps directly to the unconstrained hypercube that gp_minimize expects. Here's how to do it step by step:
Option 1: Variable Transformation (Recommended)
The key idea is to map a 100-dimensional unconstrained space (each variable ∈ [0,1]) to your desired non-increasing sequence. A simple, effective transformation uses multiplicative scaling:
Define the transformation function:
Convert an unconstrained vectorz(where eachz[i] ∈ [0,1]) into a non-increasing vectorx:def z_to_x(z): x = [z[0]] for i in range(1, len(z)): # Each subsequent x is the previous x multiplied by a value ≤1, ensuring non-increase x.append(x[-1] * z[i]) return xThis guarantees
x[0] ≥ x[1] ≥ ... ≥ x[99] ≥ 0and allx[i] ≤1, which fits your original space constraints.Wrap your objective function:
Modify your target function to accept the unconstrainedzvector, convert it tox, then compute your original objective:def constrained_objective(z): x = z_to_x(z) # Replace this with your original f(x) calculation return f(x)Run the optimization:
Use the same 100-dimensional [0,1] space as before, sincezis unconstrained:from skopt import gp_minimize space = [(0., 1.) for _ in range(100)] res = gp_minimize(constrained_objective, space)Retrieve the optimal constrained solution:
Convert the optimalzback to your desiredxsequence:optimal_x = z_to_x(res.x)
Option 2: Penalty Function (Not Recommended for High Dimensions)
If you prefer a simpler (but less efficient) approach, you can add a large penalty to any point that violates the non-increasing constraint. However, this is not ideal for 100-dimensional spaces, since random samples will almost never satisfy the constraint, slowing down optimization:
def constrained_f(x): # Check if the sequence is non-increasing for i in range(1, len(x)): if x[i] > x[i-1]: # Return a huge penalty for invalid points return 1e10 # Return the original objective for valid points return f(x) res = gp_minimize(constrained_f, space)
Why Transformation is Better
The variable transformation approach ensures every sample gp_minimize generates is valid, so the optimizer can focus entirely on exploring good solutions instead of wasting time on invalid points. This is critical for high-dimensional spaces like your 100-dimensional problem.
内容的提问来源于stack exchange,提问作者Snochacz

