pyswarm
pyswarm copied to clipboard
Prevent evaluating infeasible solutions
I’m trying to optimise a black-box function which needs to obey a constraint. However, I noticed that the objective function is evaluated with values that don’t obey the constraint. I created a toy problem to verify the behaviour and indeed it seems to be sampling the function while violating constraints.
!pip install --upgrade pyswarm
import numpy as np
iteration = 0
def objective(val):
global iteration
x, y = val
if (x+y)>3 :
print("Sum of X and Y is: ", x+y)
print("Iteration: ", iteration)
iteration=iteration+1
return -20.0 * np.exp(-0.2 * np.sqrt(0.5 * (x**2 + y**2))) - np.exp(0.5 * (np.cos(2 * np.pi * x) + np.cos(2 * np.pi * y))) + np.e + 20
def condition(val):
x, y = val
sum = x + y
return [3 - sum]
ub = [5, 5]
lb = [-5, -5]
xopt, fopt = pso(objective, lb, ub, f_ieqcons=condition, debug=True, maxiter=20)
xopt
Ideally "Sum of X and Y is: " shouldn't be printed, but it is. I cannot evaluate the black-box function outside the constraints since it involves changing a parameters of a live system (And system simply wouldn’t allow those combinations).
Also, I get around 620 "iterations" although I've set maxiter=20.
Was wondering what I'm doing wrong here..
A couple of misunderstandings is all. The algorithm is currently written to evaluate EVERY function (objective + constraints) and then ignores the combinations of inputs that violate any constraint. I suppose I could have written it to check constraints first and use that to determine if the objective should be evaluated, but I didn't.
If I were doing this, I would fake the constraint within your objective by pre-evalulating the constraint and, if violated, skip the black-box function call entirely and simply return a very large number (since the algorithm is always minimizing). That way, those designs are always thrown away by the swarm and the black-box function never gets evaluated when it shouldn't.
Also, your iteration
variable isn't really an iteration variable, it's actually being a function evaluation counter, which happens once for every particle in the swarm in each of the algorithm's iteration. So, it's no real surprise that you are getting a much larger value than maxiter
.