diff --git a/pygmo/CMakeLists.txt b/pygmo/CMakeLists.txt index 4c9cfbc0..4b767c9d 100644 --- a/pygmo/CMakeLists.txt +++ b/pygmo/CMakeLists.txt @@ -77,9 +77,10 @@ Python3_add_library(core MODULE WITH_SOABI ) target_link_libraries(core PRIVATE Pagmo::pagmo Boost::boost Boost::serialization) +target_link_directories(core PRIVATE "/home/paul/work/UoM/wrg/code/moea/pagmo2/build") # NOTE: quench warnings from Boost when building the library. target_compile_definitions(core PRIVATE BOOST_ALLOW_DEPRECATED_HEADERS) -target_include_directories(core SYSTEM PRIVATE "${pybind11_INCLUDE_DIR}") +target_include_directories(core SYSTEM PRIVATE "${pybind11_INCLUDE_DIR}" "/home/paul/work/UoM/wrg/code/moea/pagmo2/include") target_compile_definitions(core PRIVATE "${pybind11_DEFINITIONS}") target_compile_options(core PRIVATE "$<$:${PYGMO_CXX_FLAGS_DEBUG}>" diff --git a/pygmo/docstrings.cpp b/pygmo/docstrings.cpp index e30107a7..fff0ed9a 100644 --- a/pygmo/docstrings.cpp +++ b/pygmo/docstrings.cpp @@ -2453,6 +2453,9 @@ See also the docs of the relevant C++ method :cpp:func:`pagmo::nsga2::get_log`. )"; } +std::string nsga3_docstring(){ return R"(nsga3_docstring)"; } +std::string nsga3_get_log_docstring(){ return R"(nsga3_get_log_docstring)"; } + std::string gaco_set_bfe_docstring() { return R"(set_bfe(b) diff --git a/pygmo/docstrings.hpp b/pygmo/docstrings.hpp index 1c5cc454..534e27f6 100644 --- a/pygmo/docstrings.hpp +++ b/pygmo/docstrings.hpp @@ -127,6 +127,8 @@ std::string moead_gen_get_log_docstring(); std::string nsga2_set_bfe_docstring(); std::string nsga2_docstring(); std::string nsga2_get_log_docstring(); +std::string nsga3_docstring(); +std::string nsga3_get_log_docstring(); std::string nspso_set_bfe_docstring(); std::string nspso_docstring(); std::string nspso_get_log_docstring(); diff --git a/pygmo/expose_algorithms_1.cpp b/pygmo/expose_algorithms_1.cpp index 0b75a2a0..275500ff 100644 --- a/pygmo/expose_algorithms_1.cpp +++ b/pygmo/expose_algorithms_1.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +72,26 @@ void expose_algorithms_1(py::module &m, py::class_ &algo, py:: nsga2_.def("get_seed", &pagmo::nsga2::get_seed, generic_uda_get_seed_docstring().c_str()); nsga2_.def("set_bfe", &pagmo::nsga2::set_bfe, nsga2_set_bfe_docstring().c_str(), py::arg("b")); + // NSGA3 + auto nsga3_ = expose_algorithm(m, algo, a_module, "nsga3", nsga3_docstring().c_str()); + nsga3_.def(py::init(), + py::arg("gen") = 1u, py::arg("cr") = 1.0, py::arg("eta_cr") = 30.0, py::arg("mut") = 0.10, + py::arg("eta_mut") = 20.0, py::arg("divisions") = 12u, py::arg("seed"), py::arg("use_memory") ); + + nsga3_.def( + "get_log", + [](const pagmo::nsga3 &a) -> py::list { + py::list retval; + for (const auto &t : a.get_log()) { + retval.append(py::make_tuple(std::get<0>(t), std::get<1>(t), + vector_to_ndarr>(std::get<2>(t)))); + } + return retval; + }, + nsga3_get_log_docstring().c_str()); + + nsga3_.def("get_seed", &pagmo::nsga3::get_seed, generic_uda_get_seed_docstring().c_str()); + // GACO auto gaco_ = expose_algorithm(m, algo, a_module, "gaco", gaco_docstring().c_str()); gaco_.def( diff --git a/pygmo/test.py b/pygmo/test.py index 9eff4c72..fab1b1a9 100644 --- a/pygmo/test.py +++ b/pygmo/test.py @@ -1690,6 +1690,48 @@ def runTest(self): log = uda.get_log() +class nsga3_test_case(_ut.TestCase): + """Test case for the UDA NSGA-III""" + + def runTest(self): + import numpy as np + from .core import algorithm, dtlz, ideal, nsga3, population + from pickle import loads, dumps + import random + + dtlz1_p92_g20_ideal = [3.36287e-06, 8.54994e-06, 1.33931e-04] + nsga3_seed = 32 + + # Test evolve population with DTLZ1 problem + uda = nsga3(gen=20, cr=1.0, eta_cr=30.0, mut=0.10, eta_mut=20.0, divisions=12, seed=nsga3_seed, use_memory=False) + udp = dtlz(prob_id=1, dim=10, fdim=3) + pop = population(udp, size=92, seed=23) + alg = algorithm(uda) + alg.set_verbosity(2) # Required for log test below + out = alg.evolve(pop) + g20_ideal = ideal(out.get_f()) + assert np.allclose(dtlz1_p92_g20_ideal, g20_ideal) + + # Test serialisation + self.assertEqual(str(alg), str(loads(dumps(alg)))) + + # Test get_seed() + self.assertEqual(uda.get_seed(), nsga3_seed) + + # Test log retrieval + inst = alg.extract(nsga3) + rlog = inst.get_log() + self.assertTrue(isinstance(rlog, list)) + self.assertEqual(len(rlog), 20) # ngen + entry = random.choice(rlog) + self.assertTrue(isinstance(entry, tuple)) + self.assertEqual(len(entry), 3) # gen, fevals, ideal + self.assertTrue(isinstance(entry[0], int)) + self.assertTrue(isinstance(entry[1], int)) + self.assertTrue(isinstance(entry[2], np.ndarray)) + self.assertEqual(entry[2].shape, (3,)) # nobjs + + class gaco_test_case(_ut.TestCase): """Test case for the UDA gaco""" @@ -3435,6 +3477,7 @@ def run_test_suite(level=0): suite.addTest(lennard_jones_test_case()) suite.addTest(de_test_case()) suite.addTest(nsga2_test_case()) + suite.addTest(nsga3_test_case()) suite.addTest(gaco_test_case()) suite.addTest(gwo_test_case()) suite.addTest(de1220_test_case())