/** * Constructor using std::vector (for python exposition purposes) * * @param[in] p base::problem to be rotated * @param[in] rotation std::vector<std::vector<double> > expressing the problem rotation * * @see problem::base constructors. */ rotated::rotated(const base &p, const std::vector<std::vector<double> > &rotation): base_meta( p, p.get_dimension(), p.get_i_dimension(), p.get_f_dimension(), p.get_c_dimension(), p.get_ic_dimension(), p.get_c_tol()), m_Rotate(),m_normalize_translation(), m_normalize_scale() { if(!(rotation.size()==get_dimension())){ pagmo_throw(value_error,"The input matrix dimensions seem incorrect"); } if(p.get_i_dimension()>0){ pagmo_throw(value_error,"Input problem has an integer dimension. Cannot rotate it."); } m_Rotate.resize(rotation.size(),rotation.size()); for (base::size_type i = 0; i < rotation.size(); ++i) { if(!(rotation.size()==rotation[i].size())){ pagmo_throw(value_error,"The input matrix seems not to be square"); } for (base::size_type j = 0; j < rotation[i].size(); ++j) { m_Rotate(i,j) = rotation[i][j]; } } m_InvRotate = m_Rotate.transpose(); Eigen::MatrixXd check = m_InvRotate * m_Rotate; if(!check.isIdentity(1e-5)){ pagmo_throw(value_error,"The input matrix seems not to be orthonormal (to a tolerance of 1e-5)"); } configure_new_bounds(); }
cstrs_self_adaptive::cstrs_self_adaptive(const base &problem): base_meta( problem, problem.get_dimension(), problem.get_i_dimension(), problem.get_f_dimension(), 0, 0, std::vector<double>()), m_apply_penalty_1(false), m_scaling_factor(0.0), m_c_scaling(problem.get_c_dimension(),0.0), m_f_hat_down(problem.get_f_dimension(),0.0), m_f_hat_up(problem.get_f_dimension(),0.0), m_f_hat_round(problem.get_f_dimension(),0.0), m_i_hat_down(0.0), m_i_hat_up(0.0), m_i_hat_round(0.0), m_map_fitness(), m_map_constraint(), m_decision_vector_hash() { population pop(*m_original_problem,0); if(m_original_problem->get_c_dimension() <= 0){ pagmo_throw(value_error,"The original problem has no constraints."); } // check that the dimension of the problem is 1 if (m_original_problem->get_f_dimension() != 1) { pagmo_throw(value_error,"The original fitness dimension of the problem must be one, multi objective problems can't be handled with self adaptive meta problem."); } update_penalty_coeff(pop); }
/** * Constructor of antibodies meta-problem * * Note: This problem is not intended to be used by itself. Instead use the * cstrs_immune_system algorithm if you want to solve constrained problems. * * @param[in] problem base::problem to be used to set up the boundaries * @param[in] method method_type to used for the distance computation. * Two posssibililties are available: HAMMING, EUCLIDEAN. */ antibodies_problem::antibodies_problem(const base &problem, const algorithm::cstrs_immune_system::distance_method_type method): base((int)problem.get_dimension(), problem.get_i_dimension(), problem.get_f_dimension(), 0, 0, 0.), m_original_problem(problem.clone()), m_pop_antigens(), m_method(method) { if(m_original_problem->get_c_dimension() <= 0){ pagmo_throw(value_error,"The original problem has no constraints."); } // check that the dimension of the problem is 1 if(m_original_problem->get_f_dimension() != 1) { pagmo_throw(value_error,"The original fitness dimension of the problem must be one, multi objective problems can't be handled with co-evolution meta problem."); } // encoding for hamming distance m_bit_encoding = 25; m_max_encoding_integer = int(std::pow(2., m_bit_encoding)); set_bounds(m_original_problem->get_lb(),m_original_problem->get_ub()); }
/** * Constructor using initial constrained problem * * @param[in] problem base::problem to be modified to use a constrained to * multi-objective handling technique. * @param[in] method method_type to be modified to use a single constrained * to multi-objective approach defined with OBJ_CSTRS, OBJ_CSTRSVIO or OBJ_EQVIO_INEQVIO * */ con2mo::con2mo(const base &problem, const method_type method): base_meta( problem, problem.get_dimension(), problem.get_i_dimension(), __mo_dimension__(problem, method), 0, 0, std::vector<double>()), m_method(method) {}
rotated::rotated(const base &p, const Eigen::MatrixXd &rotation ): base_meta( p, p.get_dimension(), p.get_i_dimension(), p.get_f_dimension(), p.get_c_dimension(), p.get_ic_dimension(), p.get_c_tol()), m_Rotate(rotation), m_normalize_translation(), m_normalize_scale() { m_InvRotate = m_Rotate.transpose(); Eigen::MatrixXd check = m_InvRotate * m_Rotate; if(!check.isIdentity(1e-5)){ pagmo_throw(value_error,"The input matrix seems not to be orthonormal (to a tolerance of 1e-5)"); } if(p.get_i_dimension()>0){ pagmo_throw(value_error,"Input problem has an integer dimension. Cannot rotate it."); } configure_new_bounds(); }
robust::robust(const base & p, unsigned int trials, const double param_rho, unsigned int seed): base_stochastic((int)p.get_dimension(), p.get_i_dimension(), p.get_f_dimension(), p.get_c_dimension(), p.get_ic_dimension(), p.get_c_tol(), seed), m_original_problem(p.clone()), m_normal_dist(0, 1), m_uniform_dist(0, 1), m_trials(trials), m_rho(param_rho) { if(param_rho < 0){ pagmo_throw(value_error, "Rho should be greater than 0"); } set_bounds(p.get_lb(),p.get_ub()); }
noisy::noisy(const base & p, unsigned int trials, const double param_first, const double param_second, noise_type distribution, unsigned int seed): base_stochastic((int)p.get_dimension(), p.get_i_dimension(), p.get_f_dimension(), p.get_c_dimension(), p.get_ic_dimension(), p.get_c_tol(), seed), m_original_problem(p.clone()), m_trials(trials), m_normal_dist(0.0,1.0), m_uniform_dist(0.0,1.0), m_decision_vector_hash(), m_param_first(param_first), m_param_second(param_second), m_noise_type(distribution) { if(distribution == UNIFORM && param_first > param_second){ pagmo_throw(value_error, "Bounds specified for the uniform noise are not valid."); } set_bounds(p.get_lb(),p.get_ub()); }
/** * Constructor * * @param[in] p base::problem to be decomposed * @param[in] method decomposition method (WEIGHTS, TCHEBYCHEFF, BI) * @param[in] weights the weight vector (by default is set to random weights) * @param[in] z ideal reference point (used in Tchebycheff and Boundary Intersection (BI) methods, by default it is set to 0) * @param[in] adapt_ideal if true it updates the ideal reference point each time the objective function is called checking if the computed fitness is better (assumes minimization) * @see For the uniform random generation of weights vector see Appendix 2 in "A. Jaszkiewicz - On the Performance of Multiple-Objective Genetic Local Search on the 0/1 Knapsack Problem—A Comparative Experiment" * @see For the different decomposition methods see "Q. Zhang - MOEA/D: A Multiobjective Evolutionary Algorithm Based on Decomposition" */ decompose::decompose(const base & p, method_type method, const std::vector<double> & weights, const std::vector<double> & z, const bool adapt_ideal): base_meta( p, p.get_dimension(), // Ambiguous without the cast ... p.get_i_dimension(), 1, //it transforms the problem into a single-objective problem p.get_c_dimension(), p.get_ic_dimension(), p.get_c_tol()), m_method(method), m_weights(weights), m_z(z), m_adapt_ideal(adapt_ideal) { //0 - Check whether method is implemented if(m_method != WEIGHTED && m_method != TCHEBYCHEFF && m_method != BI) { pagmo_throw(value_error,"non existing decomposition method"); } if (p.get_f_dimension() == 1) { pagmo_throw(value_error,"decompose works only for multi-objective problems, you are trying to decompose a single objective one."); } //1 - Checks whether the weight vector has a dimension, if not, sets its default value if (m_weights.size() == 0) { //Initialise a random weight vector rng_double m_drng = rng_generator::get<rng_double>(); m_weights = std::vector<double>((int)p.get_f_dimension(), 0.0); double sum = 0; for(std::vector<double>::size_type i = 0; i<m_weights.size(); ++i) { m_weights[i] = (1-sum) * (1 - pow(boost::uniform_real<double>(0,1)(m_drng), 1.0 / (m_weights.size() - i - 1))); sum += m_weights[i]; } } else { //1.1 - Checks whether the weight has lenght equal to the fitness size if (m_weights.size() != p.get_f_dimension()) { pagmo_throw(value_error,"the weight vector must have length equal to the fitness size"); } //1.2 - Checks whether the weight vector sums to 1 double sum = 0.0; for (std::vector<double>::size_type i=0; i<m_weights.size(); ++i) { sum += m_weights[i]; } if (fabs(sum-1.0) > 1E-8) { pagmo_throw(value_error,"the weight vector should sum to 1 with a tolerance of E1-8"); } //1.4 - Checks that all weights are positive for (std::vector<double>::size_type i=0; i<m_weights.size(); ++i) { if (m_weights[i] < 0) { pagmo_throw(value_error,"the weight vector should contain only positive values"); } } } //2 - Checks whether the reference point has a dimension, if not, sets its default value m_z = (0, ..., 0) if (m_z.size() == 0) { m_z = std::vector<double>((int)p.get_f_dimension(), 0.0); //by default m_z = (0, ..., 0) } else { //2.1 - Checks whether the reference point has lenght equal to the fitness size if (m_z.size() != p.get_f_dimension()) { pagmo_throw(value_error,"the the reference point vector must have equal length to the fitness size"); } } }