pyVolutionary 2.6.6__tar.gz → 2.7.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/PKG-INFO +4 -1
  2. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/README.md +3 -0
  3. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyproject.toml +1 -1
  4. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/abstract.py +56 -23
  5. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/african_vulture/african_vulture_optimization.py +7 -3
  6. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/ant_colony/ant_colony_optimization.py +6 -3
  7. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/ant_lion/ant_lion_optimization.py +9 -9
  8. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/aquila/aquila_optimization.py +1 -1
  9. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/archimede/archimede_optimization.py +1 -1
  10. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/bacterial_foraging/bacterial_foraging_optimization.py +21 -15
  11. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/bat/bat_optimization.py +1 -1
  12. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/battle_royale/battle_royale_optimization.py +1 -1
  13. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/bee_colony/bee_colony_optimization.py +8 -5
  14. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/biogeography_based/biogeography_based_optimization.py +3 -3
  15. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/brain_storm/brain_storm_optimization.py +3 -3
  16. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/brain_storm/improved_brain_storm_optimization.py +3 -3
  17. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/brown_bear/brown_bear_optimization.py +2 -2
  18. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/camel_caravan/camel_caravan_optimization.py +1 -1
  19. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/cat_swarm/cat_swarm_optimization.py +5 -5
  20. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/chaos_game/chaos_game_optimization.py +4 -4
  21. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/chernobyl_disaster/chernobyl_disaster_optimization.py +1 -1
  22. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/coati/coati_optimization.py +4 -4
  23. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/coral_reef/coral_reef_optimization.py +7 -4
  24. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/coronavirus_herd_immunity/coronavirus_herd_immunity_optimization.py +9 -9
  25. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/coyotes/coyotes_optimization.py +1 -1
  26. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/cuckoo_search/cuckoo_search_optimization.py +3 -2
  27. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/dragonfly/dragonfly_optimization.py +10 -15
  28. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/dwarf_mongoose/dwarf_mongoose_optimization.py +1 -1
  29. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/earthworms/earthworms_optimization.py +32 -13
  30. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/egret_swarm/egret_swarm_optimization.py +1 -1
  31. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/electromagnetic_field/electromagnetic_field_optimization.py +1 -1
  32. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/elephant_herd/elephant_herd_optimization.py +1 -1
  33. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/energy_valley/energy_valley_optimization.py +5 -5
  34. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/ficks_law/ficks_law_optimization.py +10 -6
  35. pyvolutionary-2.7.0/pyvolutionary/firefly_swarm/firefly_swarm_optimization.py +106 -0
  36. pyvolutionary-2.7.0/pyvolutionary/firefly_swarm/models.py +61 -0
  37. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/firehawk/firehawk_optimization.py +2 -2
  38. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/fireworks/fireworks_optimization.py +13 -9
  39. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/fish_school_search/fish_school_search_optimization.py +29 -23
  40. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/flower_pollination_algorithm/flower_pollination_algorithm_optimization.py +1 -1
  41. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/forensic_based_investigation/forensic_based_investigation_optimization.py +4 -4
  42. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/forest_algorithm/forest_optimization_algorithm.py +3 -3
  43. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/fox/fox_optimization.py +6 -1
  44. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/gaining_sharing_knowledge_algorithm/gaining_sharing_knowledge_optimization.py +1 -1
  45. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/genetic_algorithm/classes.py +6 -5
  46. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/genetic_algorithm/genetic_algorithm_optimization.py +4 -2
  47. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/germinal_center/germinal_center_optimization.py +6 -5
  48. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/giant_trevally/giant_trevally_optimization.py +3 -3
  49. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/giza_pyramid_construction/giza_pyramid_construction_optimization.py +1 -1
  50. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/golden_jackal/golden_jackal_optimization.py +3 -3
  51. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/grasshopper/grasshopper_optimization_algorithm.py +9 -7
  52. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/grey_wolf/grey_wolf_optimization.py +1 -1
  53. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/harmony_search/harmony_search_optimization.py +3 -2
  54. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/helpers.py +84 -24
  55. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/henry_gas_solubility/henry_gas_solubility_optimization.py +2 -2
  56. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/hunger_games_search/hunger_games_search_optimization.py +1 -1
  57. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/hypertuner.py +26 -13
  58. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/imperialist_competitive/classes.py +3 -1
  59. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/imperialist_competitive/imperialist_competitive_optimization.py +41 -24
  60. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/invasive_weed/invasive_weed_optimization.py +1 -1
  61. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/krill_herd/krill_herd_optimization.py +35 -23
  62. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/levi_jaya_swarm/levy_flight_jaya_swarm_optimization.py +1 -1
  63. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/marine_predators/marine_predators_optimization.py +2 -2
  64. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/models.py +155 -36
  65. pyvolutionary-2.7.0/pyvolutionary/monarch_butterfly/monarch_butterfly_optimization.py +83 -0
  66. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/moth_flame/moth_flame_optimization.py +1 -1
  67. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/mountain_gazelle/mountain_gazelle_optimization.py +1 -1
  68. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/multi_verse/multi_verse_optimization.py +1 -1
  69. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/multitask.py +23 -15
  70. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/nuclear_reaction/nuclear_reaction_optimization.py +3 -3
  71. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/osprey/osprey_optimization.py +2 -2
  72. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/particle_swarm/particle_swarm_optimization.py +3 -4
  73. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/pathfinder_algorithm/pathfinder_algorithm_optimization.py +1 -1
  74. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/pelican/pelican_optimization.py +2 -2
  75. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/runge_kutta/runge_kutta_optimization.py +1 -1
  76. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/salp_swarm/salp_swarm_optimization.py +1 -1
  77. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/seagull/seagull_optimization.py +1 -1
  78. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/serval/serval_optimization.py +2 -2
  79. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/siberian_tiger/siberian_tiger_optimization.py +2 -2
  80. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/sine_cosine_algorithm/qle_sine_cosine_algorithm_optimization.py +2 -2
  81. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/sine_cosine_algorithm/sine_cosine_algorithm_optimization.py +1 -1
  82. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/spotted_hyena/spotted_hyena_optimization.py +4 -4
  83. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/success_history_intelligent/success_history_intelligent_optimization.py +5 -1
  84. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/swarm_hill_climbing/swarm_hill_climbing_optimization.py +1 -1
  85. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/tasmanian_devil/tasmanian_devil_optimization.py +2 -2
  86. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/tuna_swarm/tuna_swarm_optimization.py +1 -1
  87. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/virus_colony_search/virus_colony_search_optimization.py +3 -3
  88. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/walrus/walrus_optimization.py +2 -2
  89. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/war_strategy/war_strategy_optimization.py +1 -1
  90. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/water_cycle/water_cycle_optimization.py +17 -5
  91. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/whales/whales_optimization.py +1 -1
  92. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/wildebeest_herd/wildebeest_herd_optimization.py +6 -6
  93. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/wind_driven/wind_driven_optimization.py +1 -1
  94. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/zebra/zebra_optimization.py +2 -2
  95. pyvolutionary-2.6.6/pyvolutionary/firefly_swarm/firefly_swarm_optimization.py +0 -76
  96. pyvolutionary-2.6.6/pyvolutionary/firefly_swarm/models.py +0 -37
  97. pyvolutionary-2.6.6/pyvolutionary/monarch_butterfly/monarch_butterfly_optimization.py +0 -74
  98. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/LICENSE +0 -0
  99. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/__init__.py +0 -0
  100. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/african_vulture/__init__.py +0 -0
  101. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/african_vulture/models.py +0 -0
  102. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/ant_colony/__init__.py +0 -0
  103. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/ant_colony/models.py +0 -0
  104. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/ant_lion/__init__.py +0 -0
  105. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/ant_lion/models.py +0 -0
  106. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/aquila/__init__.py +0 -0
  107. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/aquila/models.py +0 -0
  108. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/archimede/__init__.py +0 -0
  109. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/archimede/models.py +0 -0
  110. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/bacterial_foraging/__init__.py +0 -0
  111. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/bacterial_foraging/models.py +0 -0
  112. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/bat/__init__.py +0 -0
  113. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/bat/models.py +0 -0
  114. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/battle_royale/__init__.py +0 -0
  115. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/battle_royale/models.py +0 -0
  116. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/bee_colony/__init__.py +0 -0
  117. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/bee_colony/models.py +0 -0
  118. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/biogeography_based/__init__.py +0 -0
  119. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/biogeography_based/models.py +0 -0
  120. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/brain_storm/__init__.py +0 -0
  121. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/brain_storm/models.py +0 -0
  122. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/brown_bear/__init__.py +0 -0
  123. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/brown_bear/models.py +0 -0
  124. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/camel_caravan/__init__.py +0 -0
  125. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/camel_caravan/models.py +0 -0
  126. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/cat_swarm/__init__.py +0 -0
  127. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/cat_swarm/models.py +0 -0
  128. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/chaos_game/__init__.py +0 -0
  129. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/chaos_game/models.py +0 -0
  130. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/chernobyl_disaster/__init__.py +0 -0
  131. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/chernobyl_disaster/models.py +0 -0
  132. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/coati/__init__.py +0 -0
  133. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/coati/models.py +0 -0
  134. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/coral_reef/__init__.py +0 -0
  135. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/coral_reef/models.py +0 -0
  136. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/coronavirus_herd_immunity/__init__.py +0 -0
  137. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/coronavirus_herd_immunity/models.py +0 -0
  138. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/coyotes/__init__.py +0 -0
  139. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/coyotes/models.py +0 -0
  140. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/cuckoo_search/__init__.py +0 -0
  141. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/cuckoo_search/models.py +0 -0
  142. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/dragonfly/__init__.py +0 -0
  143. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/dragonfly/models.py +0 -0
  144. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/dwarf_mongoose/__init__.py +0 -0
  145. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/dwarf_mongoose/models.py +0 -0
  146. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/earthworms/__init__.py +0 -0
  147. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/earthworms/models.py +0 -0
  148. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/egret_swarm/__init__.py +0 -0
  149. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/egret_swarm/models.py +0 -0
  150. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/electromagnetic_field/__init__.py +0 -0
  151. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/electromagnetic_field/models.py +0 -0
  152. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/elephant_herd/__init__.py +0 -0
  153. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/elephant_herd/models.py +0 -0
  154. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/energy_valley/__init__.py +0 -0
  155. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/energy_valley/models.py +0 -0
  156. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/enums.py +0 -0
  157. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/ficks_law/__init__.py +0 -0
  158. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/ficks_law/models.py +0 -0
  159. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/firefly_swarm/__init__.py +0 -0
  160. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/firehawk/__init__.py +0 -0
  161. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/firehawk/models.py +0 -0
  162. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/fireworks/__init__.py +0 -0
  163. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/fireworks/models.py +0 -0
  164. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/fish_school_search/__init__.py +0 -0
  165. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/fish_school_search/models.py +0 -0
  166. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/flower_pollination_algorithm/__init__.py +0 -0
  167. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/flower_pollination_algorithm/models.py +0 -0
  168. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/forensic_based_investigation/__init__.py +0 -0
  169. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/forensic_based_investigation/models.py +0 -0
  170. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/forest_algorithm/__init__.py +0 -0
  171. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/forest_algorithm/models.py +0 -0
  172. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/fox/__init__.py +0 -0
  173. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/fox/models.py +0 -0
  174. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/gaining_sharing_knowledge_algorithm/__init__.py +0 -0
  175. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/gaining_sharing_knowledge_algorithm/models.py +0 -0
  176. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/genetic_algorithm/__init__.py +0 -0
  177. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/genetic_algorithm/models.py +0 -0
  178. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/germinal_center/__init__.py +0 -0
  179. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/germinal_center/models.py +0 -0
  180. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/giant_trevally/__init__.py +0 -0
  181. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/giant_trevally/models.py +0 -0
  182. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/giza_pyramid_construction/__init__.py +0 -0
  183. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/giza_pyramid_construction/models.py +0 -0
  184. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/golden_jackal/__init__.py +0 -0
  185. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/golden_jackal/models.py +0 -0
  186. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/grasshopper/__init__.py +0 -0
  187. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/grasshopper/models.py +0 -0
  188. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/grey_wolf/__init__.py +0 -0
  189. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/grey_wolf/models.py +0 -0
  190. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/harmony_search/__init__.py +0 -0
  191. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/harmony_search/models.py +0 -0
  192. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/heap_based/__init__.py +0 -0
  193. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/heap_based/heap_based_optimization.py +0 -0
  194. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/heap_based/models.py +0 -0
  195. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/henry_gas_solubility/__init__.py +0 -0
  196. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/henry_gas_solubility/models.py +0 -0
  197. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/hunger_games_search/__init__.py +0 -0
  198. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/hunger_games_search/models.py +0 -0
  199. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/imperialist_competitive/__init__.py +0 -0
  200. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/imperialist_competitive/models.py +0 -0
  201. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/invasive_weed/__init__.py +0 -0
  202. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/invasive_weed/models.py +0 -0
  203. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/krill_herd/__init__.py +0 -0
  204. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/krill_herd/models.py +0 -0
  205. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/levi_jaya_swarm/__init__.py +0 -0
  206. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/levi_jaya_swarm/models.py +0 -0
  207. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/marine_predators/__init__.py +0 -0
  208. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/marine_predators/models.py +0 -0
  209. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/monarch_butterfly/__init__.py +0 -0
  210. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/monarch_butterfly/models.py +0 -0
  211. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/moth_flame/__init__.py +0 -0
  212. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/moth_flame/models.py +0 -0
  213. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/mountain_gazelle/__init__.py +0 -0
  214. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/mountain_gazelle/models.py +0 -0
  215. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/multi_verse/__init__.py +0 -0
  216. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/multi_verse/models.py +0 -0
  217. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/nuclear_reaction/__init__.py +0 -0
  218. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/nuclear_reaction/models.py +0 -0
  219. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/osprey/__init__.py +0 -0
  220. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/osprey/models.py +0 -0
  221. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/particle_swarm/__init__.py +0 -0
  222. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/particle_swarm/models.py +0 -0
  223. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/pathfinder_algorithm/__init__.py +0 -0
  224. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/pathfinder_algorithm/models.py +0 -0
  225. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/pelican/__init__.py +0 -0
  226. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/pelican/models.py +0 -0
  227. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/runge_kutta/__init__.py +0 -0
  228. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/runge_kutta/models.py +0 -0
  229. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/salp_swarm/__init__.py +0 -0
  230. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/salp_swarm/models.py +0 -0
  231. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/seagull/__init__.py +0 -0
  232. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/seagull/models.py +0 -0
  233. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/serval/__init__.py +0 -0
  234. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/serval/models.py +0 -0
  235. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/siberian_tiger/__init__.py +0 -0
  236. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/siberian_tiger/models.py +0 -0
  237. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/sine_cosine_algorithm/__init__.py +0 -0
  238. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/sine_cosine_algorithm/classes.py +0 -0
  239. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/sine_cosine_algorithm/models.py +0 -0
  240. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/spotted_hyena/__init__.py +0 -0
  241. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/spotted_hyena/models.py +0 -0
  242. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/success_history_intelligent/__init__.py +0 -0
  243. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/success_history_intelligent/models.py +0 -0
  244. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/swarm_hill_climbing/__init__.py +0 -0
  245. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/swarm_hill_climbing/models.py +0 -0
  246. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/tasmanian_devil/__init__.py +0 -0
  247. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/tasmanian_devil/models.py +0 -0
  248. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/tuna_swarm/__init__.py +0 -0
  249. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/tuna_swarm/models.py +0 -0
  250. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/utils.py +0 -0
  251. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/virus_colony_search/__init__.py +0 -0
  252. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/virus_colony_search/models.py +0 -0
  253. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/walrus/__init__.py +0 -0
  254. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/walrus/models.py +0 -0
  255. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/war_strategy/__init__.py +0 -0
  256. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/war_strategy/models.py +0 -0
  257. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/water_cycle/__init__.py +0 -0
  258. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/water_cycle/models.py +0 -0
  259. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/whales/__init__.py +0 -0
  260. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/whales/models.py +0 -0
  261. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/wildebeest_herd/__init__.py +0 -0
  262. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/wildebeest_herd/models.py +0 -0
  263. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/wind_driven/__init__.py +0 -0
  264. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/wind_driven/models.py +0 -0
  265. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/zebra/__init__.py +0 -0
  266. {pyvolutionary-2.6.6 → pyvolutionary-2.7.0}/pyvolutionary/zebra/models.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyVolutionary
