diff --git a/cmake/PygmoFindBoost.cmake b/cmake/PygmoFindBoost.cmake index 05a9d9e5..0e254147 100644 --- a/cmake/PygmoFindBoost.cmake +++ b/cmake/PygmoFindBoost.cmake @@ -1,4 +1,4 @@ -set(_PYGMO_BOOST_MINIMUM_VERSION 1.60.0) +set(_PYGMO_BOOST_MINIMUM_VERSION 1.83.0) find_package(Boost ${_PYGMO_BOOST_MINIMUM_VERSION} REQUIRED COMPONENTS serialization) message(STATUS "Detected Boost version: ${Boost_VERSION}") 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..5f7c3740 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") = 4u, 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..6f51fc93 100644 --- a/pygmo/test.py +++ b/pygmo/test.py @@ -1690,6 +1690,47 @@ 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 + + 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=4, 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()) + np.less(g20_ideal, [0.1]*3) + + # 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 +3476,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())