3 #include "../problem/base_stochastic.h"
4 #include <boost/math/distributions/chi_squared.hpp>
5 #include <boost/math/distributions/students_t.hpp>
6 #include <boost/math/distributions/normal.hpp>
10 namespace pagmo{
namespace util{
22 racing_population::racing_population(
const population &pop): population(pop)
33 racing_population::racing_population(
const problem::base &prob): population(prob)
46 void racing_population::set_x_noeval(
const size_type idx,
const decision_vector &x)
49 pagmo_throw(index_error,
"invalid individual position");
51 if (!problem().verify_x(x)) {
52 pagmo_throw(value_error,
"decision vector is not compatible with problem");
56 m_container[idx].cur_x = x;
72 pagmo_throw(index_error,
"Invalid individual position in set_fc");
74 if (f.size() != problem().get_f_dimension()) {
75 pagmo_throw(value_error,
"Incompatible fitness dimension in set_fc");
77 if (c.size() != problem().get_c_dimension()) {
78 pagmo_throw(value_error,
"Incompatible constraint dimension in set_fc");
80 m_container[idx].cur_f = f;
81 m_container[idx].cur_c = c;
85 m_container[idx].best_f = f;
86 m_container[idx].best_c = c;
110 const fitness_vector::size_type f_size = problem().get_f_dimension();
111 const constraint_vector::size_type c_size = problem().get_c_dimension();
112 const decision_vector::size_type p_size = problem().get_dimension();
114 m_container.push_back(individual_type());
115 m_dom_list.push_back(std::vector<size_type>());
116 m_dom_count.push_back(0);
118 m_container.back().cur_x.resize(p_size);
119 m_container.back().cur_v.resize(p_size);
120 m_container.back().cur_c.resize(c_size);
121 m_container.back().cur_f.resize(f_size);
125 m_container.back().best_f.resize(f_size);
126 m_container.back().best_c.resize(c_size);
129 set_x_noeval(m_container.size() - 1, x);
139 std::vector<double> racing_population::get_rankings()
const
141 std::vector<double> rankings(size());
142 std::vector<size_type> raw_order = get_best_idx(size());
145 for(size_type i = 0; i < raw_order.size(); i++){
146 int ind_idx = raw_order[i];
147 rankings[ind_idx] = cur_rank;
153 std::vector<bool> tied(size() - 1,
false);
154 if(problem().get_f_dimension() == 1){
156 population::trivial_comparison_operator comparator(*
this);
157 for(size_type i = 0; i < size() - 1; i++){
158 if (!comparator(i, i+1) && !comparator(i+1, i)){
165 population::crowded_comparison_operator comparator(*
this);
166 for(size_type i = 0; i < size() - 1; i++){
167 if (!comparator(i, i+1) && !comparator(i+1, i)){
175 size_type cur_pos = 0;
176 size_type begin_avg_pos;
177 while(cur_pos < tied.size()){
178 begin_avg_pos = cur_pos;
179 while(tied[cur_pos]==1){
181 if(cur_pos >= tied.size()){
187 for(size_type i = begin_avg_pos; i <= cur_pos; i++){
188 avg_rank += rankings[i] / ((double)cur_pos - begin_avg_pos + 1);
190 for(size_type i = begin_avg_pos; i <= cur_pos; i++){
191 rankings[i] = avg_rank;
195 if(begin_avg_pos == cur_pos){
214 void f_race_assign_ranks(std::vector<racer_type>& racers,
const racing_population& racing_pop_full)
223 racing_population racing_pop(racing_pop_full.problem());
225 std::vector<size_type> idx_mapping;
226 for(size_type i = 0; i < racers.size(); i++){
227 if(racers[i].active){
228 racing_pop.push_back_noeval(dummy_x);
229 racing_pop.set_fc(racing_pop.size()-1, racing_pop_full.get_individual(i).cur_f, racing_pop_full.get_individual(i).cur_c);
230 idx_mapping.push_back(i);
235 std::vector<double> rankings = racing_pop.get_rankings();
236 for(
unsigned int i = 0; i < racing_pop.size(); i++){
237 racers[idx_mapping[i]].m_hist.push_back(rankings[i]);
242 for(size_type i = 0; i < rankings.size(); i++){
243 racer_type& cur_racer = racers[idx_mapping[i]];
244 cur_racer.m_mean = 0;
245 for(
unsigned int j = 0; j < cur_racer.length(); j++){
246 cur_racer.m_mean += (cur_racer.m_hist[j]) / (
double)cur_racer.length();
262 void f_race_adjust_ranks(std::vector<racer_type>& racers,
const std::vector<population::size_type>& deleted_racers)
264 for(
unsigned int i = 0; i < racers.size(); i++){
265 if(!racers[i].active)
continue;
266 for(
unsigned int j = 0; j < racers[i].length(); j++){
268 for(
unsigned int k = 0; k < deleted_racers.size(); k++){
269 if(racers[i].m_hist[j] > racers[deleted_racers[k]].m_hist[j]){
273 racers[i].m_hist[j] -= adjustment;
293 stat_test_result core_friedman_test(
const std::vector<std::vector<double> >& X,
double delta)
295 pagmo_assert(X.size() > 0);
297 unsigned int N = X.size();
298 unsigned int B = X[0].size();
301 std::vector<double> X_mean(N, 0);
302 for(
unsigned int i = 0; i < N; i++){
303 for(
unsigned int j = 0; j < X[i].size(); j++){
304 X_mean[i] += X[i][j];
306 X_mean[i] /= (double)X[i].size();
310 std::vector<double> R(N, 0);
312 double C1 = B * N * (N+1) * (N+1) / 4.0;
314 for(
unsigned int i = 0; i < N; i++){
315 for(
unsigned int j = 0; j < B; j++){
317 A1 += (X[i][j])*(X[i][j]);
322 for(
unsigned int i = 0; i < N; i++){
323 T1 += ((R[i] - B*(N+1)/2.0) * (R[i] - B*(N+1)/2.0));
325 T1 *= (N - 1) / (A1 - C1);
327 using boost::math::chi_squared;
328 using boost::math::students_t;
329 using boost::math::quantile;
331 chi_squared chi_squared_dist(N - 1);
333 double delta_quantile = quantile(chi_squared_dist, 1 - delta);
336 bool null_hypothesis_0 = (boost::math::isnan(T1) || T1 < delta_quantile);
338 stat_test_result res;
342 res.trivial = null_hypothesis_0;
344 res.is_better = std::vector<std::vector<bool> >(N, std::vector<bool>(N,
false));
346 if(!null_hypothesis_0){
347 std::vector<std::vector<bool> >& is_better = res.is_better;
349 students_t students_t_dist((N-1)*(B-1));
350 double t_delta2_quantile = quantile(students_t_dist, 1 - delta/2.0);
351 double Q = sqrt(((A1-C1) * 2.0 * B / ((B-1) * (N-1))) * (1 - T1 / (B*(N-1))));
352 for(
unsigned int i = 0; i < N; i++){
353 for(
unsigned int j = i + 1; j < N; j++){
354 double diff_r = fabs(R[i] - R[j]);
356 if(diff_r > t_delta2_quantile * Q){
357 if(X_mean[i] < X_mean[j]){
358 is_better[i][j] =
true;
360 if(X_mean[j] < X_mean[i]){
361 is_better[j][i] =
true;
379 stat_test_result friedman_test(std::vector<racer_type> &racers,
const std::vector<population::size_type> &in_race,
const racing_population &pop,
double delta)
381 f_race_assign_ranks(racers, pop);
387 std::vector<std::vector<double> > X;
388 for(
unsigned int i = 0; i < in_race.size(); i++){
389 X.push_back(racers[in_race[i]].m_hist);
393 stat_test_result ss_result = core_friedman_test(X, delta);
405 stat_test_result wilcoxon_ranksum_test(std::vector<racer_type> &racers,
const std::vector<population::size_type> &in_race,
const racing_population& wilcoxon_pop,
double delta)
407 pagmo_assert(in_race.size() == 2);
410 std::vector<double> rankings = wilcoxon_pop.get_rankings();
416 racers[in_race[0]].m_hist.push_back(rankings[wilcoxon_pop.size()/2 - 1]);
417 racers[in_race[1]].m_hist.push_back(rankings[wilcoxon_pop.size() - 1]);
420 for(std::vector<population::size_type>::const_iterator it = in_race.begin(); it != in_race.end(); it++){
421 racer_type& cur_racer = racers[*it];
422 cur_racer.m_mean = 0;
423 for(
unsigned int j = 0; j < cur_racer.length(); j++){
424 cur_racer.m_mean += (cur_racer.m_hist[j]) / (
double)cur_racer.length();
428 std::vector<std::vector<double> > X(2);
429 unsigned int n_samples = wilcoxon_pop.size() / 2;
430 for(
unsigned int i = 0; i < 2; i++){
431 X[i].resize(n_samples);
433 for(
unsigned int i = 0; i < wilcoxon_pop.size(); i++){
434 X[i%2][i/2] = rankings[i];
436 return core_wilcoxon_ranksum_test(X, delta);
440 std::size_t wilcoxon_faculty( std::size_t n )
445 return( n * wilcoxon_faculty( n-1 ) );
449 double wilcoxon_frequency(
double u,
int sampleSizeA,
int sampleSizeB )
451 if( u < 0. || sampleSizeA < 0 || sampleSizeB < 0 )
454 if( u == 0 && sampleSizeA >= 0 && sampleSizeB >= 0 )
457 return( wilcoxon_frequency( u - sampleSizeB, sampleSizeA - 1, sampleSizeB ) + wilcoxon_frequency( u, sampleSizeA, sampleSizeB - 1 ) );
464 stat_test_result core_wilcoxon_ranksum_test(
const std::vector<std::vector<double> > &X,
double delta)
467 pagmo_throw(value_error,
"Wilcoxon rank-sum test is applicable only when the group size is 2");
472 std::vector<double> rank_sum(N, 0);
473 for(
unsigned int i = 0; i < N; i++){
474 for(
unsigned int j = 0; j < X[i].size(); j++){
475 rank_sum[i] += X[i][j];
480 stat_test_result res(N);
482 int sizeA = X[0].size();
483 int sizeB = X[1].size();
484 if(sizeA < 12 && sizeB < 12){
489 int wA = rank_sum[0];
491 double uA = wA - sizeA * ( sizeA + 1 ) / 2.;
493 double pA = (double)( wilcoxon_faculty( sizeA ) * wilcoxon_faculty( sizeB ) ) / (
double)( wilcoxon_faculty( sizeA + sizeB ) ) * wilcoxon_frequency( uA, sizeA, sizeB );
497 if(rank_sum[0] > rank_sum[1]){
498 res.is_better[1][0] =
true;
501 res.is_better[0][1] =
true;
507 using boost::math::normal;
508 int n1 = X[0].size();
509 int n2 = X[1].size();
510 normal normal_dist(n1*n2/2, sqrt(n1*n2*(n1+n2+1.0)/12.0));
511 double delta_quantile_upp = quantile(normal_dist, 1 - delta);
512 if(rank_sum[0] > rank_sum[1] && rank_sum[0] > delta_quantile_upp){
514 res.is_better[1][0] =
true;
516 else if(rank_sum[1] > rank_sum[0] && rank_sum[1] > delta_quantile_upp){
518 res.is_better[0][1] =
true;
std::vector< double > decision_vector
Decision vector type.
std::vector< double > fitness_vector
Fitness vector type.
std::vector< double > constraint_vector
Constraint vector type.
container_type::size_type size_type
Population size type.