3
- Version: 2.6.6
3
+ Version: 2.7.0
4
4
  Summary: pyVolutionary is a package collecting metaheuristic algorithms, available for free usage and able to solve a wide range of optimization problems.
5
5
  License: GPL-3.0-only
6
6
  License-File: LICENSE
@@ -331,6 +331,9 @@ As an illustration, consider a TSP scenario involving 5 cities denoted as A, B,
331
331
  be denoted by the permutation [A, B, D, E, C], illustrating the order in which the cities are visited. This interpretation
332
332
  indicates that the tour initiates at city A, proceeds to city B, then D, E, and ultimately C before looping back to city A.
333
333
 
334
+ A `PermutationVariable` spans one dimension per item: the position of an agent holds a key for each item, and the
335
+ permutation is the order of the items by increasing key. Use `transform_solution` to get the permutation of the items.
336
+
334
337
  The following code snippet illustrates how to solve the TSP with the Virus Colony Search Optimization algorithm.
335
338
 
336
339
  ```python
@@ -304,6 +304,9 @@ As an illustration, consider a TSP scenario involving 5 cities denoted as A, B,
304
304
  be denoted by the permutation [A, B, D, E, C], illustrating the order in which the cities are visited. This interpretation
305
305
  indicates that the tour initiates at city A, proceeds to city B, then D, E, and ultimately C before looping back to city A.
306
306
 
307
+ A `PermutationVariable` spans one dimension per item: the position of an agent holds a key for each item, and the
308
+ permutation is the order of the items by increasing key. Use `transform_solution` to get the permutation of the items.
309
+
307
310
  The following code snippet illustrates how to solve the TSP with the Virus Colony Search Optimization algorithm.
308
311
 
309
312
  ```python
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pyVolutionary"
3
- version = "2.6.6"
3
+ version = "2.7.0"
4
4
  description = "pyVolutionary is a package collecting metaheuristic algorithms, available for free usage and able to solve a wide range of optimization problems."
