Projet du cours MPRI 2.24.2 "Résolution de problèmes d'optimisation avec heuristiques de recherche" : https://wikimpri.dptinfo.ens-cachan.fr/doku.php?id=cours:c-2-24-2
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

  1. #include "heuristics/GGA.h"
  2. int* selector(int i, void* object) {
  3. Candidate** tab = (Candidate**) object;
  4. return tab[i]->sol;
  5. }
  6. GGA::GGA(int mu, int lda, int selection, int crossover_method, int version, std::default_random_engine& randomizer) {
  7. m_mu = mu;
  8. m_lambda = lda;
  9. m_selection = selection;
  10. m_crossover_method = crossover_method;
  11. m_version = version;
  12. m_randomizer = randomizer;
  13. m_is_prepared = false;
  14. x_tab = nullptr;
  15. if(m_mu==0 || (selection==COMMA && m_mu>m_lambda)) {
  16. std::cout << "Bad parameters for GA !" << std::endl;
  17. exit(EXIT_FAILURE);
  18. }
  19. }
  20. void GGA::prepare_tab() {
  21. if(m_is_prepared) return;
  22. x_tab = new Candidate*[m_mu+m_lambda];
  23. for(int i=0; i<m_mu+m_lambda; i++) {
  24. int* x = m_problem->get_random_candidate();
  25. x_tab[i] = new Candidate(x, 0);
  26. }
  27. m_uniform_dist = std::uniform_int_distribution<int>(0, m_mu-1);
  28. m_is_prepared = true;
  29. }
  30. Result GGA::run() {
  31. MasterMind* pb = m_problem;
  32. prepare_tab();
  33. clear_record();
  34. // Initial parents
  35. for(int i=0; i<m_mu; i++) {
  36. int* x = pb->get_random_candidate();
  37. delete[] x_tab[i]->sol;
  38. x_tab[i]->sol = x;
  39. x_tab[i]->value = pb->try_candidate(x);
  40. }
  41. std::sort(x_tab, x_tab+m_mu, cmp_candidates);
  42. Candidate* x_best = x_tab[0];
  43. int nb_calls = m_mu;
  44. while(! pb->is_optimal(x_best->sol, x_best->value, m_objective)) {
  45. double progress = pb->get_progress(x_best->sol, x_best->value);
  46. double sbm_proba = get_sbm_proba(progress);
  47. std::binomial_distribution<int> mutation = std::binomial_distribution<int>(m_problem->get_max_radius(), sbm_proba);
  48. std::bernoulli_distribution crossover(get_crossover_proba(progress));
  49. // Evaluation fitness of the parent population
  50. std::vector<double> parent_fitness_dist_tab;
  51. for(int i=0; i<m_mu; i++)
  52. parent_fitness_dist_tab.push_back(exp(x_tab[i]->value));
  53. std::discrete_distribution<int> parent_fitness_dist(parent_fitness_dist_tab.begin(), parent_fitness_dist_tab.end());
  54. // Variation phase
  55. for(int i=0; i<m_lambda; i++) {
  56. Candidate* y = x_tab[m_mu+i];
  57. bool crossover_step = crossover(m_randomizer);
  58. switch(m_version) {
  59. case GA_V1:
  60. if(crossover_step) {
  61. if(m_mu == 1)
  62. pb->copy_candidate(x_tab[m_uniform_dist(m_randomizer)]->sol, y->sol);
  63. else
  64. pb->crossover(y->sol, (void*) x_tab, m_mu, &selector, m_crossover_method);
  65. } else {
  66. int r = mutation(m_randomizer);
  67. if(sbm_proba < 0)
  68. r = round(m_problem->get_max_radius() * (-sbm_proba));
  69. int parent_index = m_uniform_dist(m_randomizer);
  70. pb->copy_candidate(x_tab[parent_index]->sol, y->sol);
  71. pb->modify_with_radius(y->sol, r);
  72. }
  73. y->value = pb->try_candidate(y->sol);
  74. break;
  75. case GA_V2:
  76. if(crossover_step) {
  77. if(m_mu == 1)
  78. pb->copy_candidate(x_tab[m_uniform_dist(m_randomizer)]->sol, y->sol);
  79. else {
  80. // Choose parents
  81. int ind1 = parent_fitness_dist(m_randomizer);
  82. int ind2 = ind1;
  83. while(ind1 == ind2)
  84. ind2 = parent_fitness_dist(m_randomizer);
  85. // Proceed crossover
  86. int pos1 = (ind1 <= 1) ? ind1 : ((ind2 <= 1) ? 1-ind2 : 0);
  87. int pos2 = 1-pos1;
  88. swap_candidates(x_tab, pos1, ind1);
  89. swap_candidates(x_tab, pos2, ind2);
  90. pb->crossover(y->sol, (void*) x_tab, 2, &selector, m_crossover_method);
  91. swap_candidates(x_tab, pos1, ind1);
  92. swap_candidates(x_tab, pos2, ind2);
  93. }
  94. } else {
  95. int parent_index = parent_fitness_dist(m_randomizer);
  96. pb->copy_candidate(x_tab[parent_index]->sol, y->sol);
  97. }
  98. int r = mutation(m_randomizer);
  99. pb->modify_with_radius(y->sol, r);
  100. y->value = pb->try_candidate(y->sol);
  101. break;
  102. }
  103. }
  104. // Selection phase
  105. if(m_selection == PLUS) {
  106. // Selection among parent population and offspring population
  107. std::sort(x_tab, x_tab+(m_mu+m_lambda), cmp_candidates);
  108. x_best = x_tab[0];
  109. } else {
  110. // Selection among ONLY offspring population
  111. std::sort(x_tab+(m_mu), x_tab+(m_mu+m_lambda), cmp_candidates);
  112. for(int i=0; i<m_mu; i++)
  113. swap_candidates(x_tab, i, m_mu+i);
  114. x_best = x_tab[0];
  115. }
  116. nb_calls += m_lambda;
  117. record(nb_calls, x_best->value);
  118. if(m_abortion_limit > 0 && nb_calls >= m_abortion_limit) {
  119. int* final_sol = pb->get_random_candidate();
  120. pb->copy_candidate(x_best->sol, final_sol);
  121. return Result(final_sol, x_best->value, nb_calls, true);
  122. }
  123. }
  124. int* final_sol = pb->get_random_candidate();
  125. pb->copy_candidate(x_best->sol, final_sol);
  126. return Result(final_sol, x_best->value, nb_calls);
  127. }
  128. GGA::~GGA() {
  129. if(m_is_prepared) {
  130. for(int i=0, s=m_mu+m_lambda; i<s; i++) {
  131. Candidate* y = x_tab[i];
  132. delete[] y->sol;
  133. delete y;
  134. }
  135. delete[] x_tab;
  136. }
  137. }