pymoo

U-NSGA-III

The algorithm is implemented based on [9]. NSGA-III selects parents randomly for mating. It has been shown that tournament selection performs better than random selection. The U stands for unified and increases the performance of NSGA-III by introducing tournament pressure.

The mating selections works as follows:

unsga3_mating

Example

[1]:
from pymoo.optimize import minimize
from pymoo.util import plotting
from pymoo.util.reference_direction import UniformReferenceDirectionFactory
from pymop.factory import get_problem
from pymoo.factory import get_algorithm
import numpy as np

# create the reference directions to be used for the optimization
ref_dirs = UniformReferenceDirectionFactory(1, n_points=1).do()

# create the algorithm object
method = get_algorithm("unsga3",
                      pop_size=100,
                      ref_dirs=ref_dirs)

# execute the optimization
res = minimize(get_problem("ackley", n_var=30),
               method,
               termination=('n_gen', 150),
               save_history=True)

print("UNSGA3: Best solution found: \nX = %s\nF = %s" % (res.X, res.F))
UNSGA3: Best solution found:
X = [-0.08971464  0.02542057 -0.09928178 -0.04103037  0.12043261  0.0652284
  0.09230988  0.01377524 -0.11760051 -0.01478208 -0.03297162  0.00062692
  0.10420719  0.08548882 -0.08412093 -0.12313098  0.02842218  0.09985696
 -0.02226573  0.05461655 -0.04751691 -0.04079794  0.04940306 -0.01557481
 -0.0456587   0.06875416 -0.00968723 -0.07294767 -0.11009459  0.03699245]
F = [0.52831849]

U-NSGA-III has for single- and bi-objective problems a tournament pressure which is known to be useful. In the following we provide a quick comparison (here just one run, so not a valid experiment), to see the difference in convergence.

[2]:
_res = minimize(get_problem("ackley", n_var=30),
                get_algorithm("nsga3", pop_size=100, ref_dirs=ref_dirs),
               termination=('n_gen', 150),
               save_history=True)
print("NSGA3: Best solution found: \nX = %s\nF = %s" % (res.X, res.F))
NSGA3: Best solution found:
X = [-0.08971464  0.02542057 -0.09928178 -0.04103037  0.12043261  0.0652284
  0.09230988  0.01377524 -0.11760051 -0.01478208 -0.03297162  0.00062692
  0.10420719  0.08548882 -0.08412093 -0.12313098  0.02842218  0.09985696
 -0.02226573  0.05461655 -0.04751691 -0.04079794  0.04940306 -0.01557481
 -0.0456587   0.06875416 -0.00968723 -0.07294767 -0.11009459  0.03699245]
F = [0.52831849]
[3]:
import numpy as np
import matplotlib.pyplot as plt

ret = [np.min(e.pop.get("F")) for e in res.history]
_ret = [np.min(e.pop.get("F")) for e in _res.history]

plt.plot(np.arange(len(ret)), ret, label="unsga3")
plt.plot(np.arange(len(_ret)), _ret, label="nsga3")
plt.title("Convergence")
plt.xlabel("Generation")
plt.ylabel("F")
plt.legend()
plt.show()
../_images/algorithms_unsga3_8_0.png