5
5
  authors = ["Matteo Cacciola <matteo.cacciola@gmail.com>"]
6
6
  license = "GPL-3.0-only"
@@ -1,3 +1,4 @@
1
+ import random
1
2
  from abc import ABC, abstractmethod
2
3
  from typing import Generic, Final, Any
3
4
  import numpy as np
@@ -66,14 +67,24 @@ class OptimizationAbstract(ABC, Generic[T]):
66
67
  def name(self):
67
68
  return self.__class__.__name__
68
69
 
69
- def _fcn(self, x: list[float] | np.ndarray) -> float | list[float]:
70
+ def _fcn(self, x: list[float] | np.ndarray, corrected: bool = False) -> float | list[float]:
70
71
  """
71
72
  This method evaluates the objective function.
72
73
  :param x: the position to evaluate
74
+ :param corrected: whether the position has already been corrected by the task
73
75
  :return the cost of the position, or the list of costs if the objective function is multi-objective
74
76
  :rtype: float | list[float]
75
77
  """
76
- return self._task.solve(x) if self._task.minmax == TaskType.MIN else -1 * self._task.solve(x)
78
+ # correcting an already corrected solution is a no-op for the built-in variables: skip it, and pass a copy of
79
+ # the position, so that the objective function can not alter it
80
+ if corrected and self._task.idempotent_correction:
81
+ cost = self._task.objective_function(list(x))
82
+ else:
83
+ cost = self._task.solve(x)
84
+ if self._task.minmax == TaskType.MIN:
85
+ return cost
86
+ # multi-objective functions return a list of costs: negate each of them
87
+ return [-c for c in cost] if isinstance(cost, (list, tuple, np.ndarray)) else -cost
77
88
 
