anyoptimization / pymoo

NSGA2, NSGA3, R-NSGA3, MOEAD, Genetic Algorithms (GA), Differential Evolution (DE), CMAES, PSO
https://pymoo.org
Apache License 2.0
2.28k stars 390 forks source link

U-NSGA-III Verbose=True error #432

Closed corsair20141 closed 11 months ago

corsair20141 commented 1 year ago

When argument Verbose=True is applied to the minimize() method using UNSGA3 algorithm, the following error is encountered after the first iteration (generation):

ValueError: zero-size array to reduction operation minimum which has no identity

corsair20141 commented 1 year ago

Additionally: It is not just related to Verbose=True, there is a deeper problem. With Verbose=False the minimization routine runs, but it appears only the initial population is kept so very few non-dominated solutions occur.

Is this a bug or is it improper use on my end?

n_obj = 2 n_ineq = 1 n_var = 4

blankjul commented 1 year ago

Can you please provide an example for us to reproduce the error? It is hard to guess what can cause the error above without any indication.

import numpy as np

from pymoo.algorithms.moo.unsga3 import UNSGA3
from pymoo.optimize import minimize
from pymoo.problems import get_problem

problem = get_problem("ackley", n_var=30)

ref_dirs = np.array([[1.0]])

algorithm = UNSGA3(ref_dirs, pop_size=100)

res = minimize(problem,
               algorithm,
               termination=('n_gen', 150),
               verbose=True,
               seed=1)

print("UNSGA3: Best solution found: \nX = %s\nF = %s" % (res.X, res.F))

This is an example from the documentation that works. I have a feeling the error could be related to the constraint. Could other algorithms solve your problem? (just to be sure the problem is defined the right way).

corsair20141 commented 1 year ago

Thank you for your response. Yes, that example code runs fine for me as well. However, with my specific problem the UNSGA3 algorithm has issues. The NSGA2 algorithm worked fine for my constrained optimization problem, as did CTAEA. Could it be because I have the problem defined as an 'element-wise problem'?

On Sun, May 21, 2023 at 7:25 PM Julian Blank @.***> wrote:

Can you please provide an example for us to reproduce the error? It is hard to guess what can cause the error above without any indication.

import numpy as np

from pymoo.algorithms.moo.unsga3 import UNSGA3 from pymoo.optimize import minimize from pymoo.problems import get_problem

problem = get_problem("ackley", n_var=30)

ref_dirs = np.array([[1.0]])

algorithm = UNSGA3(ref_dirs, pop_size=100)

res = minimize(problem, algorithm, termination=('n_gen', 150), verbose=True, seed=1)

print("UNSGA3: Best solution found: \nX = %s\nF = %s" % (res.X, res.F))

This is an example from the documentation that works. I have a feeling the error could be related to the constraint. Could other algorithms solve your problem? (just to be sure the problem is defined the right way).

— Reply to this email directly, view it on GitHub https://github.com/anyoptimization/pymoo/issues/432#issuecomment-1556423427, or unsubscribe https://github.com/notifications/unsubscribe-auth/AIXDX3HXTX3F72KIWW2OEODXHLFCPANCNFSM6AAAAAAYIASTCI . You are receiving this because you authored the thread.Message ID: @.***>

blankjul commented 1 year ago

Thanks for the clarification. It seems to be a U-NSGA3-specific problem then. Can you provide some simple code to reproduce the problem? The information above will not be enough for me to analyze when what goes wrong.

corsair20141 commented 1 year ago

Sure, here is an example from the documentation, but using U-NSGA-III instead of NSGA-II

import numpy as np
import matplotlib.pyplot as plt
from pymoo.core.problem import ElementwiseProblem
from pymoo.algorithms.moo.unsga3 import UNSGA3
from pymoo.operators.crossover.sbx import SBX
from pymoo.operators.mutation.pm import PM
from pymoo.operators.sampling.rnd import FloatRandomSampling
from pymoo.termination import get_termination
from pymoo.optimize import minimize
from pymoo.mcdm.pseudo_weights import PseudoWeights

plt.close('all')

# ---- Define Problem
class MyProblem(ElementwiseProblem):

    def __init__(self):
        super().__init__(n_var=2,
                         n_obj=2,
                         n_ieq_constr=2,
                         xl=np.array([-2,-2]),
                         xu=np.array([2,2]))

    def _evaluate(self, x, out, *args, **kwargs):
        f1 = 100 * (x[0]**2 + x[1]**2)
        f2 = (x[0]-1)**2 + x[1]**2

        g1 = 2*(x[0]-0.1) * (x[0]-0.9) / 0.18
        g2 = - 20*(x[0]-0.4) * (x[0]-0.6) / 4.8

        out["F"] = [f1, f2]
        out["G"] = [g1, g2]

problem = MyProblem()
ref_dirs = np.array([[1.0,1.0]])

# ---- Setup Solver Algorithm
algorithm = UNSGA3(
    pop_size=40,
    n_offsprings=10,
    sampling=FloatRandomSampling(),
    crossover=SBX(prob=0.9, eta=15),
    mutation=PM(eta=20),
    eliminate_duplicates=True,
    ref_dirs = ref_dirs
)

# ---- Define Termination Criteria
termination = get_termination("n_gen", 40)

# ---- Minimize the PROBLEM using the ALGORITHM and TERMINATION CRITERIA
res = minimize(problem,
               algorithm,
               termination,
               seed=1,
               save_history=True,
               verbose=True)

X = res.X
F = res.F

# ---- Pseudo-Weight method to determine "best" design from Pareto-Optimal set and user-input weight factors
weights = np.array([0.2, 0.8])
i = PseudoWeights(weights).do(F)
print("Best regarding Pseudo Weights: Point \ni = %s\nF = %s" % (i, F[i]))

plt.figure(figsize=(7, 5))
plt.scatter(F[:, 0], F[:, 1], s=30, facecolors='none', edgecolors='blue')
plt.scatter(F[i, 0], F[i, 1], marker="x", color="red", s=200)
plt.title("Objective Space")
plt.show()

# ---- Visualize the Results
xl, xu = problem.bounds()
plt.figure(figsize=(7, 5))
plt.scatter(X[:, 0], X[:, 1], s=30, facecolors='none', edgecolors='r')
plt.xlim(xl[0], xu[0])
plt.ylim(xl[1], xu[1])
plt.title("Design Space")
plt.show()
blankjul commented 1 year ago

wow. that is a really interesting problem. It actually is because of NSGA3.

So in NSGA3 the optimum is based on a solution being

Now, what happens is that no solution that is non-dominated is closest to a reference direction. Thus, there is no true optimum which brings some trouble later. Can you check if it woks with the commit above?

Technically, this can still make throw an exception if this happens in the very first interaction I think.