anyoptimization / pymoo

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

Error when running a vectorized problem #424

Closed isong29 closed 1 year ago

isong29 commented 1 year ago

Hi everyone,

Thank you again for the help earlier last week. I am now attempting to run an MOO with a vectorized problem, written as follows:

class MOO_UASB_TEA_NPV(Problem):

    def __init__(self, **kwargs):
        super().__init__(n_var=3,
                         n_obj=2,
                         xl=np.array([25,4.0, 1]),
                         xu=np.array([45, 9.0, 72]), 
                         **kwargs)

    def _evaluate(self, x, out, *args, **kwargs):

        out["F"] = BaselineSolve(x, model = modelSys)
        out["G"] = []

algorithm = NSGA2(
    pop_size=40,
    n_offsprings=10,
    sampling=FloatRandomSampling(),
    crossover=SBX(prob=0.9, eta=15),
    mutation=PM(eta=20),
    eliminate_duplicates=True
) 

termination = DefaultMultiObjectiveTermination(
    xtol=1e-3,
    cvtol=1e-6,
    ftol=0.0025,
    period=10,
    n_max_gen=1000,
    n_max_evals=100000
)

problem = MOO_UASB_TEA_NPV()

startTime = time.time()
res = minimize(problem,
               algorithm,
               termination,
               seed=7,
               save_history=True,
               verbose=True)
endTime = time.time()

"BaselineSolve" inside the Problem calls a function that takes in a 2D numpy array where each row is an entry, and each column is a parameter. It outputs a 2D numpy array that is formatted the same way. I.e. the output is:

np.array([ Obj1, Obj2, Obj3, ...., Objn ])

Where each Obji is a 1D np array containing the objective function values for the i-th set of parameters that were inputted into the function.

I confirmed this by printing the np.shape() of the input and the output. It shows that x has a shape of (40, 3) - which makes sense, 40 population and 3 parameters each) - and that the output of the BaselineSolve function has a shape of (40,2) - which also makes sense since there are 40 individuals and 2 objective functions each.

However, at the very end of the evaluation, I run into a numpy error, specifically that:

     35 @primitive
     36 def concatenate_args(axis, *args):
---> 37     return _np.concatenate(args, axis).view(ndarray)
     38 concatenate = lambda arr_list, axis=0 : concatenate_args(axis, *arr_list)
     39 vstack = row_stack = lambda tup: concatenate([atleast_2d(_m) for _m in tup], axis=0)

[.../AppData/Roaming/Python/Python39/site-packages/numpy/core/overrides.py) in concatenate(*args, **kwargs)

ValueError: need at least one array to concatenate

Have you seen such an error occur? I did look through the other issues on the github, and Julian had mentioned that the output should be of shape (len(x), n_obj), which in this case it is.

Thank you very much for your assistance in this matter.

Best, Ian

blankjul commented 1 year ago

does commenting out out["G"] = [] solve the issue?

isong29 commented 1 year ago

Hi Julian,

It seems like it fixes that error, but adds new errors:

[c:\Users\cfiso\.conda\envs\QSD\lib\site-packages\pymoo\core\problem.py:237](file:///C:/Users/cfiso/.conda/envs/QSD/lib/site-packages/pymoo/core/problem.py:237): FailedEvaluation: [TypeError] list indices must be integers or slices, not str
  self._evaluate(X, out, *args, **kwargs)
[c:\Users\cfiso\.conda\envs\QSD\lib\site-packages\pymoo\core\problem.py:237](file:///C:/Users/cfiso/.conda/envs/QSD/lib/site-packages/pymoo/core/problem.py:237): FailedEvaluation: [TypeError] list indices must be integers or slices, not str
  self._evaluate(X, out, *args, **kwargs)

and some type of assertion error:

[c:\Users\cfiso\.conda\envs\QSD\lib\site-packages\pymoo\core\termination.py](file:///C:/Users/cfiso/.conda/envs/QSD/lib/site-packages/pymoo/core/termination.py) in update(self, algorithm)
     27         else:
     28             progress = self._update(algorithm)
---> 29             assert progress >= 0.0
     30 
     31         self.perc = progress

AssertionError:

I'm not quite sure which list it is unable to index, since I do not call a specific index aside from out["F"], which is pre-defined in PyMoo.

Thank you once again for your quick response and help.

Best, Ian

blankjul commented 1 year ago

I was not able to reproduce the error. Please provide a minimum working example if you want me to have a look into it.

isong29 commented 1 year ago

Hi Julian,

Thank you for your willingness to help looking into this. Would it be OK for me to send this to you via email, or should I attach the full code here?

Thank you, Ian

blankjul commented 1 year ago

You can directly attach it here. Please only post a minimum example with the code necessary to reproduce the error though (not your entire file).

isong29 commented 1 year ago

Hi Julian,

I actually went through everything and found the issue in my own personal code. So commenting out the ["G"] does help. Thank you very much for your assistance.

Best, Ian