78
89
  def _init_agent(self, position: list[Any] | np.ndarray | None = None) -> Agent:
79
90
  """
@@ -81,7 +92,7 @@ class OptimizationAbstract(ABC, Generic[T]):
81
92
  not provided. The other properties of the agent.
82
93
  """
83
94
  position = self._task.initial_solution(position)
84
- cost = self._fcn(position)
95
+ cost = self._fcn(position, corrected=True)
85
96
  n_weights = len(self._task.objective_weights) if self._task.objective_weights is not None else 1
86
97
  n_objectives = len(cost) if isinstance(cost, list) else 1
87
98
  if n_weights != n_objectives:
@@ -100,10 +111,25 @@ class OptimizationAbstract(ABC, Generic[T]):
100
111
 
101
112
  # Parallel mode
102
113
  with get_pool_executor(self._mode, self._workers) as executor:
103
- executors = [executor.submit(self._init_agent) for _ in range(0, n_agents)]
114
+ if self._mode == ModeSolver.PROCESS:
115
+ # each worker process inherits a copy of the parent's random state: seed each job independently, or
116
+ # different workers would generate identical agents
117
+ seeds = np.random.randint(0, 2**31 - 1, size=n_agents)
118
+ executors = [executor.submit(self._init_agent_with_seed, int(seed)) for seed in seeds]
119
+ else:
120
+ executors = [executor.submit(self._init_agent) for _ in range(0, n_agents)]
104
121
  pop = get_pool_results(executors)
105
122
  return pop
106
123
 
124
+ def _init_agent_with_seed(self, seed: int) -> Agent:
125
+ """
126
+ This method initializes a random agent after seeding the random generators. It is used in process mode.
127
+ :param seed: the seed of the random generators
128
+ """
129
+ np.random.seed(seed)
130
+ random.seed(seed)
131
+ return self._init_agent()
132
+
107
133
  def _init_population(self):
108
134
  """
109
135
  This method initializes the population of the optimization algorithm.
@@ -121,19 +147,11 @@ class OptimizationAbstract(ABC, Generic[T]):
121
147
  self._population = sort_by_cost(self._population)
122
148
  new_population = sort_by_cost(new_population)
123
149
 
124
- # Serial mode
125
- if self._mode == ModeSolver.SERIAL:
126
- self._population = [
127
- self._greedy_select_agent(agent, new_population[idx]) for idx, agent in enumerate(self._population)
128
- ]
129
- return
130
-
131
- # Parallel mode
132
- with get_pool_executor(self._mode, self._workers) as executor:
133
- executors = [executor.submit(
134
- self._greedy_select_agent, agent, new_population[idx]
135
- ) for idx, agent in enumerate(self._population)]
136
- self._population = get_pool_results(executors)
150
+ # the selection is a mere comparison of costs: dispatching it to a pool of workers would be far more
151
+ # expensive than running it serially
152
+ self._population = [
153
+ self._greedy_select_agent(agent, new_population[idx]) for idx, agent in enumerate(self._population)
154
+ ]
137
155
 
138
156
  def _greedy_select_agent(self, agent: T, new_agent: T) -> T:
139
157
  """
@@ -207,8 +225,16 @@ class OptimizationAbstract(ABC, Generic[T]):
207
225
  raise ValueError("Invalid configuration")
208
226
 
209
227
  np.random.seed(task.seed)
228
+ random.seed(task.seed)
210
229
  evolution: list[Population] = []
211
230
 
231
+ # reset the state of any previous run, so that the same instance can be used to optimize several times
232
+ self._current_cycle = 1
233
+ self._errors = []
234
+ self._error_diffs = []
235
+ self._best_agent = None
236
+ self._worst_agent = None
237
+
212
238
  if workers is not None:
213
239
  if workers <= 0:
214
240
  raise ValueError("Invalid number of workers. It must be greater than 0")
@@ -235,6 +261,7 @@ class OptimizationAbstract(ABC, Generic[T]):
235
261
  self._init_population()
236
262
  evolution.append(Population(agents=self._population, task_type=task.minmax))
237
263
  (self._best_agent, ), (self._worst_agent, ) = special_agents(self._population, n_best=1, n_worst=1)
264
+ self._best_agent = self._best_agent.model_copy()
238
265
 
239
266
  self.after_initialization()
240
267
 
@@ -249,7 +276,11 @@ class OptimizationAbstract(ABC, Generic[T]):
249
276
  # append the current population to the evolution, being sure that costs and fitness are updated
250
277
  evolution.append(Population(agents=self._population, task_type=task.minmax))
251
278
 
252
- (self._best_agent, ), (self._worst_agent, ) = special_agents(self._population, n_best=1, n_worst=1)
279
+ # the best agent is the best one found so far (the global best): an algorithm may lose it from the
280
+ # population, but it must neither be lost in the result nor stop guiding the algorithms using it
281
+ (current_best, ), (self._worst_agent, ) = special_agents(self._population, n_best=1, n_worst=1)
282
+ if current_best.cost < self._best_agent.cost:
283
+ self._best_agent = current_best.model_copy()
253
284
 
254
285
  # stop when the error is below the error criteria or when the maximum number of cycles is reached
255
286
  error, fitness, has_to_stop = self.__error_check__()
@@ -280,14 +311,13 @@ class OptimizationAbstract(ABC, Generic[T]):
280
311
  # Get the optimal population
281
312
  avg_fit = average_fitness(self._population)
282
313
  current_error = abs(1 - avg_fit)
283
- previous_error = self._errors[-1] if len(self._errors) > 0 else 0
314
+ # Append the difference between the current error and the previous one to the list of error differences
315
+ if len(self._errors) > 0:
316
+ self._error_diffs.append(current_error - self._errors[-1])
284
317
 
285
318
  # Append the current error to the list of errors
286
319
  self._errors.append(current_error)
287
320
 
288
- # Append the difference between the current error and the previous one to the list of error differences
289
- self._error_diffs.append(current_error - previous_error)
290
-
291
321
  return current_error, avg_fit, self.__should_stop__(current_error)
292
322
 
293
323
  def __should_stop__(self, current_error: float) -> bool:
@@ -301,9 +331,12 @@ class OptimizationAbstract(ABC, Generic[T]):
301
331
  has_to_stop = cycle >= max_cycles
302
332
 
303
333
  # Evaluate the early stopping criteria
334
+ # (stop when the error has not improved, i.e. decreased, by at least min_delta for patience cycles)
304
335
  if early_stopping is not None:
305
336
  min_delta, patience = early_stopping.min_delta, early_stopping.patience
