pyVolutionary 2.6.6__tar.gz → 2.7.1__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.
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/PKG-INFO +4 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/README.md +3 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyproject.toml +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/abstract.py +72 -23
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/african_vulture/african_vulture_optimization.py +7 -3
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/ant_colony/ant_colony_optimization.py +6 -3
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/ant_lion/ant_lion_optimization.py +9 -9
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/aquila/aquila_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/archimede/archimede_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/bacterial_foraging/bacterial_foraging_optimization.py +21 -15
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/bat/bat_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/battle_royale/battle_royale_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/bee_colony/bee_colony_optimization.py +12 -5
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/biogeography_based/biogeography_based_optimization.py +3 -3
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/brain_storm/brain_storm_optimization.py +19 -18
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/brain_storm/improved_brain_storm_optimization.py +15 -15
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/brown_bear/brown_bear_optimization.py +2 -2
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/camel_caravan/camel_caravan_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/cat_swarm/cat_swarm_optimization.py +5 -5
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/chaos_game/chaos_game_optimization.py +4 -4
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/chernobyl_disaster/chernobyl_disaster_optimization.py +5 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/coati/coati_optimization.py +4 -4
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/coral_reef/coral_reef_optimization.py +10 -4
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/coronavirus_herd_immunity/coronavirus_herd_immunity_optimization.py +9 -9
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/coyotes/coyotes_optimization.py +5 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/cuckoo_search/cuckoo_search_optimization.py +3 -2
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/dragonfly/dragonfly_optimization.py +10 -15
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/dwarf_mongoose/dwarf_mongoose_optimization.py +5 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/earthworms/earthworms_optimization.py +36 -13
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/egret_swarm/egret_swarm_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/electromagnetic_field/electromagnetic_field_optimization.py +16 -5
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/elephant_herd/elephant_herd_optimization.py +9 -11
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/energy_valley/energy_valley_optimization.py +9 -5
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/ficks_law/ficks_law_optimization.py +10 -6
- pyvolutionary-2.7.1/pyvolutionary/firefly_swarm/firefly_swarm_optimization.py +106 -0
- pyvolutionary-2.7.1/pyvolutionary/firefly_swarm/models.py +61 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/firehawk/firehawk_optimization.py +4 -3
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/fireworks/fireworks_optimization.py +13 -9
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/fish_school_search/fish_school_search_optimization.py +29 -23
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/flower_pollination_algorithm/flower_pollination_algorithm_optimization.py +5 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/forensic_based_investigation/forensic_based_investigation_optimization.py +8 -4
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/forest_algorithm/forest_optimization_algorithm.py +6 -6
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/fox/fox_optimization.py +6 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/gaining_sharing_knowledge_algorithm/gaining_sharing_knowledge_optimization.py +21 -7
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/genetic_algorithm/classes.py +6 -5
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/genetic_algorithm/genetic_algorithm_optimization.py +9 -6
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/germinal_center/germinal_center_optimization.py +10 -5
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/giant_trevally/giant_trevally_optimization.py +3 -3
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/giza_pyramid_construction/giza_pyramid_construction_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/golden_jackal/golden_jackal_optimization.py +3 -3
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/grasshopper/grasshopper_optimization_algorithm.py +9 -7
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/grey_wolf/grey_wolf_optimization.py +5 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/harmony_search/harmony_search_optimization.py +3 -2
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/helpers.py +104 -24
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/henry_gas_solubility/henry_gas_solubility_optimization.py +2 -2
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/hunger_games_search/hunger_games_search_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/hypertuner.py +26 -13
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/imperialist_competitive/classes.py +3 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/imperialist_competitive/imperialist_competitive_optimization.py +41 -24
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/invasive_weed/invasive_weed_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/krill_herd/krill_herd_optimization.py +35 -23
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/levi_jaya_swarm/levy_flight_jaya_swarm_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/marine_predators/marine_predators_optimization.py +2 -2
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/models.py +155 -36
- pyvolutionary-2.7.1/pyvolutionary/monarch_butterfly/monarch_butterfly_optimization.py +83 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/moth_flame/moth_flame_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/mountain_gazelle/mountain_gazelle_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/multi_verse/multi_verse_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/multitask.py +23 -15
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/nuclear_reaction/nuclear_reaction_optimization.py +7 -3
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/osprey/osprey_optimization.py +2 -2
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/particle_swarm/particle_swarm_optimization.py +3 -4
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/pathfinder_algorithm/pathfinder_algorithm_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/pelican/pelican_optimization.py +2 -2
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/runge_kutta/runge_kutta_optimization.py +5 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/salp_swarm/salp_swarm_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/seagull/seagull_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/serval/serval_optimization.py +2 -2
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/siberian_tiger/siberian_tiger_optimization.py +2 -2
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/sine_cosine_algorithm/qle_sine_cosine_algorithm_optimization.py +2 -2
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/sine_cosine_algorithm/sine_cosine_algorithm_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/spotted_hyena/spotted_hyena_optimization.py +6 -5
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/success_history_intelligent/success_history_intelligent_optimization.py +9 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/swarm_hill_climbing/swarm_hill_climbing_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/tasmanian_devil/tasmanian_devil_optimization.py +2 -2
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/tuna_swarm/tuna_swarm_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/virus_colony_search/virus_colony_search_optimization.py +7 -3
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/walrus/walrus_optimization.py +2 -2
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/war_strategy/war_strategy_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/water_cycle/water_cycle_optimization.py +21 -5
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/whales/whales_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/wildebeest_herd/wildebeest_herd_optimization.py +6 -6
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/wind_driven/wind_driven_optimization.py +1 -1
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/zebra/zebra_optimization.py +2 -2
- pyvolutionary-2.6.6/pyvolutionary/firefly_swarm/firefly_swarm_optimization.py +0 -76
- pyvolutionary-2.6.6/pyvolutionary/firefly_swarm/models.py +0 -37
- pyvolutionary-2.6.6/pyvolutionary/monarch_butterfly/monarch_butterfly_optimization.py +0 -74
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/LICENSE +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/african_vulture/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/african_vulture/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/ant_colony/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/ant_colony/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/ant_lion/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/ant_lion/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/aquila/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/aquila/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/archimede/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/archimede/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/bacterial_foraging/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/bacterial_foraging/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/bat/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/bat/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/battle_royale/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/battle_royale/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/bee_colony/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/bee_colony/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/biogeography_based/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/biogeography_based/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/brain_storm/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/brain_storm/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/brown_bear/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/brown_bear/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/camel_caravan/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/camel_caravan/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/cat_swarm/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/cat_swarm/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/chaos_game/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/chaos_game/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/chernobyl_disaster/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/chernobyl_disaster/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/coati/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/coati/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/coral_reef/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/coral_reef/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/coronavirus_herd_immunity/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/coronavirus_herd_immunity/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/coyotes/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/coyotes/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/cuckoo_search/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/cuckoo_search/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/dragonfly/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/dragonfly/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/dwarf_mongoose/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/dwarf_mongoose/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/earthworms/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/earthworms/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/egret_swarm/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/egret_swarm/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/electromagnetic_field/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/electromagnetic_field/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/elephant_herd/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/elephant_herd/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/energy_valley/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/energy_valley/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/enums.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/ficks_law/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/ficks_law/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/firefly_swarm/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/firehawk/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/firehawk/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/fireworks/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/fireworks/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/fish_school_search/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/fish_school_search/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/flower_pollination_algorithm/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/flower_pollination_algorithm/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/forensic_based_investigation/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/forensic_based_investigation/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/forest_algorithm/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/forest_algorithm/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/fox/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/fox/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/gaining_sharing_knowledge_algorithm/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/gaining_sharing_knowledge_algorithm/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/genetic_algorithm/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/genetic_algorithm/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/germinal_center/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/germinal_center/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/giant_trevally/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/giant_trevally/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/giza_pyramid_construction/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/giza_pyramid_construction/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/golden_jackal/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/golden_jackal/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/grasshopper/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/grasshopper/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/grey_wolf/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/grey_wolf/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/harmony_search/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/harmony_search/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/heap_based/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/heap_based/heap_based_optimization.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/heap_based/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/henry_gas_solubility/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/henry_gas_solubility/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/hunger_games_search/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/hunger_games_search/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/imperialist_competitive/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/imperialist_competitive/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/invasive_weed/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/invasive_weed/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/krill_herd/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/krill_herd/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/levi_jaya_swarm/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/levi_jaya_swarm/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/marine_predators/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/marine_predators/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/monarch_butterfly/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/monarch_butterfly/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/moth_flame/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/moth_flame/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/mountain_gazelle/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/mountain_gazelle/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/multi_verse/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/multi_verse/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/nuclear_reaction/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/nuclear_reaction/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/osprey/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/osprey/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/particle_swarm/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/particle_swarm/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/pathfinder_algorithm/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/pathfinder_algorithm/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/pelican/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/pelican/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/runge_kutta/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/runge_kutta/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/salp_swarm/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/salp_swarm/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/seagull/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/seagull/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/serval/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/serval/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/siberian_tiger/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/siberian_tiger/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/sine_cosine_algorithm/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/sine_cosine_algorithm/classes.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/sine_cosine_algorithm/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/spotted_hyena/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/spotted_hyena/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/success_history_intelligent/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/success_history_intelligent/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/swarm_hill_climbing/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/swarm_hill_climbing/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/tasmanian_devil/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/tasmanian_devil/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/tuna_swarm/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/tuna_swarm/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/utils.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/virus_colony_search/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/virus_colony_search/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/walrus/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/walrus/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/war_strategy/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/war_strategy/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/water_cycle/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/water_cycle/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/whales/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/whales/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/wildebeest_herd/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/wildebeest_herd/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/wind_driven/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/wind_driven/models.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/zebra/__init__.py +0 -0
- {pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/zebra/models.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyVolutionary
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.1
|
|
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.
|
|
3
|
+
version = "2.7.1"
|
|
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
|
|
@@ -50,6 +51,15 @@ class OptimizationAbstract(ABC, Generic[T]):
|
|
|
50
51
|
def before_initialization(self):
|
|
51
52
|
pass
|
|
52
53
|
|
|
54
|
+
def _minimum_population_size(self) -> int:
|
|
55
|
+
"""
|
|
56
|
+
The minimum size of the population the algorithm can work with (e.g. an algorithm guided by the three best
|
|
57
|
+
agents needs at least three agents). The algorithms needing more than two agents override it.
|
|
58
|
+
:return: the minimum population size
|
|
59
|
+
:rtype: int
|
|
60
|
+
"""
|
|
61
|
+
return 2
|
|
62
|
+
|
|
53
63
|
def after_initialization(self):
|
|
54
64
|
pass
|
|
55
65
|
|
|
@@ -66,14 +76,24 @@ class OptimizationAbstract(ABC, Generic[T]):
|
|
|
66
76
|
def name(self):
|
|
67
77
|
return self.__class__.__name__
|
|
68
78
|
|
|
69
|
-
def _fcn(self, x: list[float] | np.ndarray) -> float | list[float]:
|
|
79
|
+
def _fcn(self, x: list[float] | np.ndarray, corrected: bool = False) -> float | list[float]:
|
|
70
80
|
"""
|
|
71
81
|
This method evaluates the objective function.
|
|
72
82
|
:param x: the position to evaluate
|
|
83
|
+
:param corrected: whether the position has already been corrected by the task
|
|
73
84
|
:return the cost of the position, or the list of costs if the objective function is multi-objective
|
|
74
85
|
:rtype: float | list[float]
|
|
75
86
|
"""
|
|
76
|
-
|
|
87
|
+
# correcting an already corrected solution is a no-op for the built-in variables: skip it, and pass a copy of
|
|
88
|
+
# the position, so that the objective function can not alter it
|
|
89
|
+
if corrected and self._task.idempotent_correction:
|
|
90
|
+
cost = self._task.objective_function(list(x))
|
|
91
|
+
else:
|
|
92
|
+
cost = self._task.solve(x)
|
|
93
|
+
if self._task.minmax == TaskType.MIN:
|
|
94
|
+
return cost
|
|
95
|
+
# multi-objective functions return a list of costs: negate each of them
|
|
96
|
+
return [-c for c in cost] if isinstance(cost, (list, tuple, np.ndarray)) else -cost
|
|
77
97
|
|
|
78
98
|
def _init_agent(self, position: list[Any] | np.ndarray | None = None) -> Agent:
|
|
79
99
|
"""
|
|
@@ -81,7 +101,7 @@ class OptimizationAbstract(ABC, Generic[T]):
|
|
|
81
101
|
not provided. The other properties of the agent.
|
|
82
102
|
"""
|
|
83
103
|
position = self._task.initial_solution(position)
|
|
84
|
-
cost = self._fcn(position)
|
|
104
|
+
cost = self._fcn(position, corrected=True)
|
|
85
105
|
n_weights = len(self._task.objective_weights) if self._task.objective_weights is not None else 1
|
|
86
106
|
n_objectives = len(cost) if isinstance(cost, list) else 1
|
|
87
107
|
if n_weights != n_objectives:
|
|
@@ -100,10 +120,25 @@ class OptimizationAbstract(ABC, Generic[T]):
|
|
|
100
120
|
|
|
101
121
|
# Parallel mode
|
|
102
122
|
with get_pool_executor(self._mode, self._workers) as executor:
|
|
103
|
-
|
|
123
|
+
if self._mode == ModeSolver.PROCESS:
|
|
124
|
+
# each worker process inherits a copy of the parent's random state: seed each job independently, or
|
|
125
|
+
# different workers would generate identical agents
|
|
126
|
+
seeds = np.random.randint(0, 2**31 - 1, size=n_agents)
|
|
127
|
+
executors = [executor.submit(self._init_agent_with_seed, int(seed)) for seed in seeds]
|
|
128
|
+
else:
|
|
129
|
+
executors = [executor.submit(self._init_agent) for _ in range(0, n_agents)]
|
|
104
130
|
pop = get_pool_results(executors)
|
|
105
131
|
return pop
|
|
106
132
|
|
|
133
|
+
def _init_agent_with_seed(self, seed: int) -> Agent:
|
|
134
|
+
"""
|
|
135
|
+
This method initializes a random agent after seeding the random generators. It is used in process mode.
|
|
136
|
+
:param seed: the seed of the random generators
|
|
137
|
+
"""
|
|
138
|
+
np.random.seed(seed)
|
|
139
|
+
random.seed(seed)
|
|
140
|
+
return self._init_agent()
|
|
141
|
+
|
|
107
142
|
def _init_population(self):
|
|
108
143
|
"""
|
|
109
144
|
This method initializes the population of the optimization algorithm.
|
|
@@ -121,19 +156,11 @@ class OptimizationAbstract(ABC, Generic[T]):
|
|
|
121
156
|
self._population = sort_by_cost(self._population)
|
|
122
157
|
new_population = sort_by_cost(new_population)
|
|
123
158
|
|
|
124
|
-
#
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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)
|
|
159
|
+
# the selection is a mere comparison of costs: dispatching it to a pool of workers would be far more
|
|
160
|
+
# expensive than running it serially
|
|
161
|
+
self._population = [
|
|
162
|
+
self._greedy_select_agent(agent, new_population[idx]) for idx, agent in enumerate(self._population)
|
|
163
|
+
]
|
|
137
164
|
|
|
138
165
|
def _greedy_select_agent(self, agent: T, new_agent: T) -> T:
|
|
139
166
|
"""
|
|
@@ -206,9 +233,24 @@ class OptimizationAbstract(ABC, Generic[T]):
|
|
|
206
233
|
if not self._config:
|
|
207
234
|
raise ValueError("Invalid configuration")
|
|
208
235
|
|
|
236
|
+
minimum_population_size = self._minimum_population_size()
|
|
237
|
+
if self._config.population_size < minimum_population_size:
|
|
238
|
+
raise ValueError(
|
|
239
|
+
f"{self.name} needs a population of at least {minimum_population_size} agents. "
|
|
240
|
+
f"Got {self._config.population_size}"
|
|
241
|
+
)
|
|
242
|
+
|
|
209
243
|
np.random.seed(task.seed)
|
|
244
|
+
random.seed(task.seed)
|
|
210
245
|
evolution: list[Population] = []
|
|
211
246
|
|
|
247
|
+
# reset the state of any previous run, so that the same instance can be used to optimize several times
|
|
248
|
+
self._current_cycle = 1
|
|
249
|
+
self._errors = []
|
|
250
|
+
self._error_diffs = []
|
|
251
|
+
self._best_agent = None
|
|
252
|
+
self._worst_agent = None
|
|
253
|
+
|
|
212
254
|
if workers is not None:
|
|
213
255
|
if workers <= 0:
|
|
214
256
|
raise ValueError("Invalid number of workers. It must be greater than 0")
|
|
@@ -235,6 +277,7 @@ class OptimizationAbstract(ABC, Generic[T]):
|
|
|
235
277
|
self._init_population()
|
|
236
278
|
evolution.append(Population(agents=self._population, task_type=task.minmax))
|
|
237
279
|
(self._best_agent, ), (self._worst_agent, ) = special_agents(self._population, n_best=1, n_worst=1)
|
|
280
|
+
self._best_agent = self._best_agent.model_copy()
|
|
238
281
|
|
|
239
282
|
self.after_initialization()
|
|
240
283
|
|
|
@@ -249,7 +292,11 @@ class OptimizationAbstract(ABC, Generic[T]):
|
|
|
249
292
|
# append the current population to the evolution, being sure that costs and fitness are updated
|
|
250
293
|
evolution.append(Population(agents=self._population, task_type=task.minmax))
|
|
251
294
|
|
|
252
|
-
|
|
295
|
+
# the best agent is the best one found so far (the global best): an algorithm may lose it from the
|
|
296
|
+
# population, but it must neither be lost in the result nor stop guiding the algorithms using it
|
|
297
|
+
(current_best, ), (self._worst_agent, ) = special_agents(self._population, n_best=1, n_worst=1)
|
|
298
|
+
if current_best.cost < self._best_agent.cost:
|
|
299
|
+
self._best_agent = current_best.model_copy()
|
|
253
300
|
|
|
254
301
|
# stop when the error is below the error criteria or when the maximum number of cycles is reached
|
|
255
302
|
error, fitness, has_to_stop = self.__error_check__()
|
|
@@ -280,14 +327,13 @@ class OptimizationAbstract(ABC, Generic[T]):
|
|
|
280
327
|
# Get the optimal population
|
|
281
328
|
avg_fit = average_fitness(self._population)
|
|
282
329
|
current_error = abs(1 - avg_fit)
|
|
283
|
-
|
|
330
|
+
# Append the difference between the current error and the previous one to the list of error differences
|
|
331
|
+
if len(self._errors) > 0:
|
|
332
|
+
self._error_diffs.append(current_error - self._errors[-1])
|
|
284
333
|
|
|
285
334
|
# Append the current error to the list of errors
|
|
286
335
|
self._errors.append(current_error)
|
|
287
336
|
|
|
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
337
|
return current_error, avg_fit, self.__should_stop__(current_error)
|
|
292
338
|
|
|
293
339
|
def __should_stop__(self, current_error: float) -> bool:
|
|
@@ -301,9 +347,12 @@ class OptimizationAbstract(ABC, Generic[T]):
|
|
|
301
347
|
has_to_stop = cycle >= max_cycles
|
|
302
348
|
|
|
303
349
|
# Evaluate the early stopping criteria
|
|
350
|
+
# (stop when the error has not improved, i.e. decreased, by at least min_delta for patience cycles)
|
|
304
351
|
if early_stopping is not None:
|
|
305
352
|
min_delta, patience = early_stopping.min_delta, early_stopping.patience
|
|
306
|
-
has_to_stop |=
|
|
353
|
+
has_to_stop |= len(self._error_diffs) >= patience and all(
|
|
354
|
+
-diff < min_delta for diff in self._error_diffs[-patience:]
|
|
355
|
+
)
|
|
307
356
|
|
|
308
357
|
# Stop when the error is below the error criteria
|
|
309
358
|
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 - (
|
|
39
|
-
B = best_x2 - (
|
|
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).
|
|
73
|
+
vulture, AfricanVulture(**self._init_agent(pos_new).__dict__)
|
|
70
74
|
)
|
|
71
75
|
|
|
72
76
|
cycle_ratio = self._current_cycle / self._config.max_cycles
|
{pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/ant_colony/ant_colony_optimization.py
RENAMED
|
@@ -2,7 +2,7 @@ from typing import Any
|
|
|
2
2
|
import numpy as np
|
|
3
3
|
|
|
4
4
|
from ..helpers import (
|
|
5
|
-
|
|
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
|
|
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
|
-
).
|
|
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
|
-
|
|
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
|
-
|
|
53
|
-
|
|
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
|
|
63
|
-
return AntLion(**self._init_agent(pos_new).
|
|
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).
|
|
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
|
{pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/archimede/archimede_optimization.py
RENAMED
|
@@ -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.
|
|
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.
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
34
|
+
soldier = Soldier(**agent.__dict__)
|
|
35
35
|
if damage is not None:
|
|
36
36
|
soldier.damage = damage
|
|
37
37
|
return soldier
|
{pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/bee_colony/bee_colony_optimization.py
RENAMED
|
@@ -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,18 @@ class BeeColonyOptimization(OptimizationAbstract):
|
|
|
33
34
|
def set_config_parameters(self, parameters: dict[str, Any]):
|
|
34
35
|
self._config = BeeColonyOptimizationConfig(**parameters)
|
|
35
36
|
|
|
36
|
-
def
|
|
37
|
-
|
|
37
|
+
def _minimum_population_size(self) -> int:
|
|
38
|
+
# half of the colony are food sources, and a food source needs a partner
|
|
39
|
+
return 4
|
|
40
|
+
|
|
41
|
+
def _init_population(self):
|
|
42
|
+
# half of the colony are employed bees, each one bound to a food source: the population is made of the food
|
|
43
|
+
# sources (the configuration is not altered, so that it can be reused for further optimizations)
|
|
44
|
+
self._population = self._generate_agents(int(self._config.population_size / 2))
|
|
38
45
|
|
|
39
46
|
def _init_agent(self, position: list[float] | np.ndarray | None = None) -> Bee:
|
|
40
47
|
agent = super()._init_agent(position)
|
|
41
|
-
return Bee(**agent.
|
|
48
|
+
return Bee(**agent.__dict__)
|
|
42
49
|
|
|
43
50
|
def _greedy_select_agent(self, agent: Bee, new_agent: Bee) -> Bee:
|
|
44
51
|
"""
|
|
@@ -77,7 +84,7 @@ class BeeColonyOptimization(OptimizationAbstract):
|
|
|
77
84
|
selected_bee = self._population[jdx]
|
|
78
85
|
return food_source_dance(idx, selected_bee)
|
|
79
86
|
|
|
80
|
-
population_size = self.
|
|
87
|
+
population_size = len(self._population)
|
|
81
88
|
dims = self._task.space_dimension
|
|
82
89
|
phi = np.random.uniform(low=-1, high=1, size=dims)
|
|
83
90
|
|
|
@@ -87,7 +94,7 @@ class BeeColonyOptimization(OptimizationAbstract):
|
|
|
87
94
|
# based to probability, generate a neighbour point and evaluate again some food sources
|
|
88
95
|
# same food source can be evaluated multiple times
|
|
89
96
|
employed_costs = np.array([agent.cost for agent in self._population])
|
|
90
|
-
probabilities =
|
|
97
|
+
probabilities = normalize_costs(employed_costs)
|
|
91
98
|
self._population = [send_onlooker_bees(idx) for idx in range(0, population_size)]
|
|
92
99
|
|
|
93
100
|
# 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).
|
|
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
|
|
{pyvolutionary-2.6.6 → pyvolutionary-2.7.1}/pyvolutionary/brain_storm/brain_storm_optimization.py
RENAMED
|
@@ -4,6 +4,7 @@ import numpy as np
|
|
|
4
4
|
|
|
5
5
|
from ..helpers import (
|
|
6
6
|
find_centers,
|
|
7
|
+
split_in_clusters,
|
|
7
8
|
parse_obj_doc, # type: ignore
|
|
8
9
|
)
|
|
9
10
|
from ..abstract import OptimizationAbstract
|
|
@@ -25,40 +26,39 @@ class BrainStormOptimization(OptimizationAbstract):
|
|
|
25
26
|
"""
|
|
26
27
|
def __init__(self, config: BrainStormOptimizationConfig | None = None, debug: bool | None = False):
|
|
27
28
|
super().__init__(config, debug)
|
|
28
|
-
self.__m_solution: int | None = None
|
|
29
29
|
self.__clusters: list[list[Person]] = []
|
|
30
30
|
self.__centers: list[Person] = []
|
|
31
31
|
|
|
32
32
|
def set_config_parameters(self, parameters: dict[str, Any]):
|
|
33
33
|
self._config = BrainStormOptimizationConfig(**parameters)
|
|
34
34
|
|
|
35
|
-
def before_initialization(self):
|
|
36
|
-
self.__m_solution = int(self._config.population_size / self._config.m_clusters)
|
|
37
|
-
|
|
38
35
|
def after_initialization(self):
|
|
39
|
-
|
|
36
|
+
# every agent belongs to a cluster, also when the population size is not a multiple of m_clusters
|
|
37
|
+
self.__clusters = split_in_clusters(self._population, self._config.m_clusters)
|
|
40
38
|
self.__centers: list[Person] = find_centers(self.__clusters)
|
|
41
39
|
|
|
42
40
|
def optimization_step(self):
|
|
43
41
|
def evolve(idx: int) -> tuple[Person, int, int]:
|
|
44
|
-
cluster_id =
|
|
45
|
-
location_id = int(idx % m_solution)
|
|
42
|
+
cluster_id, location_id = locations[idx]
|
|
46
43
|
if np.random.uniform() < p2: # p_6b
|
|
47
|
-
rand_idx = np.random.randint(0,
|
|
44
|
+
rand_idx = np.random.randint(0, len(self.__clusters[cluster_id]))
|
|
48
45
|
pos_new = np.array(self.__clusters[cluster_id][rand_idx].position) + np.random.normal(0, 1, n_dims)
|
|
49
46
|
if np.random.uniform() < p3: # p_6i
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
# the new idea comes from the center of a random cluster, and competes with the agent idx
|
|
48
|
+
center_id = np.random.randint(0, m_clusters)
|
|
49
|
+
pos_new = np.array(self.__centers[center_id].position) + epsilon * np.random.normal(0, 1, n_dims)
|
|
52
50
|
else:
|
|
53
|
-
id1, id2 = np.random.choice(
|
|
51
|
+
id1, id2 = np.random.choice(m_clusters, 2, replace=False)
|
|
54
52
|
pos_new = 0.5 * (
|
|
55
53
|
np.array(self.__centers[id1].position) + np.array(self.__centers[id2].position)
|
|
56
54
|
) + epsilon * np.random.normal(0, 1, n_dims)
|
|
57
55
|
if np.random.uniform() >= p4:
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
cluster1 = self.__clusters[id1]
|
|
57
|
+
pos_rand_id1 = np.array(cluster1[np.random.randint(0, len(cluster1))].position)
|
|
58
|
+
cluster2 = self.__clusters[id2]
|
|
59
|
+
pos_rand_id2 = np.array(cluster2[np.random.randint(0, len(cluster2))].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).
|
|
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
|
|
@@ -68,16 +68,17 @@ class BrainStormOptimization(OptimizationAbstract):
|
|
|
68
68
|
epsilon = np.random.uniform() * (1 / (1 + np.exp(-x)))
|
|
69
69
|
|
|
70
70
|
p1, p2, p3, p4 = self._config.p1, self._config.p2, self._config.p3, self._config.p4
|
|
71
|
-
|
|
71
|
+
# the (cluster, location) of each agent, cluster by cluster
|
|
72
|
+
locations = [(c_id, l_id) for c_id, cluster in enumerate(self.__clusters) for l_id in range(0, len(cluster))]
|
|
72
73
|
|
|
73
74
|
n_dims = self._task.space_dimension
|
|
74
|
-
m_clusters = self.
|
|
75
|
+
m_clusters = len(self.__clusters)
|
|
75
76
|
|
|
76
77
|
epsilon = 1. - 1. * epoch / epochs
|
|
77
78
|
if np.random.uniform() < p1:
|
|
78
|
-
self.__centers[np.random.randint(0, m_clusters)] = Person(**self._init_agent().
|
|
79
|
+
self.__centers[np.random.randint(0, m_clusters)] = Person(**self._init_agent().__dict__)
|
|
79
80
|
|
|
80
|
-
new_agents, cluster_ids, location_ids = zip(*[evolve(idx) for idx in range(0,
|
|
81
|
+
new_agents, cluster_ids, location_ids = zip(*[evolve(idx) for idx in range(0, len(locations))])
|
|
81
82
|
for cl_id, loc_id, new_agent in zip(cluster_ids, location_ids, new_agents):
|
|
82
83
|
self.__clusters[cl_id][loc_id] = self._greedy_select_agent(self.__clusters[cl_id][loc_id], new_agent)
|
|
83
84
|
|