在Pymoo优化中如何为目标函数输出值添加约束?
Got it, let's walk through how to build this repair function step by step. First, let's clarify the core logic: your target function is f1 = -1 * (constant1 * (variable1 - constant2)), and you want to enforce 10 ≤ f1 ≤ 20 using a Repair function instead of traditional constraint checks.
Step 1: Reverse-engineer the variable adjustment
Since we need to fix f1 to stay within the valid range, we can rearrange your target function to solve for variable1 when f1 goes out of bounds:
- If
f1 < 10: Setf1 = 10, then calculatevariable1 = constant2 - f1 / constant1 - If
f1 > 20: Setf1 = 20, then calculatevariable1 = constant2 - f1 / constant1 - If
10 ≤ f1 ≤20: Leavevariable1unchanged
Step 2: Full Code Implementation
Here's a complete, runnable example with explanations:
from pymoo.core.problem import Problem from pymoo.core.repair import Repair from pymoo.algorithms.soo.nonconvex.ga import GA from pymoo.optimize import minimize # Replace these with your actual constant values CONSTANT1 = 5 CONSTANT2 = 3 # Define your optimization problem class MyProblem(Problem): def __init__(self): super().__init__( n_var=1, # Only variable1 as input n_obj=1, # Single objective f1 n_constr=0, # We're using Repair instead of explicit constraints # No variable bounds set per your request ) def _evaluate(self, X, out, *args, **kwargs): # X is a 2D array where each row is an individual's variable1 value variable1 = X[:, 0] # Calculate f1 using your formula f1 = -1 * (CONSTANT1 * (variable1 - CONSTANT2)) out["F"] = f1.reshape(-1, 1) # Define the custom Repair function class F1RangeRepair(Repair): def _do_repair(self, problem, X, **kwargs): # Iterate over every individual in the population for i in range(len(X)): variable1 = X[i, 0] # Compute the current f1 value for this individual current_f1 = -1 * (CONSTANT1 * (variable1 - CONSTANT2)) # Adjust variable1 if f1 is outside the allowed range if current_f1 < 10: # Force f1 to the minimum valid value, then reverse-calculate variable1 new_f1 = 10 X[i, 0] = CONSTANT2 - new_f1 / CONSTANT1 elif current_f1 > 20: # Force f1 to the maximum valid value, then reverse-calculate variable1 new_f1 = 20 X[i, 0] = CONSTANT2 - new_f1 / CONSTANT1 # No action needed if f1 is already in range return X # Run the optimization process if __name__ == "__main__": # Initialize problem and algorithm with the repair function problem = MyProblem() algorithm = GA(pop_size=20, repair=F1RangeRepair()) # Execute minimization (adjust the objective direction if you need to optimize f1 further) res = minimize(problem, algorithm, termination=('n_gen', 10), verbose=True) # Verify that all results meet the f1 constraint print("\nOptimized variable1 values:", res.X) print("Corresponding f1 values:", -1*(CONSTANT1*(res.X - CONSTANT2)))
Key Details to Note:
- Problem Setup: We set
n_constr=0because we're handling the constraint via Repair instead of Pymoo's built-in constraint validation. - Repair Logic: The
_do_repairmethod checks each individual'sf1value. If it's outside [10,20], it adjustsvariable1to forcef1back into the valid range using the reversed formula. - Algorithm Integration: The repair function is passed directly to the GA (or any other Pymoo algorithm) via the
repairparameter. - Validation: The final print statements let you confirm that all resulting
f1values fall within your desired range.
If you need to optimize f1 further (e.g., maximize or minimize it while keeping it in bounds), you can adjust the objective function's direction in the minimization call or tweak the problem's objective definition.
内容的提问来源于stack exchange,提问作者Karthick Mohanraj