306
- has_to_stop |= all([diff < 0 and abs(diff) < min_delta for diff in self._error_diffs[-patience:]])
337
+ has_to_stop |= len(self._error_diffs) >= patience and all(
338
+ -diff < min_delta for diff in self._error_diffs[-patience:]
339
+ )
307
340
 
308
341
  # Stop when the error is below the error criteria
309
342
  if fitness_error is not None:
@@ -35,13 +35,17 @@ class AfricanVultureOptimization(OptimizationAbstract):
35
35
  best_x1 = np.array(best_list[0].position)
36
36
  best_x2 = np.array(best_list[1].position)
37
37
  if np.random.random() < p2:
38
- A = best_x1 - ((best_x1 * position) / (best_x1 - position ** 2)) * F
39
- B = best_x2 - ((best_x2 * position) / (best_x2 - position ** 2)) * F
38
+ A = best_x1 - safe_ratio(best_x1 * position, best_x1 - position ** 2) * F
39
+ B = best_x2 - safe_ratio(best_x2 * position, best_x2 - position ** 2) * F
40
40
  return (A + B) / 2
41
41
  return rand_pos - np.abs(rand_pos - position) * F * get_levy_flight_step(
42
42
  beta=1.5, multiplier=1., size=dim, case=-1
43
43
  )
44
44
 
45
+ def safe_ratio(numerator: np.ndarray, denominator: np.ndarray) -> np.ndarray:
46
+ # the ratio is zero where the denominator is zero (it was NaN or infinite, e.g. with best_x = position = 0)
47
+ return np.divide(numerator, denominator, out=np.zeros_like(numerator, dtype=float), where=denominator != 0)
48
+
45
49
  def exploration_position_phase2(rand_pos: np.ndarray, position: np.ndarray) -> np.ndarray:
46
50
  if np.random.random() < p3:
47
51
  return (
@@ -66,7 +70,7 @@ class AfricanVultureOptimization(OptimizationAbstract):
66
70
  else: # Exploitation Phase 2
67
71
  pos_new = exploration_position_phase2(rand_pos, position)
68
72
  return self._greedy_select_agent(
69
- vulture, AfricanVulture(**self._init_agent(pos_new).model_dump())
73
+ vulture, AfricanVulture(**self._init_agent(pos_new).__dict__)
70
74
  )
71
75
 
72
76
  cycle_ratio = self._current_cycle / self._config.max_cycles
@@ -2,7 +2,7 @@ from typing import Any
2
2
  import numpy as np
3
3
 
4
4
  from ..helpers import (
5
- roulette_wheel_indexes,
5
+ roulette_wheel_sampler,
6
6
  parse_obj_doc, # type: ignore
7
7
  )
8
8
  from ..abstract import OptimizationAbstract
@@ -35,7 +35,7 @@ class AntColonyOptimization(OptimizationAbstract):
35
35
  return zeta * np.sum(np.abs(positions - M), axis=0) / (pop_size - 1)
36
36
 
37
37
  def generate_coordinate(j: int) -> float:
38
- rdx, = roulette_wheel_indexes(weights)
38
+ rdx = select_ant()
39
39
  return float(self._population[rdx].position[j] + np.random.normal() * sigmas[rdx, j])
40
40
 
41
41
  # compute the selection probability of each ant in the population
@@ -51,9 +51,12 @@ class AntColonyOptimization(OptimizationAbstract):
51
51
 
52
52
  sigmas = np.array([compute_sigma(ant) for ant in self._population])
53
53
 
54
+ # the weights do not change while generating the new ants: build the roulette wheel once
55
+ select_ant = roulette_wheel_sampler(weights)
56
+
54
57
  # Generate new ants
55
58
  new_ants = [Ant(**self._init_agent(
56
59
  list(map(generate_coordinate, range(0, self._task.space_dimension)))
57
- ).model_dump()) for _ in range(0, self._config.archive_size)]
60
+ ).__dict__) for _ in range(0, self._config.archive_size)]
58
61
 
59
62
  self._extend_and_trim_population(new_ants)
@@ -42,25 +42,25 @@ class AntLionOptimization(OptimizationAbstract):
42
42
  return 1 + 1000000 * (cycle / max_cycles)
43
43
  return 1
44
44
 
45
- def random_walk_ant_lion(ant_lion_position: np.ndarray) -> np.ndarray:
46
- X = np.array([np.cumsum(2 * (np.random.random(pop_size) > 0.5) - 1) for _ in range(0, n_dims)])
45
+ def random_walk_ant_lion(ant_lion_position: np.ndarray, idx: int) -> np.ndarray:
46
+ # one row of random steps per dimension (drawn at once, in the same order as row by row)
47
+ X = np.cumsum(2 * (np.random.random((n_dims, pop_size)) > 0.5) - 1, axis=1)
47
48
  # Move the interval of [lb ub] around the ant lion [lb + ant_lion, ub + ant_lion]. Eq 2.8, 2.9
48
49
  lb = lower_bounds * (1 if np.random.random() < 0.5 else -1) + ant_lion_position
49
50
  ub = upper_bounds * (1 if np.random.random() < 0.5 else -1) + ant_lion_position
50
51
  a = np.min(X, axis=1)
51
52
  b = np.max(X, axis=1)
52
- return (X - np.reshape(a, (n_dims, 1))) * (
53
- np.reshape((ub - lb) / (b - a), (n_dims, 1))
54
- ) + np.reshape(lb, (n_dims, 1))
53
+ # only the idx-th step of the walk is used: normalize just that column
54
+ return (X[:, idx] - a) * ((ub - lb) / (b - a)) + lb
55
55
 
56
56
  def new_agent(idx: int) -> AntLion:
57
57
  roulette_index, = roulette_wheel_indexes(weights)
58
58
  # RA is the random walk around the selected ant lion by roulette wheel
59
- RA = random_walk_ant_lion(np.array(self._population[roulette_index].position))
59
+ RA = random_walk_ant_lion(np.array(self._population[roulette_index].position), idx)
60
60
  # RE is the random walk around the elite (the best ant lion so far)
61
- RE = random_walk_ant_lion(g_best_pos)
62
- pos_new = (RA[:, idx] + RE[:, idx]) / 2 # Equation(2.13) in the paper
63
- return AntLion(**self._init_agent(pos_new).model_dump())
61
+ RE = random_walk_ant_lion(g_best_pos, idx)
62
+ pos_new = (RA + RE) / 2 # Equation(2.13) in the paper
63
+ return AntLion(**self._init_agent(pos_new).__dict__)
64
64
 
65
65
  cycle = self._current_cycle
66
66
  max_cycles = self._config.max_cycles
@@ -45,7 +45,7 @@ class AquilaOptimization(OptimizationAbstract):
45
45
  ) if np.random.random() < 0.5 else QF * best_position - (
46
46
  g2 * pos * np.random.random()
47
47
  ) - g2 * levy_step + np.random.random() * g1 # Eq. 13, 14
