anyoptimization / pymoo

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

Error in xtol termination: axis 1 is out of bounds for array of dimension 1 in numpy.AxisError #403

Closed fracerma closed 1 year ago

fracerma commented 1 year ago

Description

I'm using NSGAII algorithm for a custom Mixed Variable Problem, with something like x1 = Choice(), x2 = Choice(), x3 = Integer() as variable types.

I've set the termination as:

termination = DefaultMultiObjectiveTermination(
                            xtol=1e-8,
                            cvtol=1e-6,
                            ftol=1e-6,
                            period= 20,
                            n_max_gen = 150)

and the algorithm as:

algorithm = NSGA2(  pop_size=50,
                                    sampling=MixedVariableSampling(),
                                    mating=MixedVariableMating(eliminate_duplicates=MixedVariableDuplicateElimination()),
                                    eliminate_duplicates=MixedVariableDuplicateElimination(),
                                    )

Debugging the code, I have that inpymoo.termination.xtol.py , prev and current have the same dimensions:

prev = [{'x1': 'choice1_1', 'x2': 'choice2_1', 'x3' : 2}]
curr= [{'x1': 'choice1_1', 'x2': 'choice2_1',  'x3' : 2}]

Then e != prev have just one dimension, making np.mean([np.sum(e != prev, axis=1) to fail.

This seems to be fixed removing axis=1

Environment

Error Traceback

  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/pymoo/optimize.py", line 67, in minimize
    res = algorithm.run()
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/pymoo/core/algorithm.py", line 141, in run
    self.next()
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/pymoo/core/algorithm.py", line 162, in next
    self.advance(infills=infills)
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/pymoo/core/algorithm.py", line 232, in advance
    self._post_advance()
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/pymoo/core/algorithm.py", line 309, in _post_advance
    self.termination.update(self)
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/pymoo/core/termination.py", line 28, in update
    progress = self._update(algorithm)
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/pymoo/termination/default.py", line 24, in _update
    p = [criterion.update(algorithm) for criterion in self.criteria]
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/pymoo/termination/default.py", line 24, in <listcomp>
    p = [criterion.update(algorithm) for criterion in self.criteria]
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/pymoo/core/termination.py", line 28, in update
    progress = self._update(algorithm)
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/pymoo/termination/robust.py", line 32, in _update
    perc = self.termination.update(algorithm)
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/pymoo/core/termination.py", line 28, in update
    progress = self._update(algorithm)
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/pymoo/termination/delta.py", line 42, in _update
    delta = self._delta(prev, current)
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/pymoo/termination/xtol.py", line 21, in _delta
    return np.mean([np.sum(e != prev, axis=1).max() / len(e) for e in current])
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/pymoo/termination/xtol.py", line 21, in <listcomp>
    return np.mean([np.sum(e != prev, axis=1).max() / len(e) for e in current])
  File "<__array_function__ internals>", line 6, in sum
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/numpy/core/fromnumeric.py", line 2260, in sum
    initial=initial, where=where)
  File "/home/user/miniconda3/envs/fatai/lib/python3.7/site-packages/numpy/core/fromnumeric.py", line 86, in _wrapreduction
    return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
numpy.AxisError: axis 1 is out of bounds for array of dimension 1
blankjul commented 1 year ago

Honestly, I think the xtol only makes sense for variables that can be represented as float variables. Can you check out the commit above and see if this works for you?

fracerma commented 1 year ago

Make sense and now it works