diff --git a/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/fitness_function.h b/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/fitness_function.h index 40ceb55e45f..51a06289d99 100644 --- a/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/fitness_function.h +++ b/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/fitness_function.h @@ -106,6 +106,13 @@ struct Fitness_map // -> a free function } + double get_best_fitness_value(const Matrix& data) + { + Matrix best_mat = get_best(); + return compute_fitness(best_mat, data); + } + + const Matrix points; Population pop; }; diff --git a/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/obb.h b/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/obb.h index fb936a53491..42760894665 100644 --- a/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/obb.h +++ b/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/obb.h @@ -46,7 +46,7 @@ namespace Optimal_bounding_box { template -void evolution(Matrix& R, Matrix& points, std::size_t generations) // todo: points is const +void evolution(Matrix& R, Matrix& points, std::size_t max_generations) // todo: points is const { CGAL_assertion(points.rows() >= 3); @@ -59,12 +59,12 @@ void evolution(Matrix& R, Matrix& points, std::size_t generations) // todo: poin Population pop(50); - //std::cout << "initial pop" << std::endl; - //pop.show_population(); - //std::cout << std::endl; - //std::cin.get(); + double prev_fit_value = 0; + double new_fit_value = 0; + double tolerance = 1e-2; + int stale = 0; - for(std::size_t t = 0; t < generations; ++t) + for(std::size_t t = 0; t < max_generations; ++t) { genetic_algorithm(pop, points); @@ -73,7 +73,6 @@ void evolution(Matrix& R, Matrix& points, std::size_t generations) // todo: poin // std::cout << std::endl; //std::cin.get(); - for(std::size_t s = 0; s < pop.size(); ++s) nelder_mead(pop[s], points, nelder_mead_iterations); @@ -82,7 +81,6 @@ void evolution(Matrix& R, Matrix& points, std::size_t generations) // todo: poin //std::cout << std::endl; //std::cin.get(); - // debugging /* Fitness_map fitness_map(pop, points); @@ -90,13 +88,23 @@ void evolution(Matrix& R, Matrix& points, std::size_t generations) // todo: poin std::cout << "det= " << R_now.determinant() << std::endl; */ + // stopping criteria + Fitness_map fitness_map(pop, points); + new_fit_value = fitness_map.get_best_fitness_value(points); + double difference = new_fit_value - prev_fit_value; + if(abs(difference) < tolerance * new_fit_value) + stale++; + + if(stale == 5) + break; + + prev_fit_value = new_fit_value; } // compute fitness of entire population Fitness_map fitness_map(pop, points); R = fitness_map.get_best(); - } @@ -152,8 +160,11 @@ void fill_matrix(std::vector& v_points, Matrix& points_mat) } } -/// @param points point coordinates of the input mesh +/// @param points point coordinates of the input mesh. /// @param obb_points the 8 points of the obb. +/// @param use convex hull or not. +/// +/// todo named parameters: max iterations template void find_obb(std::vector& points, std::vector& obb_points, bool use_ch) { @@ -186,8 +197,8 @@ void find_obb(std::vector& points, std::vector& obb_points, bool u } MatrixXf R(3, 3); - std::size_t generations = 10; - CGAL::Optimal_bounding_box::evolution(R, points_mat, generations); + std::size_t max_generations = 100; + CGAL::Optimal_bounding_box::evolution(R, points_mat, max_generations); MatrixXf obb(8, 3); CGAL::Optimal_bounding_box::post_processing(points_mat, R, obb);