48
- new_agent = Aquila(**self._init_agent(pos_new).model_dump())
48
+ new_agent = Aquila(**self._init_agent(pos_new).__dict__)
49
49
  return self._greedy_select_agent(new_agent, aquila)
50
50
 
51
51
  current_cycle = self._current_cycle
@@ -44,7 +44,7 @@ class ArchimedeOptimization(OptimizationAbstract):
44
44
  acceleration = self._task.empty_solution() if acceleration is None else (
45
45
  acceleration.tolist() if isinstance(acceleration, np.ndarray) else acceleration
46
46
  )
47
- return Object(**agent.model_dump(), density=density, volume=volume, acceleration=acceleration)
47
+ return Object(**agent.__dict__, density=density, volume=volume, acceleration=acceleration)
48
48
 
49
49
  def optimization_step(self):
50
50
  def calculate_new_properties(idx: int, obj: Object) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
@@ -36,19 +36,21 @@ class BacterialForagingOptimization(OptimizationAbstract):
36
36
 
37
37
  def _init_agent(self, position: list[Any] | np.ndarray | None = None) -> Cell:
38
38
  agent = super()._init_agent(position)
39
- return Cell(**agent.model_dump(), local_best=agent.position.copy(), local_cost=agent.cost)
39
+ return Cell(**agent.__dict__, local_best=agent.position.copy(), local_cost=agent.cost)
40
40
 
41
41
  def __clean_population__(self):
42
42
  """
43
43
  Remove duplicates from the population. This method is called after each optimization step.
44
44
  """
45
- new_set = set()
46
- pop = self._population.copy()
47
- for idx, obj in enumerate(pop):
48
- if pos := tuple(obj.position) in new_set:
49
- self._population.pop(idx)
50
- else:
51
- new_set.add(pos)
45
+ # keep the first cell of each position
46
+ seen = set()
47
+ unique = []
48
+ for cell in self._population:
49
+ position = tuple(cell.position)
50
+ if position not in seen:
51
+ seen.add(position)
52
+ unique.append(cell)
53
+ self._population = unique
52
54
 
53
55
  def __balance_population__(self):
54
56
  """
@@ -63,13 +65,15 @@ class BacterialForagingOptimization(OptimizationAbstract):
63
65
  if n_agents < 0:
64
66
  self._population += [self._init_agent() for _ in range(0, -n_agents)]
65
67
  else:
66
- list_idx_removed = np.random.choice(range(0, len(self._population)), n_agents, replace=False)
68
+ list_idx_removed = np.random.choice(len(self._population), n_agents, replace=False)
67
69
  for idx in sorted(list_idx_removed, reverse=True):
68
70
  self._population.pop(idx)
69
71
 
70
72
  def optimization_step(self):
71
73
  def update_step_size(c: Cell) -> float:
72
- step_sz = C_s - (C_s - C_e) * c.cost / total_costs
74
+ # the step size decreases with the share of the cost of the cell (all the costs may be zero)
75
+ share = c.cost / total_costs if total_costs != 0 else 0
76
+ step_sz = C_s - (C_s - C_e) * share
73
77
  return step_sz / c.nutrients if c.nutrients > 0 else step_sz
74
78
 
75
79
  def tumble_cell(c: Cell, step_sz: float) -> Cell:
@@ -89,11 +93,11 @@ class BacterialForagingOptimization(OptimizationAbstract):
89
93
  c.nutrients -= 1
90
94
  continue
91
95
  new_cell.nutrients += 1
96
+ # the personal best is the best position found by the cell so far
97
+ if c.local_cost < new_cell.cost:
98
+ new_cell.local_best = list(c.local_best)
99
+ new_cell.local_cost = c.local_cost
92
100
  c = new_cell
93
- # update personal best
94
- if new_cell.cost < c.local_cost:
95
- c.local_best = new_cell.position.copy()
96
- c.local_cost = new_cell.cost
97
101
  return c
98
102
 
99
103
  C_s, C_e = self.__C_s, self.__C_e
@@ -107,6 +111,7 @@ class BacterialForagingOptimization(OptimizationAbstract):
107
111
 
108
112
  step_size = update_step_size(cell)
109
113
  cell = swim(cell, step_size)
114
+ self._population[idx] = cell
110
115
 
111
116
  m = max(self._config.N_split, self._config.N_split + (
112
117
  len(self._population) - self._config.population_size
@@ -124,7 +129,8 @@ class BacterialForagingOptimization(OptimizationAbstract):
124
129
  len(self._population) - self._config.population_size
125
130
  ) / self._config.N_adapt)
126
131
 
127
- if cell.nutrients < nut_min and np.random.random() < self._config.Ped:
132
+ # eliminate the cell if it is starving, or with probability Ped (elimination-dispersal)
133
+ if cell.nutrients < nut_min or np.random.random() < self._config.Ped:
128
134
  self._population[idx] = self._init_agent()
129
135
 
130
136
  # make sure the population does not have duplicates
@@ -37,7 +37,7 @@ class BatOptimization(OptimizationAbstract):
37
37
  velocity = self._task.correct_solution(velocity if velocity is not None else self._task.empty_solution())
38
38
 
39
39
  return Bat(
40
- **agent.model_dump(),
40
+ **agent.__dict__,
41
41
  velocity=velocity,
42
42
  loudness=loudness if loudness is not None else np.random.uniform(*self._config.loudness),
43
43
  pulse_rate=pulse_rate if pulse_rate is not None else np.random.uniform(*self._config.pulse_rate),
@@ -31,7 +31,7 @@ class BattleRoyaleOptimization(OptimizationAbstract):
31
31
 
32
32
  def _init_agent(self, position: list[Any] | np.ndarray | None = None, damage: int | None = None) -> Soldier:
33
33
  agent = super()._init_agent(position=position)
34
- soldier = Soldier(**agent.model_dump())
34
+ soldier = Soldier(**agent.__dict__)
35
35
  if damage is not None:
36
36
  soldier.damage = damage
37
37
  return soldier
@@ -2,6 +2,7 @@ from typing import Any
2
2
  import numpy as np
3
3
 
4
4
  from ..helpers import (
5
+ normalize_costs,
5
6
  get_partner_index,
6
7
  roulette_wheel_indexes,
7
8
  parse_obj_doc, # type: ignore
@@ -33,12 +34,14 @@ class BeeColonyOptimization(OptimizationAbstract):
33
34
  def set_config_parameters(self, parameters: dict[str, Any]):
34
35
  self._config = BeeColonyOptimizationConfig(**parameters)
35
36
 
36
- def before_initialization(self):
37
- self._config.population_size = int(self._config.population_size / 2)
37
+ def _init_population(self):
38
+ # half of the colony are employed bees, each one bound to a food source: the population is made of the food
39
+ # sources (the configuration is not altered, so that it can be reused for further optimizations)
40
+ self._population = self._generate_agents(int(self._config.population_size / 2))
38
41
 
39
42
  def _init_agent(self, position: list[float] | np.ndarray | None = None) -> Bee:
40
43
  agent = super()._init_agent(position)
41
- return Bee(**agent.model_dump())
44
+ return Bee(**agent.__dict__)
42
45
 
43
46
  def _greedy_select_agent(self, agent: Bee, new_agent: Bee) -> Bee:
44
47
  """
@@ -77,7 +80,7 @@ class BeeColonyOptimization(OptimizationAbstract):
77
80
  selected_bee = self._population[jdx]
78
81
  return food_source_dance(idx, selected_bee)
79
82
 
80
- population_size = self._config.population_size
83
+ population_size = len(self._population)
81
84
  dims = self._task.space_dimension
82
85
  phi = np.random.uniform(low=-1, high=1, size=dims)
83
86
 
@@ -87,7 +90,7 @@ class BeeColonyOptimization(OptimizationAbstract):
87
90
  # based to probability, generate a neighbour point and evaluate again some food sources
88
91
  # same food source can be evaluated multiple times
89
92
  employed_costs = np.array([agent.cost for agent in self._population])
90
- probabilities = employed_costs / np.sum(employed_costs)
93
+ probabilities = normalize_costs(employed_costs)
91
94
  self._population = [send_onlooker_bees(idx) for idx in range(0, population_size)]
92
95
 
93
96
  # abandon the food sources which have not been improved after a predefined number of trials; it means to send
@@ -2,6 +2,7 @@ from typing import Any
2
2
  import numpy as np
3
3
 
4
4
  from ..helpers import (
5
+ normalize_costs,
5
6
  best_agents,
6
7
  roulette_wheel_indexes,
7
8
  parse_obj_doc, # type: ignore
@@ -45,7 +46,7 @@ class BiogeographyBasedOptimization(OptimizationAbstract):
45
46
  pos_new = np.where(condition, self._population[idx_selected].position, population.position)
46
47
  # Mutation
47
48
  pos_new = np.where(np.random.random(n_dims) < p_m, self._task.empty_solution(), pos_new)
48
- agent_new = Population(**self._init_agent(pos_new).model_dump())
49
+ agent_new = Population(**self._init_agent(pos_new).__dict__)
49
50
  return self._greedy_select_agent(population, agent_new)
50
51
 
51
52
  n_dims = self._task.space_dimension
@@ -55,8 +56,7 @@ class BiogeographyBasedOptimization(OptimizationAbstract):
55
56
  pop_elites = best_agents(self._population, n_best=self._config.n_elites)
56
57
 
57
58
  # pick a position from which to emigrate (roulette wheel selection)
58
- costs = np.array([agent.cost for agent in self._population])
59
- costs /= np.sum(costs)
59
+ costs = normalize_costs(np.array([agent.cost for agent in self._population]))
60
60
 
61
61
  self._population = [evolve(idx, agent) for idx, agent in enumerate(self._population)]
62
62
 
@@ -50,7 +50,7 @@ class BrainStormOptimization(OptimizationAbstract):
50
50
  cluster_id = np.random.randint(0, m_clusters)
51
51
  pos_new = np.array(self.__centers[cluster_id].position) + epsilon * np.random.normal(0, 1, n_dims)
52
52
  else:
53
- id1, id2 = np.random.choice(range(0, m_clusters), 2, replace=False)
53
+ id1, id2 = np.random.choice(m_clusters, 2, replace=False)
54
54
  pos_new = 0.5 * (
55
55
  np.array(self.__centers[id1].position) + np.array(self.__centers[id2].position)
56
56
  ) + epsilon * np.random.normal(0, 1, n_dims)
@@ -58,7 +58,7 @@ class BrainStormOptimization(OptimizationAbstract):
58
58
  pos_rand_id1 = np.array(self.__clusters[id1][np.random.randint(0, m_solution)].position)
59
59
  pos_rand_id2 = np.array(self.__clusters[id2][np.random.randint(0, m_solution)].position)
60
60
  pos_new = 0.5 * (pos_rand_id1 + pos_rand_id2) + epsilon * np.random.normal(0, 1, n_dims)
61
- agent = Person(**self._init_agent(pos_new).model_dump())
61
+ agent = Person(**self._init_agent(pos_new).__dict__)
62
62
  return agent, cluster_id, location_id
63
63
 
64
64
  epoch = self._current_cycle
@@ -75,7 +75,7 @@ class BrainStormOptimization(OptimizationAbstract):
75
75
 
76
76
  epsilon = 1. - 1. * epoch / epochs
77
77
  if np.random.uniform() < p1:
78
- self.__centers[np.random.randint(0, m_clusters)] = Person(**self._init_agent().model_dump())
78
+ self.__centers[np.random.randint(0, m_clusters)] = Person(**self._init_agent().__dict__)
79
79
 
80
80
  new_agents, cluster_ids, location_ids = zip(*[evolve(idx) for idx in range(0, self._config.population_size)])
81
81
  for cl_id, loc_id, new_agent in zip(cluster_ids, location_ids, new_agents):
@@ -52,7 +52,7 @@ class ImprovedBrainStormOptimization(OptimizationAbstract):
52
52
  temp_pos = np.array(self.__clusters[cluster_id][location_id].position)
53
53
  pos_new = temp_pos + offset
54
54
  else:
55
- id1, id2 = np.random.choice(range(0, m_clusters), 2, replace=False)
55
+ id1, id2 = np.random.choice(m_clusters, 2, replace=False)
56
56
  pos_new = 0.5 * (
57
57
  np.array(self.__centers[id1].position) + np.array(self.__centers[id2].position)
58
58
  ) + epsilon * np.random.normal(0, 1, n_dims)
@@ -60,7 +60,7 @@ class ImprovedBrainStormOptimization(OptimizationAbstract):
60
60
  pos_rand_id1 = np.array(self.__clusters[id1][np.random.randint(0, m_solution)].position)
61
61
  pos_rand_id2 = np.array(self.__clusters[id2][np.random.randint(0, m_solution)].position)
62
62
  pos_new = 0.5 * (pos_rand_id1 + pos_rand_id2) + epsilon * np.random.normal(0, 1, n_dims)
63
- agent = Person(**self._init_agent(pos_new).model_dump())
63
+ agent = Person(**self._init_agent(pos_new).__dict__)
64
64
  return agent, cluster_id, location_id
65
65
 
66
66
  p1, p2, p3, p4 = self._config.p1, self._config.p2, self._config.p3, self._config.p4
@@ -73,7 +73,7 @@ class ImprovedBrainStormOptimization(OptimizationAbstract):
73
73
 
74
74
  epsilon = 1. - 1. * epoch / epochs
75
75
  if np.random.uniform() < p1:
76
- self.__centers[np.random.randint(0, m_clusters)] = Person(**self._init_agent().model_dump())
76
+ self.__centers[np.random.randint(0, m_clusters)] = Person(**self._init_agent().__dict__)
77
77
 
78
78
  new_agents, cluster_ids, location_ids = zip(*[evolve(idx) for idx in range(0, self._config.population_size)])
79
79
  for cl_id, loc_id, new_agent in zip(cluster_ids, location_ids, new_agents):
@@ -37,7 +37,7 @@ class BrownBearOptimization(OptimizationAbstract):
37
37
  else:
38
38
  ww = 2 * pp * np.pi * np.random.random(n_dims)
39
39
  pos_new = pos + (ww * best_position - np.abs(pos)) - (ww * worst_position - np.abs(pos))
40
- return self._greedy_select_agent(bear, BrownBear(**self._init_agent(pos_new).model_dump()))
40
+ return self._greedy_select_agent(bear, BrownBear(**self._init_agent(pos_new).__dict__))
41
41
 
42
42
  def sniffing_bear(idx: int, bear: BrownBear) -> BrownBear:
43
43
  pos = np.array(bear.position)
@@ -45,7 +45,7 @@ class BrownBearOptimization(OptimizationAbstract):
45
45
  agent = self._population[kk]
46
46
  agent_pos = np.array(agent.position)
47
47
  pos_new = pos + np.random.random() * (pos - agent_pos) * (1 if bear.cost < agent.cost else -1)
48
- return self._greedy_select_agent(bear, BrownBear(**self._init_agent(pos_new).model_dump()))
48
+ return self._greedy_select_agent(bear, BrownBear(**self._init_agent(pos_new).__dict__))
49
49
 
50
50
  cycles = self._current_cycle
51
51
  pp = cycles / self._config.max_cycles
@@ -37,7 +37,7 @@ class CamelCaravanOptimization(OptimizationAbstract):
37
37
  agent = super()._init_agent(position=position)
38
38
 
39
39
  return Camel(
40
- **agent.model_dump(),
40
+ **agent.__dict__,
41
41
  endurance=endurance if endurance is not None else self._config.endurance,
42
42
  supply=supply if supply is not None else self._config.supply,
43
43
  temperature=np.random.uniform(*self._config.temperatures),
@@ -39,15 +39,15 @@ class CatSwarmOptimization(OptimizationAbstract):
39
39
 
40
40
  flag = np.random.uniform() < self._config.mixture_ratio if flag is None else flag
41
41
  if velocity is None:
42
- return Cat(**agent.model_dump(), velocity=self._task.empty_solution(), flag=flag)
42
+ return Cat(**agent.__dict__, velocity=self._task.empty_solution(), flag=flag)
43
43
 
44
44
  velocity = self._task.correct_solution(velocity.tolist() if isinstance(velocity, np.ndarray) else velocity)
45
- return Cat(**agent.model_dump(), velocity=velocity, flag=flag)
45
+ return Cat(**agent.__dict__, velocity=velocity, flag=flag)
46
46
 
47
47
  def optimization_step(self):
48
48
  def seeking_clone(c: Cat) -> Cat:
49
49
  pos = np.array(c.position)
50
- jdx = np.random.choice(range(0, n_dims), int(cdc * n_dims), replace=False)
50
+ jdx = np.random.choice(n_dims, int(cdc * n_dims), replace=False)
51
51
  pos_new = np.where(np.random.random(n_dims) < 0.5, pos * (1 + srd), pos * (1 - srd))
52
52
  pos_new[jdx] = pos[jdx]
53
53
  return self._init_agent(pos_new, c.velocity, c.flag)
@@ -55,12 +55,12 @@ class CatSwarmOptimization(OptimizationAbstract):
55
55
  def seeking_mode(cat: Cat) -> list[float]:
56
56
  cloned = [cat.model_copy() for _ in range(smp - 1)] if spc else self._generate_agents(self._config.smp)
57
57
  candidates = [cat.model_copy()] if self._config.spc else []
58
- candidates += [seeking_clone(Cat(**cat.model_dump())) for cat in cloned]
58
+ candidates += [seeking_clone(Cat(**cat.__dict__)) for cat in cloned]
59
59
  if selected_strategy == 0: # best fitness-self
60
60
  return best_agent(candidates).position
61
61
  if selected_strategy == 1: # tournament
62
62
  k_way = 4
63
- idx = np.random.choice(range(0, self._config.smp), k_way, replace=False)
63
+ idx = np.random.choice(self._config.smp, k_way, replace=False)
64
64
  cats_k_way = [candidates[_] for _ in idx]
65
65
  return best_agent(cats_k_way).position
66
66
  if selected_strategy == 2: # roulette wheel selection
@@ -50,14 +50,14 @@ class ChaosGameOptimization(OptimizationAbstract):
50
50
  selected_alpha = alpha[np.random.randint(0, 4, size=3), :]
51
51
  new_seed_1 = Seed(**self._init_agent(
52
52
  pos + selected_alpha[0] * (I[0] * g_best_pos - I[1] * mean_group_pos)
53
- ).model_dump())
53
+ ).__dict__)
54
54
  new_seed_2 = Seed(**self._init_agent(
55
55
  g_best_pos + selected_alpha[1] * (I[2] * mean_group_pos - I[3] * pos)
56
- ).model_dump())
56
+ ).__dict__)
57
57
  new_seed_3 = Seed(**self._init_agent(
58
58
  mean_group_pos + selected_alpha[2] * (I[4] * g_best_pos - I[5] * pos)
59
- ).model_dump())
60
- new_seed_4 = Seed(**self._init_agent().model_dump())
59
+ ).__dict__)
60
+ new_seed_4 = Seed(**self._init_agent().__dict__)
61
61
  return [new_seed_1, new_seed_2, new_seed_3, new_seed_4]
62
62
 
63
63
  n_dims = self._task.space_dimension
@@ -35,7 +35,7 @@ class ChernobylDisasterOptimization(OptimizationAbstract):
35
35
  pos_b = 0.5 * (b2_pos - pb * np.abs(np.random.random() ** 2 * np.pi * b2_pos - pos))
36
36
  pos_c = b3_pos - pc * np.abs(np.random.random() ** 2 * np.pi * b3_pos - pos)
37
37
  pos_new = (pos_a + pos_b + pos_c) / 3
38
- return SearchRadiation(**self._init_agent(pos_new).model_dump())
38
+ return SearchRadiation(**self._init_agent(pos_new).__dict__)
39
39
 
40
40
  a = 3. - 3. * self._current_cycle / self._config.max_cycles
41
41