├── LICENSE ├── README.md ├── gitignore.txt ├── pyMetaheuristic ├── __init__.py ├── algorithm │ ├── __init__.py │ ├── abco.py │ ├── afsa.py │ ├── alo.py │ ├── aoa.py │ ├── ars.py │ ├── bat_a.py │ ├── bbo.py │ ├── cem.py │ ├── csa.py │ ├── cuckoo_s.py │ ├── da.py │ ├── de.py │ ├── dfo.py │ ├── fda.py │ ├── firefly_a.py │ ├── fpa.py │ ├── ga.py │ ├── goa.py │ ├── gsa.py │ ├── gwo.py │ ├── hho.py │ ├── i_gwo.py │ ├── i_woa.py │ ├── jso.py │ ├── jy.py │ ├── kha.py │ ├── memetic_a.py │ ├── mfa.py │ ├── mvo.py │ ├── pfa.py │ ├── pso.py │ ├── random_s.py │ ├── sa.py │ ├── sine_cosine_a.py │ ├── sos.py │ ├── spbo.py │ ├── ssa.py │ ├── tlbo.py │ └── whale_optimization_a.py ├── test_function │ ├── __init__.py │ └── single.py └── utils │ ├── __init__.py │ └── graphs.py └── setup.py /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2022 by Valdecy Pereira 2 | 3 | pyMetaheuristic is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | pyMetaheuristic is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with pyMetaheuristic. If not, see . -------------------------------------------------------------------------------- /gitignore.txt: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | 131 | # Pycharm 132 | .idea/ 133 | 134 | # Experiment data 135 | *.png 136 | *.json -------------------------------------------------------------------------------- /pyMetaheuristic/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/__init__.py: -------------------------------------------------------------------------------- 1 | from .abco import artificial_bee_colony_optimization 2 | from .afsa import artificial_fish_swarm_algorithm 3 | from .ars import adaptive_random_search 4 | from .alo import ant_lion_optimizer 5 | from .aoa import arithmetic_optimization_algorithm 6 | from .bat_a import bat_algorithm 7 | from .bbo import biogeography_based_optimization 8 | from .cem import cross_entropy_method 9 | from .csa import crow_search_algorithm 10 | from .cuckoo_s import cuckoo_search 11 | from .da import dragonfly_algorithm 12 | from .de import differential_evolution 13 | from .dfo import dispersive_fly_optimization 14 | from .fda import flow_direction_algorithm 15 | from .firefly_a import firefly_algorithm 16 | from .fpa import flower_pollination_algorithm 17 | from .ga import genetic_algorithm 18 | from .goa import grasshopper_optimization_algorithm 19 | from .gsa import gravitational_search_algorithm 20 | from .gwo import grey_wolf_optimizer 21 | from .hho import harris_hawks_optimization 22 | from .i_gwo import improved_grey_wolf_optimizer 23 | from .i_woa import improved_whale_optimization_algorithm 24 | from .jso import jellyfish_search_optimizer 25 | from .jy import victory 26 | from .kha import krill_herd_algorithm 27 | from .memetic_a import memetic_algorithm 28 | from .mfa import moth_flame_algorithm 29 | from .mvo import muti_verse_optimizer 30 | from .pfa import pathfinder_algorithm 31 | from .pso import particle_swarm_optimization 32 | from .random_s import random_search 33 | from .sa import simulated_annealing 34 | from .sine_cosine_a import sine_cosine_algorithm 35 | from .ssa import salp_swarm_algorithm 36 | from .sos import symbiotic_organisms_search 37 | from .spbo import student_psychology_based_optimization 38 | from .tlbo import teaching_learning_based_optimization 39 | from .whale_optimization_a import whale_optimization_algorithm -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/abco.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Artificial Bee Colony Optimization 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_sources(food_sources = 3, min_values = [-5,-5], max_values = [5, 5], target_function = target_function): 27 | sources = np.zeros((food_sources, len(min_values) + 1)) 28 | for i in range(0, food_sources): 29 | for j in range(0, len(min_values)): 30 | sources[i,j] = random.uniform(min_values[j], max_values[j]) 31 | sources[i,-1] = target_function(sources[i,0:sources.shape[1]-1]) 32 | return sources 33 | 34 | ############################################################################ 35 | 36 | # Function: Fitness Value 37 | def fitness_calc(function_value): 38 | if(function_value >= 0): 39 | fitness_value = 1.0/(1.0 + function_value) 40 | else: 41 | fitness_value = 1.0 + abs(function_value) 42 | return fitness_value 43 | 44 | # Function: Fitness 45 | def fitness_function(searching_in_sources): 46 | fitness = np.zeros((searching_in_sources.shape[0], 2)) 47 | for i in range(0, fitness.shape[0]): 48 | fitness[i,0] = fitness_calc(searching_in_sources[i,-1]) 49 | fit_sum = fitness[:,0].sum() 50 | fitness[0,1] = fitness[0,0] 51 | for i in range(1, fitness.shape[0]): 52 | fitness[i,1] = (fitness[i,0] + fitness[i-1,1]) 53 | for i in range(0, fitness.shape[0]): 54 | fitness[i,1] = fitness[i,1]/fit_sum 55 | return fitness 56 | 57 | # Function: Selection 58 | def roulette_wheel(fitness): 59 | ix = 0 60 | random = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 61 | for i in range(0, fitness.shape[0]): 62 | if (random <= fitness[i, 1]): 63 | ix = i 64 | break 65 | return ix 66 | 67 | ############################################################################ 68 | 69 | # Function: Employed Bee 70 | def employed_bee(sources, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 71 | searching_in_sources = np.copy(sources) 72 | new_solution = np.zeros((1, len(min_values))) 73 | trial = np.zeros((sources.shape[0], 1)) 74 | for i in range(0, searching_in_sources.shape[0]): 75 | phi = random.uniform(-1, 1) 76 | j = np.random.randint(len(min_values), size = 1)[0] 77 | k = np.random.randint(searching_in_sources.shape[0], size = 1)[0] 78 | while i == k: 79 | k = np.random.randint(searching_in_sources.shape[0], size = 1)[0] 80 | xij = searching_in_sources[i, j] 81 | xkj = searching_in_sources[k, j] 82 | vij = xij + phi*(xij - xkj) 83 | for variable in range(0, len(min_values)): 84 | new_solution[0, variable] = searching_in_sources[i, variable] 85 | new_solution[0, j] = np.clip(vij, min_values[j], max_values[j]) 86 | new_function_value = target_function(new_solution[0,0:new_solution.shape[1]]) 87 | if (fitness_calc(new_function_value)> fitness_calc(searching_in_sources[i,-1])): 88 | searching_in_sources[i,j] = new_solution[0, j] 89 | searching_in_sources[i,-1] = new_function_value 90 | else: 91 | trial[i,0] = trial[i,0] + 1 92 | for variable in range(0, len(min_values)): 93 | new_solution[0, variable] = 0.0 94 | return searching_in_sources, trial 95 | 96 | # Function: Oulooker 97 | def outlooker_bee(searching_in_sources, fitness, trial, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 98 | improving_sources = np.copy(searching_in_sources) 99 | new_solution = np.zeros((1, len(min_values))) 100 | trial_update = np.copy(trial) 101 | for repeat in range(0, improving_sources.shape[0]): 102 | i = roulette_wheel(fitness) 103 | phi = random.uniform(-1, 1) 104 | j = np.random.randint(len(min_values), size = 1)[0] 105 | k = np.random.randint(improving_sources.shape[0], size = 1)[0] 106 | while i == k: 107 | k = np.random.randint(improving_sources.shape[0], size = 1)[0] 108 | xij = improving_sources[i, j] 109 | xkj = improving_sources[k, j] 110 | vij = xij + phi*(xij - xkj) 111 | for variable in range(0, len(min_values)): 112 | new_solution[0, variable] = improving_sources[i, variable] 113 | new_solution[0, j] = np.clip(vij, min_values[j], max_values[j]) 114 | new_function_value = target_function(new_solution[0,0:new_solution.shape[1]]) 115 | if (fitness_calc(new_function_value) > fitness_calc(improving_sources[i,-1])): 116 | improving_sources[i,j] = new_solution[0, j] 117 | improving_sources[i,-1] = new_function_value 118 | trial_update[i,0] = 0 119 | else: 120 | trial_update[i,0] = trial_update[i,0] + 1 121 | for variable in range(0, len(min_values)): 122 | new_solution[0, variable] = 0.0 123 | return improving_sources, trial_update 124 | 125 | # Function: Scouter 126 | def scouter_bee(improving_sources, trial_update, limit = 3, target_function = target_function): 127 | for i in range(0, improving_sources.shape[0]): 128 | if (trial_update[i,0] > limit): 129 | for j in range(0, improving_sources.shape[1] - 1): 130 | improving_sources[i,j] = np.random.normal(0, 1, 1)[0] 131 | function_value = target_function(improving_sources[i,0:improving_sources.shape[1]-1]) 132 | improving_sources[i,-1] = function_value 133 | return improving_sources 134 | 135 | ############################################################################ 136 | 137 | # ABCO Function 138 | def artificial_bee_colony_optimization(food_sources = 3, iterations = 50, min_values = [-5,-5], max_values = [5,5], employed_bees = 3, outlookers_bees = 3, limit = 3, target_function = target_function, verbose = True): 139 | count = 0 140 | best_value = float('inf') 141 | sources = initial_sources(food_sources, min_values, max_values, target_function) 142 | fitness = fitness_function(sources) 143 | while (count <= iterations): 144 | if (count > 0): 145 | if (verbose == True): 146 | print('Iteration = ', count, ' f(x) = ', best_value) 147 | e_bee = employed_bee(sources, min_values, max_values, target_function) 148 | for i in range(0, employed_bees - 1): 149 | e_bee = employed_bee(e_bee[0], min_values, max_values, target_function) 150 | fitness = fitness_function(e_bee[0]) 151 | o_bee = outlooker_bee(e_bee[0], fitness, e_bee[1], min_values, max_values, target_function) 152 | for i in range(0, outlookers_bees - 1): 153 | o_bee = outlooker_bee(o_bee[0], fitness, o_bee[1], min_values, max_values, target_function) 154 | value = np.copy(o_bee[0][o_bee[0][:,-1].argsort()][0,:]) 155 | if (best_value > value[-1]): 156 | best_solution = np.copy(value) 157 | best_value = np.copy(value[-1]) 158 | sources = scouter_bee(o_bee[0], o_bee[1], limit = limit, target_function = target_function) 159 | fitness = fitness_function(sources) 160 | count = count + 1 161 | return best_solution 162 | 163 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/afsa.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Artificial Fish Swarm Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | 16 | ############################################################################ 17 | 18 | # Function 19 | def target_function(): 20 | return 21 | 22 | ############################################################################ 23 | 24 | # Function: Initialize Variables 25 | def initial_position(school_size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 26 | position = np.zeros((school_size, len(min_values)+1)) 27 | for i in range(0, school_size): 28 | for j in range(0, len(min_values)): 29 | position[i,j] = random.uniform(min_values[j], max_values[j]) 30 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 31 | return position 32 | 33 | ############################################################################ 34 | 35 | # Function: Distance Matrix 36 | def build_distance_matrix(position): 37 | a = position[:,:-1] 38 | b = a.reshape(np.prod(a.shape[:-1]), 1, a.shape[-1]) 39 | return np.sqrt(np.einsum('ijk,ijk->ij', b - a, b - a)).squeeze() 40 | 41 | ############################################################################ 42 | 43 | # Function: Behavior - Prey 44 | def prey(position, visual, attempts, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 45 | position_ = np.copy(position) 46 | for i in range(0, position.shape[0]): 47 | count = 0 48 | while (count <= attempts): 49 | k = [c for c in range(0, position.shape[0]) if i != c] 50 | k = random.choice(k) 51 | for j in range(0, len(min_values)): 52 | rand = np.random.uniform(low = -1, high = 1, size = 1)[0] 53 | position_[i, j] = np.clip(position[k, j] + visual*rand, min_values[j], max_values[j]) 54 | position_[i,-1] = target_function(position_[i,0:position_.shape[1]-1]) 55 | if (position_[i,-1] <= position[i,-1]): 56 | position[i,:] = position_[i,:] 57 | count = attempts + 10 58 | count = count + 1 59 | if (count == attempts + 10): 60 | k = [c for c in range(0, position.shape[0]) if i != c] 61 | k = random.choice(k) 62 | for j in range(0, len(min_values)): 63 | rand = np.random.uniform(low = -1, high = 1, size = 1)[0] 64 | position_[i, j] = np.clip(position[k, j] + visual*rand, min_values[j], max_values[j]) 65 | position_[i,-1] = target_function(position_[i,0:position_.shape[1]-1]) 66 | position[i,:] = position_[i,:] 67 | return position 68 | 69 | # Function: Behavior - Swarm 70 | def swarm(position, visual, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 71 | distance_matrix = build_distance_matrix(position) 72 | position_ = np.copy(position) 73 | for i in range(0, position.shape[0]): 74 | k = [c for c in range(0, distance_matrix.shape[1]) if distance_matrix[i, c] <= visual and i != c] 75 | if (len(k) == 0): 76 | k = [c for c in range(0, position.shape[0]) if i != c] 77 | k = random.choice(k) 78 | for j in range(0, len(min_values)): 79 | rand = np.random.uniform(low = -1, high = 1, size = 1)[0] 80 | position_[i, j] = np.clip(position[k, j] + visual*rand, min_values[j], max_values[j]) 81 | position_[i,-1] = target_function(position_[i,0:position_.shape[1]-1]) 82 | if (position_[i,-1] <= position[i,-1]): 83 | position[i,:] = position_[i,:] 84 | return position 85 | 86 | # Function: Behavior - Follow 87 | def follow(position, best_position, visual, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 88 | position_ = np.copy(position) 89 | for i in range(0, position.shape[0]): 90 | k = [c for c in range(0, position.shape[0]) if i != c] 91 | k = random.choice(k) 92 | for j in range(0, len(min_values)): 93 | rand = np.random.uniform(low = -1, high = 1, size = 1)[0] 94 | position_[i, j] = np.clip(best_position[0, j] + visual*rand, min_values[j], max_values[j]) 95 | position_[i,-1] = target_function(position_[i,0:position_.shape[1]-1]) 96 | if (position_[i,-1] <= position[i,-1]): 97 | position[i,:] = position_[i,:] 98 | return position 99 | 100 | # Function: Behavior - Move 101 | def move(position, visual, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 102 | position_ = np.copy(position) 103 | for i in range(0, position.shape[0]): 104 | k = [c for c in range(0, position.shape[0]) if i != c] 105 | k = random.choice(k) 106 | for j in range(0, len(min_values)): 107 | rand = np.random.uniform(low = -1, high = 1, size = 1)[0] 108 | position_[i, j] = np.clip(position[0, j] + visual*rand, min_values[j], max_values[j]) 109 | position_[i,-1] = target_function(position_[i,0:position_.shape[1]-1]) 110 | if (position_[i,-1] <= position[i,-1]): 111 | position[i,:] = position_[i,:] 112 | return position 113 | 114 | # Function: Behavior - Leap 115 | def leap(position, visual, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 116 | for i in range(0, position.shape[0]): 117 | k = [c for c in range(0, position.shape[0]) if i != c] 118 | k = random.choice(k) 119 | for j in range(0, len(min_values)): 120 | rand = np.random.uniform(low = -1, high = 1, size = 1)[0] 121 | position[i, j] = np.clip(position[0, j] + visual*rand, min_values[j], max_values[j]) 122 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 123 | return position 124 | 125 | ############################################################################ 126 | 127 | # AFSA Function 128 | def artificial_fish_swarm_algorithm(school_size = 5, attempts = 100, visual = 0.3, step = 0.5, delta = 0.5, min_values = [-5,-5], max_values = [5,5], iterations = 1000, target_function = target_function, verbose = True): 129 | count = 0 130 | position = initial_position(school_size, min_values, max_values, target_function) 131 | best_position = np.copy(position[np.argmin(position[:,-1]),:].reshape(1,-1)) 132 | while (count <= iterations): 133 | if (verbose == True): 134 | print('Iteration = ', count, ' f(x) = ', best_position[0, -1]) 135 | position = prey(position, visual, attempts, min_values, max_values, target_function) 136 | position = swarm(position, visual, min_values, max_values, target_function) 137 | position = follow(position, best_position, visual, min_values, max_values, target_function) 138 | position = move(position, visual, min_values, max_values, target_function) 139 | position = leap(position, visual, min_values, max_values, target_function) 140 | if ( abs((sum(position[:,-1])/position.shape[0]) - best_position[0,-1]) <= delta): 141 | position = leap(position, visual, min_values, max_values, target_function) 142 | if (np.amin(position[:,-1]) < best_position[0,-1]): 143 | best_position = np.copy(position[np.argmin(position[:,-1]),:].reshape(1,-1)) 144 | count = count + 1 145 | return best_position 146 | 147 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/alo.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Ant Lion Optimizer 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_population(colony_size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | population = np.zeros((colony_size, len(min_values) + 1)) 28 | for i in range(0, colony_size): 29 | for j in range(0, len(min_values)): 30 | population[i,j] = random.uniform(min_values[j], max_values[j]) 31 | population[i,-1] = target_function(population[i,0:population.shape[1]-1]) 32 | return population 33 | 34 | ############################################################################ 35 | 36 | # Function: Fitness 37 | def fitness_function(population): 38 | fitness = np.zeros((population.shape[0], 2)) 39 | for i in range(0, fitness.shape[0]): 40 | fitness[i,0] = 1/(1+ population[i,-1] + abs(population[:,-1].min())) 41 | fit_sum = fitness[:,0].sum() 42 | fitness[0,1] = fitness[0,0] 43 | for i in range(1, fitness.shape[0]): 44 | fitness[i,1] = (fitness[i,0] + fitness[i-1,1]) 45 | for i in range(0, fitness.shape[0]): 46 | fitness[i,1] = fitness[i,1]/fit_sum 47 | return fitness 48 | 49 | # Function: Selection 50 | def roulette_wheel(fitness): 51 | ix = 0 52 | random = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 53 | for i in range(0, fitness.shape[0]): 54 | if (random <= fitness[i, 1]): 55 | ix = i 56 | break 57 | return ix 58 | 59 | ############################################################################ 60 | 61 | # Function: Random Walk 62 | def random_walk(iterations): 63 | x_random_walk = [0]*(iterations + 1) 64 | x_random_walk[0] = 0 65 | for k in range(1, len( x_random_walk)): 66 | rand = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 67 | if rand > 0.5: 68 | rand = 1 69 | else: 70 | rand = 0 71 | x_random_walk[k] = x_random_walk[k-1] + (2*rand - 1) 72 | return x_random_walk 73 | 74 | # Function: Combine Ants 75 | def combine(population, antlions): 76 | combination = np.vstack([population, antlions]) 77 | combination = combination[combination[:,-1].argsort()] 78 | for i in range(0, population.shape[0]): 79 | for j in range(0, population.shape[1]): 80 | antlions[i,j] = combination[i,j] 81 | population[i,j] = combination[i + population.shape[0],j] 82 | return population, antlions 83 | 84 | # Function: Update Antlion 85 | def update_ants(population, antlions, count, iterations, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 86 | i_ratio = 1 87 | minimum_c_i = np.zeros((1, population.shape[1])) 88 | maximum_d_i = np.zeros((1, population.shape[1])) 89 | minimum_c_e = np.zeros((1, population.shape[1])) 90 | maximum_d_e = np.zeros((1, population.shape[1])) 91 | elite_antlion = np.zeros((1, population.shape[1])) 92 | if (count > 0.10*iterations): 93 | w_exploration = 2 94 | i_ratio = (10**w_exploration)*(count/iterations) 95 | elif(count > 0.50*iterations): 96 | w_exploration = 3 97 | i_ratio = (10**w_exploration)*(count/iterations) 98 | elif(count > 0.75*iterations): 99 | w_exploration = 4 100 | i_ratio = (10**w_exploration)*(count/iterations) 101 | elif(count > 0.90*iterations): 102 | w_exploration = 5 103 | i_ratio = (10**w_exploration)*(count/iterations) 104 | elif(count > 0.95*iterations): 105 | w_exploration = 6 106 | i_ratio = (10**w_exploration)*(count/iterations) 107 | for i in range (0, population.shape[0]): 108 | fitness = fitness_function(antlions) 109 | ant_lion = roulette_wheel(fitness) 110 | for j in range (0, population.shape[1] - 1): 111 | minimum_c_i[0,j] = antlions[antlions[:,-1].argsort()][0,j]/i_ratio 112 | maximum_d_i[0,j] = antlions[antlions[:,-1].argsort()][-1,j]/i_ratio 113 | elite_antlion[0,j] = antlions[antlions[:,-1].argsort()][0,j] 114 | minimum_c_e[0,j] = antlions[antlions[:,-1].argsort()][0,j]/i_ratio 115 | maximum_d_e[0,j] = antlions[antlions[:,-1].argsort()][-1,j]/i_ratio 116 | rand = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 117 | if (rand < 0.5): 118 | minimum_c_i[0,j] = minimum_c_i[0,j] + antlions[ant_lion,j] 119 | minimum_c_e[0,j] = minimum_c_e[0,j] + elite_antlion[0,j] 120 | else: 121 | minimum_c_i[0,j] = - minimum_c_i[0,j] + antlions[ant_lion,j] 122 | minimum_c_e[0,j] = - minimum_c_e[0,j] + elite_antlion[0,j] 123 | 124 | rand = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 125 | if (rand >= 0.5): 126 | maximum_d_i[0,j] = maximum_d_i[0,j] + antlions[ant_lion,j] 127 | maximum_d_e[0,j] = maximum_d_e[0,j] + elite_antlion[0,j] 128 | else: 129 | maximum_d_i[0,j] = - maximum_d_i[0,j] + antlions[ant_lion,j] 130 | maximum_d_e[0,j] = - maximum_d_e[0,j] + elite_antlion[0,j] 131 | x_random_walk = random_walk(iterations) 132 | e_random_walk = random_walk(iterations) 133 | min_x, max_x = min(x_random_walk), max(x_random_walk) 134 | x_random_walk[count] = (((x_random_walk[count] - min_x)*(maximum_d_i[0,j] - minimum_c_i[0,j]))/(max_x - min_x)) + minimum_c_i[0,j] 135 | min_e, max_e = min(e_random_walk), max(e_random_walk) 136 | e_random_walk[count] = (((e_random_walk[count] - min_e)*(maximum_d_e[0,j] - minimum_c_e[0,j]))/(max_e - min_e)) + minimum_c_e[0,j] 137 | population[i,j] = np.clip((x_random_walk[count] + e_random_walk[count])/2, min_values[j], max_values[j]) 138 | population[i,-1] = target_function(population[i,0:population.shape[1]-1]) 139 | return population, antlions 140 | 141 | ############################################################################ 142 | 143 | # ALO Function 144 | def ant_lion_optimizer(colony_size = 5, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True): 145 | count = 0 146 | population = initial_population(colony_size, min_values, max_values, target_function) 147 | antlions = initial_population(colony_size, min_values, max_values, target_function) 148 | elite = np.copy(antlions[antlions[:,-1].argsort()][0,:]) 149 | while (count <= iterations): 150 | if (verbose == True): 151 | print('Iteration = ', count, ' f(x) = ', elite[-1]) 152 | population, antlions = update_ants(population, antlions, count, iterations, min_values, max_values, target_function) 153 | population, antlions = combine(population, antlions) 154 | value = np.copy(antlions[antlions[:,-1].argsort()][0,:]) 155 | if(elite[-1] > value[-1]): 156 | elite = np.copy(value) 157 | else: 158 | antlions[antlions[:,-1].argsort()][0,:] = np.copy(elite) 159 | count = count + 1 160 | return elite 161 | 162 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/aoa.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Arithmetic Optimization Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_population(size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | population = np.zeros((size, len(min_values) + 1)) 28 | for i in range(0, size): 29 | for j in range(0, len(min_values)): 30 | population[i,j] = random.uniform(min_values[j], max_values[j]) 31 | population[i,-1] = target_function(population[i,0:population.shape[1]-1]) 32 | return population 33 | 34 | ############################################################################ 35 | 36 | # Function: Update Population 37 | def update_population(population, elite, mu, moa, mop, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 38 | e = 2.2204e-16 39 | p = np.copy(population) 40 | for i in range(0, population.shape[0]): 41 | for j in range(0, len(min_values)): 42 | r1 = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 43 | r2 = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 44 | r3 = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 45 | if (r1 > moa and r2 > 0.5): 46 | p[i, j] = np.clip(elite[j] / (mop + e) * ( (max_values[j] - min_values[j]) * mu + min_values[j]), min_values[j], max_values[j]) 47 | elif (r1 > moa and r2 <= 0.5): 48 | p[i, j] = np.clip(elite[j] * ( mop ) * ( (max_values[j] - min_values[j]) * mu + min_values[j]), min_values[j], max_values[j]) 49 | elif (r1 <= moa and r3 > 0.5): 50 | p[i, j] = np.clip(elite[j] - ( mop ) * ( (max_values[j] - min_values[j]) * mu + min_values[j]), min_values[j], max_values[j]) 51 | elif (r1 <= moa and r3 <= 0.5): 52 | p[i, j] = np.clip(elite[j] + ( mop ) * ( (max_values[j] - min_values[j]) * mu + min_values[j]), min_values[j], max_values[j]) 53 | p[i, -1] = target_function(population[i, :-1]) 54 | if (p[i, -1] < population[i, -1]): 55 | population[i, :] = p[i, :] 56 | return population 57 | 58 | ############################################################################ 59 | 60 | # AOA Function 61 | def arithmetic_optimization_algorithm(size = 5, min_values = [-5,-5], max_values = [5,5], iterations = 50, alpha = 0.5, mu = 5, target_function = target_function, verbose = True): 62 | count = 0 63 | population = initial_population(size, min_values, max_values, target_function) 64 | elite = np.copy(population[population[:,-1].argsort()][0,:]) 65 | while (count <= iterations): 66 | if (verbose == True): 67 | print('Iteration = ', count, ' f(x) = ', elite[-1]) 68 | moa = 0.2 + count*((1 - 0.2)/iterations) 69 | mop = 1 - ( (count**(1/alpha)) / (iterations**(1/alpha)) ) 70 | population = update_population(population, elite, mu, moa, mop, min_values, max_values, target_function) 71 | if (population[population[:,-1].argsort()][0,-1] < elite[-1]): 72 | elite = np.copy(population[population[:,-1].argsort()][0,:]) 73 | count = count + 1 74 | return elite 75 | 76 | ############################################################################ 77 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/ars.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Random Search 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import copy 15 | import random 16 | import os 17 | 18 | ############################################################################ 19 | 20 | # Function 21 | def target_function(): 22 | return 23 | 24 | ############################################################################ 25 | 26 | # Function: Initialize Variables 27 | def initial_position(solutions = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 28 | position = np.zeros((solutions, len(min_values) + 1)) 29 | for i in range(0, solutions): 30 | for j in range(0, len(min_values)): 31 | position[i,j] = random.uniform(min_values[j], max_values[j]) 32 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 33 | return position 34 | 35 | ############################################################################ 36 | 37 | # Function: Steps 38 | def step(position, min_values = [-5,-5], max_values = [5,5], step_size = [0,0], target_function = target_function): 39 | position_temp = np.copy(position) 40 | for i in range(position.shape[0]): 41 | for j in range(position.shape[1]-1): 42 | minimun = min(min_values[j], position[i,j] + step_size[i][j]) 43 | maximum = max(max_values[j], position[i,j] - step_size[i][j]) 44 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 45 | position_temp[i, j] = np.clip(minimun + (maximum - minimun)*rand, min_values[j], max_values[j]) 46 | position_temp[i,-1] = target_function(position_temp[i,0:position_temp.shape[1]-1]) 47 | return position_temp 48 | 49 | # Function: Large Steps 50 | def large_step(position, min_values = [-5,-5], max_values = [5,5], step_size = [0,0], count = 0, large_step_threshold = 10, factor_1 = 3, factor_2 = 1.5, target_function = target_function): 51 | factor = 0 52 | position_temp = np.copy(position) 53 | step_size_temp = copy.deepcopy(step_size) 54 | for i in range(position.shape[0]): 55 | if (count > 0 and count % large_step_threshold == 0): 56 | factor = factor_1 57 | else: 58 | factor = factor_2 59 | for j in range(0, len(min_values)): 60 | step_size_temp[i][j] = step_size[i][j]*factor 61 | for i in range(position.shape[0]): 62 | for j in range(position.shape[1]-1): 63 | minimun = min(min_values[j], position[i,j] + step_size[i][j]) 64 | maximum = max(max_values[j], position[i,j] - step_size[i][j]) 65 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 66 | position_temp[i, j] = np.clip(minimun + (maximum - minimun)*rand, min_values[j], max_values[j]) 67 | position_temp[i,-1] = target_function(position_temp[i,0:position_temp.shape[1]-1]) 68 | return step_size_temp, position_temp 69 | 70 | ############################################################################ 71 | 72 | # ARS Function 73 | def adaptive_random_search(solutions = 5, min_values = [-5,-5], max_values = [5,5], step_size_factor = 0.05, factor_1 = 3, factor_2 = 1.5, iterations = 50, large_step_threshold = 10, improvement_threshold = 25, target_function = target_function, verbose = True): 74 | count = 0 75 | threshold = [0]*solutions 76 | position = initial_position(solutions, min_values, max_values, target_function) 77 | best_solution = np.copy(position[position[:,-1].argsort()][0,:]) 78 | step_size = [] 79 | for i in range(0, position.shape[0]): 80 | step_size.append([0]*len(min_values)) 81 | for j in range(0, len(min_values)): 82 | step_size[i][j] = (max_values[j] - min_values[j])*step_size_factor 83 | while (count <= iterations): 84 | if (verbose == True): 85 | print('Iteration = ', count, ' f(x) = ', best_solution[-1]) 86 | position_step = step(position, min_values, max_values, step_size, target_function) 87 | step_large, position_large_step = large_step(position, min_values, max_values, step_size, count, large_step_threshold, factor_1, factor_2, target_function) 88 | for i in range(position.shape[0]): 89 | if(position_step[i,-1] < position[i,-1] or position_large_step[i,-1] < position[i,-1]): 90 | if(position_large_step[i,-1] < position_step[i,-1]): 91 | position[i,:] = np.copy(position_large_step[i,:]) 92 | for j in range(0, position.shape[1] -1): 93 | step_size[i][j] = step_large[i][j] 94 | else: 95 | position[i,:] = np.copy(position_step[i,:]) 96 | threshold[i] = 0 97 | else: 98 | threshold[i] = threshold[i] + 1 99 | if (threshold[i] >= improvement_threshold): 100 | threshold[i] = 0 101 | for j in range(0, len(min_values)): 102 | step_size[i][j] = step_size[i][j]/factor_2 103 | if(best_solution[-1] > position[position[:,-1].argsort()][0,-1]): 104 | best_solution = np.copy(position[position[:,-1].argsort()][0,:]) 105 | count = count + 1 106 | return best_solution, position 107 | 108 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/bat_a.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Bat Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import math 16 | import os 17 | 18 | ############################################################################ 19 | 20 | # Function 21 | def target_function(): 22 | return 23 | 24 | ############################################################################ 25 | 26 | # Function: Initialize Variables 27 | def initial_position(swarm_size = 3, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 28 | position = np.zeros((swarm_size, len(min_values) + 1)) 29 | velocity = np.zeros((swarm_size, len(min_values))) 30 | frequency = np.zeros((swarm_size, 1)) 31 | rate = np.zeros((swarm_size, 1)) 32 | loudness = np.zeros((swarm_size, 1)) 33 | for i in range(0, swarm_size): 34 | for j in range(0, len(min_values)): 35 | position[i,j] = random.uniform(min_values[j], max_values[j]) 36 | position[i, -1] = target_function(position[i,0:position.shape[1]-1]) 37 | rate[i, 0] = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 38 | loudness[i, 0] = random.uniform(1, 2) 39 | return position, velocity, frequency, rate, loudness 40 | 41 | ############################################################################ 42 | 43 | # Function: Updtade Position 44 | def update_position(position, velocity, frequency, rate, loudness, best_ind, alpha = 0.9, gama = 0.9, fmin = 0, fmax = 10, count = 0, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 45 | position_temp = np.zeros((position.shape[0], position.shape[1])) 46 | for i in range(0, position.shape[0]): 47 | beta = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 48 | frequency[i,0] = fmin + (fmax - fmin)*beta 49 | for j in range(0, len(max_values)): 50 | velocity[i, j] = velocity[i,j] + (position[i,j] - best_ind[j])*frequency[i,0] 51 | for k in range(0, len(max_values)): 52 | position_temp[i,k] = position[i,k] + velocity[i,k] 53 | if (position_temp[i,k] > max_values[k]): 54 | position_temp[i,k] = max_values[k] 55 | velocity[i,k] = 0 56 | elif(position_temp[i,k] < min_values[k]): 57 | position_temp[i,k] = min_values[k] 58 | velocity[i,k] = 0 59 | position_temp[i,-1] = target_function(position_temp[i,0:len(max_values)]) 60 | rand = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 61 | if (rand > rate[i,0]): 62 | for L in range(0, len(max_values)): 63 | position_temp[i,L] = best_ind[L] + random.uniform(-1, 1)*loudness.mean() 64 | if (position_temp[i,L] > max_values[L]): 65 | position_temp[i,L] = max_values[L] 66 | velocity[i,L] = 0 67 | elif(position_temp[i,L] < min_values[L]): 68 | position_temp[i,L] = min_values[L] 69 | velocity[i,L] = 0 70 | position_temp[i,-1] = target_function(position_temp[i,0:len(max_values)]) 71 | rand = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 72 | if (rand < position[i,-1] and position_temp[i,-1] <= position[i,-1]): 73 | for m in range(0, len(max_values)): 74 | position[i, m] = position_temp[i, m] 75 | position[i,-1] = target_function(position[i,0:len(max_values)]) 76 | rate[i,0] = rate[i,0]*(1 - math.exp(-gama*count)) 77 | loudness[i,0] = alpha*loudness[i,-1] 78 | value = np.copy(position[position[:,-1].argsort()][0,:]) 79 | if(best_ind[-1] > value[-1]): 80 | best_ind = np.copy(value) 81 | return position, velocity, frequency, rate, loudness, best_ind 82 | 83 | ############################################################################ 84 | 85 | # BA Function 86 | def bat_algorithm(swarm_size = 3, min_values = [-5,-5], max_values = [5,5], iterations = 50, alpha = 0.9, gama = 0.9, fmin = 0, fmax = 10, target_function = target_function, verbose = True): 87 | count = 0 88 | position, velocity, frequency, rate, loudness = initial_position(swarm_size, min_values, max_values, target_function) 89 | best_ind = np.copy(position[position[:,-1].argsort()][0,:]) 90 | while (count <= iterations): 91 | if (verbose == True): 92 | print('Iteration = ', count, ' f(x) = ', best_ind[-1]) 93 | position, velocity, frequency, rate, loudness, best_ind = update_position(position, velocity, frequency, rate, loudness, best_ind, alpha, gama, fmin, fmax, count, min_values, max_values, target_function) 94 | count = count + 1 95 | return best_ind 96 | 97 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/bbo.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Biogeography-Based Optimization 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_population(population_size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | population = np.zeros((population_size, len(min_values) + 1)) 28 | for i in range(0, population_size): 29 | for j in range(0, len(min_values)): 30 | population[i,j] = random.uniform(min_values[j], max_values[j]) 31 | population[i,-1] = target_function(population[i,0:population.shape[1]-1]) 32 | return population 33 | 34 | ############################################################################ 35 | 36 | # Function: Migration 37 | def migration(population, island, mu, lbd, target_function): 38 | for k in range(0, island.shape[0]): 39 | for j in range(0, island.shape[1]): 40 | rand_1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 41 | if (rand_1 < lbd[k]): 42 | rand_2 = (int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1)) * sum(mu) 43 | select = mu[1]; 44 | idx = 0; 45 | while (rand_2 > select) and (idx < island.shape[0]-1): 46 | idx = idx + 1; 47 | select = select + mu[idx] 48 | island[k, j] = population[idx, j] 49 | else: 50 | island[k, j] = population[k, j] 51 | island[k,-1] = target_function(island[k,:-1]) 52 | return island 53 | 54 | # Function: Mutation 55 | def mutation(offspring, elite, mutation_rate = 0.1, eta = 1, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 56 | d_mutation = 0 57 | for i in range (elite, offspring.shape[0]): 58 | for j in range(0, offspring.shape[1] - 1): 59 | probability = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 60 | if (probability < mutation_rate): 61 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 62 | rand_d = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 63 | if (rand <= 0.5): 64 | d_mutation = 2*(rand_d) 65 | d_mutation = d_mutation**(1/(eta + 1)) - 1 66 | elif (rand > 0.5): 67 | d_mutation = 2*(1 - rand_d) 68 | d_mutation = 1 - d_mutation**(1/(eta + 1)) 69 | offspring[i,j] = np.clip((offspring[i,j] + d_mutation), min_values[j], max_values[j]) 70 | offspring[i,-1] = target_function(offspring[i,:-1]) 71 | return offspring 72 | 73 | ############################################################################ 74 | 75 | # BBO Function 76 | def biogeography_based_optimization(population_size = 5, mutation_rate = 0.1, elite = 0, min_values = [-5,-5], max_values = [5,5], eta = 1, generations = 50, target_function = target_function, verbose = True): 77 | count = 0 78 | mu = [ (population_size + 1 - i) / (population_size + 1) for i in range(0, population_size) ] 79 | lbd = [1 - mu[i] for i in range(0, population_size)] 80 | population = initial_population(population_size, min_values, max_values, target_function) 81 | island = np.zeros((population.shape[0], population.shape[1])) 82 | elite_ind = np.copy(population[population[:,-1].argsort()][0,:]) 83 | while (count <= generations): 84 | if (verbose == True): 85 | print('Generation = ', count, ' f(x) = ', elite_ind[-1]) 86 | island = migration(population, island, mu, lbd, target_function) 87 | island = mutation(island, elite, mutation_rate, eta, min_values, max_values, target_function) 88 | population = np.vstack([population, island]) 89 | population = np.copy(population[population[:,-1].argsort()]) 90 | population = population[0:population_size,:] 91 | value = np.copy(population[0,:]) 92 | if(elite_ind[-1] > value[-1]): 93 | elite_ind = np.copy(value) 94 | count = count + 1 95 | return elite_ind 96 | 97 | ############################################################################ 98 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/cem.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Cross Entropy Method 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | 16 | ############################################################################ 17 | 18 | # Function 19 | def target_function(): 20 | return 21 | 22 | ############################################################################ 23 | 24 | # Function: Initialize Variables 25 | def initial_guess(n = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 26 | guess = np.zeros((n, len(min_values) + 1)) 27 | for i in range(0, n): 28 | for j in range(0, len(min_values)): 29 | guess[i,j] = random.uniform(min_values[j], max_values[j]) 30 | guess[i,-1] = target_function(guess[i,0:guess.shape[1]-1]) 31 | return guess 32 | 33 | ############################################################################ 34 | 35 | # Function: Variables Mean 36 | def guess_mean_calc(guess): 37 | guess_mean = np.zeros((1, guess.shape[1]-1)) 38 | for j in range(0, guess_mean.shape[1]): 39 | guess_mean[0,j] = guess[:,j].mean() 40 | return guess_mean 41 | 42 | # Function: Variables Standard Deviation 43 | def guess_std_calc(guess): 44 | guess_std = np.zeros((1, guess.shape[1]-1)) 45 | for j in range(0, guess_std.shape[1]): 46 | guess_std[0,j] = guess[:,j].std() 47 | return guess_std 48 | 49 | # Function: Generate Samples 50 | def generate_samples(guess, guess_mean, guess_std, min_values = [-5,-5], max_values = [5,5], k_samples = 2, target_function = target_function): 51 | guess_ = np.copy(guess) 52 | guess_sample = guess_[guess_[:,-1].argsort()] 53 | for i in range(k_samples, guess.shape[0]): 54 | for j in range(0, len(min_values)): 55 | guess_sample[i,j] = np.clip(np.random.normal(guess_mean[0,j], guess_std[0,j], 1)[0], min_values[j], max_values[j]) 56 | guess_sample[i,-1] = target_function(guess_sample[i,0:guess_sample.shape[1]-1]) 57 | return guess_sample 58 | 59 | # Function: Update Samples 60 | def update_distribution(guess, guess_mean, guess_std, learning_rate = 0.7, k_samples = 2): 61 | guess = guess[guess[:,-1].argsort()] 62 | for j in range(0, guess_mean.shape[1]): 63 | guess_mean[0,j] = learning_rate*guess_mean[0,j] + (1 - learning_rate)*guess[0:k_samples,j].mean() 64 | guess_std[0,j] = learning_rate*guess_std[0,j] + (1 - learning_rate)*guess[0:k_samples,j].std() 65 | if (guess_std[0,j] < 0.005): 66 | guess_std[0,j] = 3 67 | return guess_mean, guess_std 68 | 69 | ############################################################################ 70 | 71 | # CEM Function 72 | def cross_entropy_method(n = 5, min_values = [-5,-5], max_values = [5,5], iterations = 1000, learning_rate = 0.7, k_samples = 2, target_function = target_function, verbose = True): 73 | guess = initial_guess(n = n, min_values = min_values, max_values = max_values, target_function = target_function) 74 | guess_mean = guess_mean_calc(guess) 75 | guess_std = guess_std_calc(guess) 76 | best = np.copy(guess[guess[:,-1].argsort()][0,:]) 77 | count = 0 78 | while (count < iterations): 79 | if (verbose == True): 80 | print('Iteration = ', count, ' f(x) = ', best[-1]) 81 | guess = generate_samples(guess, guess_mean, guess_std, min_values, max_values, k_samples, target_function) 82 | guess_mean, guess_std = update_distribution(guess, guess_mean, guess_std, learning_rate, k_samples) 83 | if (best[-1] > guess[guess[:,-1].argsort()][0,:][-1]): 84 | best = np.copy(guess[guess[:,-1].argsort()][0,:]) 85 | count = count + 1 86 | return best 87 | 88 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/csa.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Crow Search Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_population(population_size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | population = np.zeros((population_size, len(min_values) + 1)) 28 | for i in range(0, population_size): 29 | for j in range(0, len(min_values)): 30 | population[i,j] = random.uniform(min_values[j], max_values[j]) 31 | population[i,-1] = target_function(population[i, 0:population.shape[1]-1]) 32 | return population 33 | 34 | ############################################################################ 35 | 36 | # Function: Update Position 37 | def update_position(population, ap, fL, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 38 | for i in range(0, population.shape[0]): 39 | idx = [i for i in range(0, population.shape[0])] 40 | idx.remove(i) 41 | idx = random.choice(idx) 42 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 43 | for j in range(0, len(min_values)): 44 | if (rand >= ap): 45 | rand_i = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 46 | population[i, j] = np.clip(population[i, j] + rand_i*fL*( population[idx, j] - population[i, j]), min_values[j], max_values[j]) 47 | else: 48 | population[i,j] = random.uniform(min_values[j], max_values[j]) 49 | population[i,-1] = target_function(population[i, 0:population.shape[1]-1]) 50 | return population 51 | 52 | ############################################################################ 53 | 54 | # Function: Crow Search Algorithm 55 | def crow_search_algorithm(population_size = 5, ap = 0.02, fL = 0.02, min_values = [-5,-5], max_values = [5,5], iterations = 10, target_function = target_function, verbose = False): 56 | count = 0 57 | population = initial_population(population_size, min_values, max_values, target_function) 58 | best_ind = np.copy(population[population[:,-1].argsort()][ 0,:]) 59 | while (count <= iterations): 60 | if (verbose == True): 61 | print('Iteration = ', count, ' f(x) = ', best_ind[-1]) 62 | population = update_position(population, ap, fL, min_values, max_values, target_function) 63 | value = np.copy(population[0,:]) 64 | if(best_ind[-1] > value[-1]): 65 | best_ind = np.copy(value) 66 | count = count + 1 67 | return best_ind 68 | 69 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/cuckoo_s.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Cuckoo Search 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import math 15 | import random 16 | import os 17 | 18 | ############################################################################ 19 | 20 | # Function 21 | def target_function(): 22 | return 23 | 24 | ############################################################################ 25 | 26 | # Function: Initialize Variables 27 | def initial_position(birds = 3, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 28 | position = np.zeros((birds, len(min_values) + 1)) 29 | for i in range(0, birds): 30 | for j in range(0, len(min_values)): 31 | position[i,j] = random.uniform(min_values[j], max_values[j]) 32 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 33 | return position 34 | 35 | ############################################################################ 36 | 37 | # Function: Levy Distribution 38 | def levy_flight(mean): 39 | x1 = math.sin((mean - 1.0)*(random.uniform(-0.5*math.pi, 0.5*math.pi)) )/(math.pow(math.cos((random.uniform(-0.5*math.pi, 0.5*math.pi))), (1.0/(mean - 1.0)))) 40 | x2 = math.pow((math.cos((2.0 - mean)*(random.uniform(-0.5*math.pi, 0.5*math.pi)))/(-math.log(random.uniform(0.0, 1.0)))), ((2.0 - mean)/(mean - 1.0))) 41 | return x1*x2 42 | 43 | # Function: Replace Bird 44 | def replace_bird(position, alpha_value = 0.01, lambda_value = 1.5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 45 | random_bird = np.random.randint(position.shape[0], size = 1)[0] 46 | new_solution = np.zeros((1, position.shape[1])) 47 | for j in range(0, position.shape[1] - 1): 48 | new_solution[0, j] = np.clip(position[random_bird, j] + alpha_value*levy_flight(lambda_value)*position[random_bird, j]*(int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1)), min_values[j], max_values[j]) 49 | new_solution[0,-1] = target_function(new_solution[0,0:new_solution.shape[1]-1]) 50 | if (position[random_bird, -1] > new_solution[0,-1]): 51 | position[random_bird, j] = np.copy(new_solution[0, j]) 52 | return position 53 | 54 | # Function: Update Positions 55 | def update_positions(position, discovery_rate = 0.25, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 56 | updated_position = np.copy(position) 57 | abandoned_nests = math.ceil(discovery_rate*updated_position.shape[0]) + 1 58 | random_bird_j = np.random.randint(position.shape[0], size = 1)[0] 59 | random_bird_k = np.random.randint(position.shape[0], size = 1)[0] 60 | while(random_bird_j == random_bird_k): 61 | random_bird_j = np.random.randint(position.shape[0], size = 1)[0] 62 | nest_list = list(position.argsort()[-(abandoned_nests-1):][::-1][0]) 63 | for i in range(0, updated_position.shape[0]): 64 | for j in range(0, len(nest_list)): 65 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 66 | if(i == nest_list[j] and rand > discovery_rate): 67 | for k in range(0, updated_position.shape[1] - 1): 68 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 69 | updated_position[i,k] = np.clip(updated_position[i,k] + rand*(updated_position[random_bird_j,k] - updated_position[random_bird_k,k]), min_values[k], max_values[k]) 70 | updated_position[i,-1] = target_function(updated_position[i,0:updated_position.shape[1]-1]) 71 | return updated_position 72 | 73 | ############################################################################ 74 | 75 | # CS Function 76 | def cuckoo_search(birds = 3, discovery_rate = 0.25, alpha_value = 0.01, lambda_value = 1.5, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True): 77 | count = 0 78 | position = initial_position(birds, min_values, max_values, target_function) 79 | best_ind = np.copy(position[position[:,-1].argsort()][0,:]) 80 | while (count <= iterations): 81 | if (verbose == True): 82 | print('Iteration = ', count, ' f(x) = ', best_ind[-1]) 83 | for i in range(0, position.shape[0]): 84 | position = replace_bird(position, alpha_value, lambda_value, min_values, max_values, target_function) 85 | position = update_positions(position, discovery_rate, min_values, max_values, target_function) 86 | value = np.copy(position[position[:,-1].argsort()][0,:]) 87 | if (best_ind[-1] > value[-1]): 88 | best_ind = np.copy(position[position[:,-1].argsort()][0,:]) 89 | count = count + 1 90 | return best_ind 91 | 92 | ############################################################################ 93 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/da.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Dragonfly Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | from scipy.special import gamma 18 | 19 | ############################################################################ 20 | 21 | # Function 22 | def target_function(): 23 | return 24 | 25 | ############################################################################ 26 | 27 | # Function: Initialize Variables 28 | def initial_variables(size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 29 | position = np.zeros((size, len(min_values)+1)) 30 | for i in range(0, size): 31 | for j in range(0, len(min_values)): 32 | position[i,j] = random.uniform(min_values[j], max_values[j]) 33 | position[i,-1] = target_function(position[i,:-1]) 34 | return position 35 | 36 | ############################################################################ 37 | 38 | # Function: Distance Calculations 39 | def euclidean_distance(x, y): 40 | distance = 0 41 | for j in range(0, len(x)): 42 | distance = (x[j] - y[j])**2 + distance 43 | return distance**(1/2) 44 | 45 | # Function: Levy Distribution 46 | def levy_flight(beta = 1.5): 47 | beta = beta 48 | r1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 49 | r2 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 50 | sig_num = gamma(1+beta)*np.sin((np.pi*beta)/2.0) 51 | sig_den = gamma((1+beta)/2)*beta*2**((beta-1)/2) 52 | sigma = (sig_num/sig_den)**(1/beta) 53 | levy = (0.01*r1*sigma)/(abs(r2)**(1/beta)) 54 | return levy 55 | 56 | # Function: SAC 57 | def separation_alignment_cohesion(dragonflies, radius, dragon = 0): 58 | dimensions = 0 59 | neighbours = 0 60 | index_list = [] 61 | separation = np.zeros((1, dragonflies.shape[1]-1)) 62 | alignment = np.zeros((1, dragonflies.shape[1]-1)) 63 | cohesion = np.zeros((1, dragonflies.shape[1]-1)) 64 | i = dragon 65 | for j in range(0, dragonflies.shape[0]): 66 | if (i != j): 67 | for k in range(0, dragonflies.shape[1]-1): 68 | x = dragonflies[i,0:dragonflies.shape[1]-1] 69 | y = dragonflies[j,0:dragonflies.shape[1]-1] 70 | nd = euclidean_distance(x, y) 71 | if (nd < radius[0,k]): 72 | dimensions = dimensions + 1 73 | separation[0,k] = separation[0,k] - dragonflies[i,k] - dragonflies[i,k] 74 | alignment [0,k] = alignment [0,k] + dragonflies[j,k] 75 | cohesion [0,k] = cohesion [0,k] + dragonflies[j,k] 76 | if (dimensions == dragonflies.shape[1] - 1): 77 | neighbours = neighbours + 1 78 | index_list.append(j) 79 | if (neighbours > 0): 80 | alignment = alignment/neighbours 81 | cohesion = cohesion/neighbours 82 | for m in range(0, len(index_list)): 83 | for n in range(0, dragonflies.shape[1]-1): 84 | cohesion[0,n] = cohesion[0,n] - dragonflies[index_list[m],n] 85 | return separation, alignment, cohesion, neighbours 86 | 87 | # Function: Update Food 88 | def update_food(dragonflies, radius, food_position, min_values = [-5,-5], max_values = [5,5], dragon = 0, target_function = target_function): 89 | dimensions = 0 90 | i = dragon 91 | x = food_position[0,:-1] 92 | y = dragonflies[i,:-1] 93 | fd = euclidean_distance(x, y) 94 | for k in range(0, dragonflies.shape[1]-1): 95 | if (fd <= radius[0,k]): 96 | dimensions = dimensions + 1 97 | if (dimensions == dragonflies.shape[1] - 1): 98 | for k in range(0, dragonflies.shape[1]-1): 99 | food_position[0,k] = np.clip(food_position[0,k] - dragonflies[i,k], min_values[k], max_values[k]) 100 | else: 101 | food_position[0,k] = 0 102 | food_position[0,-1] = target_function(food_position[0,:-1]) 103 | return food_position, dimensions 104 | 105 | # Function: Update Predator 106 | def update_predator(dragonflies, radius, predator, min_values = [-5,-5], max_values = [5,5], dragon = 0, target_function = target_function): 107 | dimensions = 0 108 | i = dragon 109 | x = predator[0,:-1] 110 | y = dragonflies[i,0:dragonflies.shape[1]-1] 111 | pd = euclidean_distance(x, y) 112 | for k in range(0, dragonflies.shape[1]-1): 113 | if (pd <= radius[0,k]): 114 | dimensions = dimensions + 1 115 | if (dimensions == dragonflies.shape[1]): 116 | for k in range(0, dragonflies.shape[1]-1): 117 | predator[0,k] = np.clip(predator[0,k] + dragonflies[i,k], min_values[k], max_values[k]) 118 | else: 119 | predator[0,k] = 0 120 | predator[0,-1] = target_function(predator[0,0:predator.shape[1]-1]) 121 | return predator 122 | 123 | # Function: Update Search Matrices 124 | def update_da(adjustment_const, weight_inertia, delta_max, dragonflies, best_dragon, radius, food_position, predator, delta_flies, min_values, max_values, target_function): 125 | rand1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 126 | rand2 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 127 | rand3 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 128 | rand4 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 129 | weight_separation = 2*rand1*adjustment_const # Seperation Weight 130 | weight_alignment = 2*rand2*adjustment_const # Alignment Weight 131 | weight_cohesion = 2*rand3*adjustment_const # Cohesion Weight 132 | weight_food = 2*rand4 # Food Attraction Weight 133 | weight_predator = 1*adjustment_const # Enemy distraction Weight 134 | for i in range(0, dragonflies.shape[0]): 135 | separation, alignment, cohesion, neighbours = separation_alignment_cohesion(dragonflies, radius, i) 136 | food_position, dimensions = update_food(dragonflies, radius, food_position, min_values, max_values, i, target_function) 137 | predator = update_predator(dragonflies, radius, predator, min_values, max_values, i, target_function) 138 | if (dimensions > 0): 139 | if (neighbours >= 1): 140 | for j in range(0, len(min_values)): 141 | r1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 142 | r2 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 143 | r3 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 144 | delta_flies[i,j] = np.clip(weight_inertia*delta_flies[i,j] + r1*alignment[0, j] + r2*cohesion[0, j] + r3*separation[0, j], -delta_max[0,j], delta_max[0,j]) 145 | dragonflies[i,j] = dragonflies[i,j] + delta_flies[i,j] 146 | elif(neighbours < 1): 147 | for k in (0, dragonflies.shape[1]-1): 148 | dragonflies[i,k] = dragonflies[i,k] + levy_flight(beta = 1.5) 149 | delta_flies[i,k] = 0 150 | elif(dimensions == 0): 151 | for m in range(0, len(min_values)): 152 | delta_flies[i,m] = np.clip((weight_separation*separation[0,m] + weight_alignment*alignment[0,m] + weight_cohesion*cohesion[0,m] + weight_food*food_position[0,m] + weight_predator*predator[0,m]) + weight_inertia*delta_flies[i,m], -delta_max[0,m], delta_max[0,m]) 153 | dragonflies[i,m] = np.clip(dragonflies[i,m] + delta_flies[i,m], min_values[m], max_values[m]) 154 | dragonflies[i,-1] = target_function(dragonflies[i,:-1]) 155 | for i in range (0, dragonflies.shape[0]): 156 | if (dragonflies[i,-1] < food_position[0,-1]): 157 | for j in range(0, dragonflies.shape[1]): 158 | food_position[0,j] = dragonflies[i,j] 159 | if (dragonflies[i,-1] > predator[0,-1]): 160 | for j in range(0, dragonflies.shape[1]): 161 | predator[0,j] = dragonflies[i,j] 162 | if (food_position[food_position[:,-1].argsort()][0,:][-1] < best_dragon[-1]): 163 | best_dragon = np.copy(food_position[food_position[:,-1].argsort()][0,:]) 164 | else: 165 | for j in range(0, food_position.shape[1]): 166 | food_position[0,j] = best_dragon[j] 167 | return dragonflies, food_position, predator, delta_flies, best_dragon 168 | 169 | ############################################################################ 170 | 171 | # DA Function 172 | def dragonfly_algorithm(size = 3, min_values = [-5,-5], max_values = [5,5], generations = 50, target_function = target_function, verbose = True): 173 | radius = np.zeros((1, len(min_values))) 174 | delta_max = np.zeros((1, len(min_values))) 175 | for j in range(0, len(min_values)): 176 | radius[0,j] = (max_values[j] - min_values[j])/10 177 | delta_max[0,j] = (max_values[j] - min_values[j])/10 178 | dragonflies = initial_variables(size, min_values, max_values, target_function) 179 | delta_flies = initial_variables(size, min_values, max_values, target_function) 180 | predator = initial_variables(1, min_values, max_values, target_function) 181 | food_position = initial_variables(1, min_values, max_values, target_function) 182 | count = 0 183 | for i in range (0, dragonflies.shape[0]): 184 | if (dragonflies[i,-1] < food_position[0,-1]): 185 | for j in range(0, dragonflies.shape[1]): 186 | food_position[0,j] = dragonflies[i,j] 187 | if (dragonflies[i,-1] > predator[0,-1]): 188 | for j in range(0, dragonflies.shape[1]): 189 | predator[0,j] = dragonflies[i,j] 190 | best_dragon = np.copy(food_position[food_position[:,-1].argsort()][0,:]) 191 | while (count <= generations): 192 | if (verbose == True): 193 | print('Generation: ', count, ' f(x) = ', best_dragon[-1]) 194 | for j in range(0, len(min_values)): 195 | radius[0,j] = (max_values[j] - min_values[j])/4 + ((max_values[j] - min_values[j])*(count/generations)*2) 196 | weight_inertia = 0.9 - count*((0.5)/generations) 197 | adjustment_const = 0.1 - count*((0.1)/(generations/2)) 198 | if (adjustment_const < 0): 199 | adjustment_const = 0 200 | dragonflies, food_position, predator, delta_flies, best_dragon = update_da(adjustment_const, weight_inertia, delta_max, dragonflies, best_dragon, radius, food_position, predator, delta_flies, min_values, max_values, target_function) 201 | count = count + 1 202 | return best_dragon 203 | 204 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/de.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Differential Evolution 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_position(n = 3, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | position = np.zeros((n, len(min_values) + 1)) 28 | for i in range(0, n): 29 | for j in range(0, len(min_values)): 30 | position[i,j] = random.uniform(min_values[j], max_values[j]) 31 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 32 | return position 33 | 34 | # Function: Velocity 35 | def velocity(position, best_global, k0 = 0, k1 = 1, k2 = 2, F = 0.9, min_values = [-5,-5], max_values = [5,5], Cr = 0.2, target_function = target_function): 36 | v = np.copy(best_global) 37 | for i in range(0, len(best_global)): 38 | ri = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 39 | if (ri <= Cr): 40 | v[i] = best_global[i] + F*(position[k1, i] - position[k2, i]) 41 | else: 42 | v[i] = position[k0, i] 43 | if (i < len(min_values) and v[i] > max_values[i]): 44 | v[i] = max_values[i] 45 | elif(i < len(min_values) and v[i] < min_values[i]): 46 | v[i] = min_values[i] 47 | v[-1] = target_function(v[0:len(min_values)]) 48 | return v 49 | 50 | ############################################################################ 51 | 52 | # DE Function. DE/Best/1/Bin Scheme. 53 | def differential_evolution(n = 3, min_values = [-5,-5], max_values = [5,5], iterations = 50, F = 0.9, Cr = 0.2, target_function = target_function, verbose = True): 54 | count = 0 55 | position = initial_position(n = n, min_values = min_values, max_values = max_values, target_function = target_function) 56 | best_global = np.copy(position [position [:,-1].argsort()][0,:]) 57 | while (count <= iterations): 58 | if (verbose == True): 59 | print('Iteration = ', count, ' f(x) ', best_global[-1]) 60 | for i in range(0, position.shape[0]): 61 | k1 = int(np.random.randint(position.shape[0], size = 1)) 62 | k2 = int(np.random.randint(position.shape[0], size = 1)) 63 | while k1 == k2: 64 | k1 = int(np.random.randint(position.shape[0], size = 1)) 65 | vi = velocity(position, best_global, i, k1, k2, F, min_values, max_values, Cr, target_function) 66 | if (vi[-1] <= position[i,-1]): 67 | for j in range(0, position.shape[1]): 68 | position[i,j] = vi[j] 69 | if (best_global[-1] > position [position [:,-1].argsort()][0,:][-1]): 70 | best_global = np.copy(position [position [:,-1].argsort()][0,:]) 71 | count = count + 1 72 | return best_global 73 | 74 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/dfo.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Dispersive Flies Optimization 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import os 15 | 16 | ############################################################################ 17 | 18 | # Function 19 | def target_function(): 20 | return 21 | 22 | ############################################################################ 23 | 24 | # Function: Initialize Variables 25 | def initial_flies(swarm_size = 3, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 26 | position = np.zeros((swarm_size, len(min_values)+1)) 27 | for i in range(0, swarm_size): 28 | for j in range(0, len(min_values)): 29 | r = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 30 | position[i,j] = min_values[j] + r*(max_values[j] - min_values[j]) 31 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 32 | return position 33 | 34 | ############################################################################ 35 | 36 | # Function: Update Position 37 | def update_position(position, neighbour_best, swarm_best, min_values = [-5,-5], max_values = [5,5], fly = 0, target_function = target_function): 38 | for j in range(0, position.shape[1] - 1): 39 | r = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 40 | position[fly, j] = np.clip((neighbour_best[j] + r*(swarm_best[j] - position[fly, j])), min_values[j], max_values[j]) 41 | position[fly, -1] = target_function(position[fly, 0:position.shape[1]-1]) 42 | return position 43 | 44 | ############################################################################ 45 | 46 | # DFO Function 47 | def dispersive_fly_optimization(swarm_size = 3, min_values = [-5,-5], max_values = [5,5], generations = 50, dt = 0.2, target_function = target_function, verbose = True): 48 | count = 0 49 | population = initial_flies(swarm_size, min_values, max_values, target_function) 50 | neighbour_best = np.copy(population[population[:,-1].argsort()][0,:]) 51 | swarm_best = np.copy(population[population[:,-1].argsort()][0,:]) 52 | while (count <= generations): 53 | if (verbose == True): 54 | print('Generation: ', count, ' f(x) = ', swarm_best[-1]) 55 | for i in range (0, swarm_size): 56 | population = update_position(population, neighbour_best, swarm_best, min_values, max_values, i, target_function) 57 | r = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 58 | if (r < dt): 59 | for j in range(0, len(min_values)): 60 | r = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 61 | population[i,j] = min_values[j] + r*(max_values[j] - min_values[j]) 62 | population[i,-1] = target_function(population[i,0:population.shape[1]-1]) 63 | neighbour_best = np.copy(population[population[:,-1].argsort()][0,:]) 64 | if (swarm_best[-1] > neighbour_best[-1]): 65 | swarm_best = np.copy(neighbour_best) 66 | count = count + 1 67 | return swarm_best 68 | 69 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/fda.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Flow Direction Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_position(size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | position = np.zeros((size, len(min_values)+1)) 28 | for i in range(0, size): 29 | for j in range(0, len(min_values)): 30 | position[i,j] = random.uniform(min_values[j], max_values[j]) 31 | position[i,-1] = target_function(position[i,:-1]) 32 | return position 33 | 34 | ############################################################################ 35 | 36 | # Function: Create Neighbors 37 | def neighbors(position_a, elite, beta, w_component, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 38 | b_list = [] 39 | for _ in range(0, beta): 40 | position_b = np.zeros((position_a.shape[0], len(min_values)+1)) 41 | for i in range(0, position_a.shape[0]): 42 | for j in range(0, len(min_values)): 43 | ru = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 44 | rn = np.random.normal(0, 1) 45 | ix = random.sample(range(0, position_a.shape[0] - 1), 1)[0] 46 | dt = euclidean_distance(position_a[i, :-1], elite[:-1]) 47 | dl = (ru*position_a[ix, j] - ru*position_a[i,j])*dt*w_component 48 | position_b[i,j] = np.clip(position_a[i,j] + rn*dl, min_values[j], max_values[j]) 49 | position_b[i,-1] = target_function(position_b[i,:-1]) 50 | b_list.append(position_b) 51 | position_b = np.concatenate( b_list, axis = 0 ) 52 | return position_b 53 | 54 | # Function: Elite 55 | def elite_flow(elite, elite_a, elite_b): 56 | if (elite_a[-1] < elite_b[-1] and elite[-1] > elite_a[-1]): 57 | elite = np.copy(elite_a) 58 | elif (elite_b[-1] < elite_a[-1] and elite[-1] > elite_b[-1]): 59 | elite = np.copy(elite_b) 60 | return elite 61 | 62 | # Function: Distance Calculations 63 | def euclidean_distance(x, y): 64 | distance = 0 65 | for j in range(0, len(x)): 66 | distance = (x[j] - y[j])**2 + distance 67 | return distance**(1/2) 68 | 69 | # Function: Updtade Position 70 | def update_position(position_a, position_b, elite, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 71 | for k in range(0, position_b.shape[0], position_a.shape[0]): 72 | candidate = np.copy(position_a) 73 | for i in range(0, position_a.shape[0]): 74 | for j in range(0, len(min_values)): 75 | if (position_b[i+k, -1] < position_a[i, -1]): 76 | rn = np.random.normal(0, 1) 77 | distance = euclidean_distance(position_a[i, :-1], position_b[i+k, :-1]) 78 | slope = (position_a[i, -1] - position_b[i+k, -1])/distance 79 | velocity = rn*slope 80 | candidate[i, j] = np.clip(position_a[i, j] + velocity*(position_a[i, j] - position_b[i+k, j])/distance, min_values[j], max_values[j]) 81 | else: 82 | ix = random.sample(range(0, position_a.shape[0] - 1), 1) 83 | rn = np.random.normal(0, 1) 84 | if (position_a[ix, -1] < position_a[i, -1]): 85 | candidate[i, j] = np.clip(position_a[i, j] + rn*(position_a[ix, j] - position_a[i, j]), min_values[j], max_values[j]) 86 | else: 87 | candidate[i, j] = np.clip(position_a[i, j] + 2*rn*(elite[j] - position_a[i, j]), min_values[j], max_values[j]) 88 | candidate[i, -1] = target_function(candidate[i, :-1]) 89 | if (candidate[i, -1] < position_a[i, -1]): 90 | position_a[i, :] = candidate[i, :] 91 | return position_a 92 | 93 | ############################################################################ 94 | 95 | # FDA Function 96 | def flow_direction_algorithm(size = 5, beta = 8, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True): 97 | count = 1 98 | position_a = initial_position(size, min_values, max_values, target_function) 99 | position_b = initial_position(size*beta, min_values, max_values, target_function) 100 | elite_a = np.copy(position_a[position_a[:,-1].argsort()][0,:]) 101 | elite_b = np.copy(elite_a) 102 | elite = np.copy(elite_a) 103 | while (count <= iterations): 104 | if (verbose == True): 105 | print('Iteration = ', count, ' f(x) = ', elite[-1]) 106 | r1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 107 | r2 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 108 | w_component = ( (1 - count/iterations)**(2*r1) )*(r2*count/iterations)*r2 109 | elite = elite_flow(elite, elite_a, elite_b) 110 | position_b = neighbors(position_a, elite, beta, w_component, min_values, max_values, target_function) 111 | elite_b = np.copy(position_b[position_b[:,-1].argsort()][0,:]) 112 | elite = elite_flow(elite, elite_a, elite_b) 113 | position_a = update_position(position_a, position_b, elite, min_values, max_values, target_function) 114 | elite_a = np.copy(position_a[position_a[:,-1].argsort()][0,:]) 115 | elite = elite_flow(elite, elite_a, elite_b) 116 | count = count + 1 117 | return elite 118 | 119 | ############################################################################ 120 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/firefly_a.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Firefly Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import math 16 | import os 17 | 18 | ############################################################################ 19 | 20 | # Function 21 | def target_function(): 22 | return 23 | 24 | ############################################################################ 25 | 26 | # Function: Initialize Variables 27 | def initial_fireflies(swarm_size = 3, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 28 | position = np.zeros((swarm_size, len(min_values)+1)) 29 | for i in range(0, swarm_size): 30 | for j in range(0, len(min_values)): 31 | position[i,j] = random.uniform(min_values[j], max_values[j]) 32 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 33 | return position 34 | 35 | ############################################################################ 36 | 37 | # Function: Distance Calculations 38 | def euclidean_distance(x, y): 39 | distance = 0 40 | for j in range(0, len(x)): 41 | distance = (x[j] - y[j])**2 + distance 42 | return distance**(1/2) 43 | 44 | ############################################################################ 45 | 46 | # Function: Beta Value 47 | def beta_value(x, y, gama = 1, beta_0 = 1): 48 | rij = euclidean_distance(x, y) 49 | beta = beta_0*math.exp(-gama*(rij)**2) 50 | return beta 51 | 52 | # Function: Ligth Intensity 53 | def ligth_value(light_0, x, y, gama = 1): 54 | rij = euclidean_distance(x, y) 55 | light = light_0*math.exp(-gama*(rij)**2) 56 | return light 57 | 58 | # Function: Update Position 59 | def update_position(position, x, y, alpha_0 = 0.2, beta_0 = 1, gama = 1, firefly = 0, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 60 | for j in range(0, len(x)): 61 | epson = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) - (1/2) 62 | position[firefly, j] = np.clip((x[j] + beta_value(x, y, gama = gama, beta_0 = beta_0)*(y[j] - x[j]) + alpha_0*epson), min_values[j], max_values[j]) 63 | position[firefly, -1] = target_function(position[firefly, 0:position.shape[1]-1]) 64 | return position 65 | 66 | ############################################################################ 67 | 68 | # FA Function 69 | def firefly_algorithm(swarm_size = 3, min_values = [-5,-5], max_values = [5,5], generations = 50, alpha_0 = 0.2, beta_0 = 1, gama = 1, target_function = target_function, verbose = True): 70 | count = 0 71 | position = initial_fireflies(swarm_size = swarm_size, min_values = min_values, max_values = max_values, target_function = target_function) 72 | while (count <= generations): 73 | if (verbose == True): 74 | print('Generation: ', count, ' f(x) = ', position[position[:,-1].argsort()][0,:][-1]) 75 | for i in range (0, swarm_size): 76 | for j in range(0, swarm_size): 77 | if (i != j): 78 | firefly_i = np.copy(position[i, 0:position.shape[1]-1]) 79 | firefly_j = np.copy(position[j, 0:position.shape[1]-1]) 80 | ligth_i = ligth_value(position[i,-1], firefly_i, firefly_j, gama = gama) 81 | ligth_j = ligth_value(position[j,-1], firefly_i, firefly_j, gama = gama) 82 | if (ligth_i > ligth_j): 83 | position = update_position(position, firefly_i, firefly_j, alpha_0, beta_0, gama, i, min_values, max_values, target_function) 84 | count = count + 1 85 | best_firefly = np.copy(position[position[:,-1].argsort()][0,:]) 86 | return best_firefly 87 | 88 | ############################################################################ 89 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/fpa.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Flower Pollination Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | from scipy.special import gamma 17 | 18 | ############################################################################ 19 | 20 | # Function 21 | def target_function(): 22 | return 23 | 24 | ############################################################################ 25 | 26 | # Function: Initialize Variables 27 | def initial_position(flowers = 3, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 28 | position = np.zeros((flowers, len(min_values)+1)) 29 | for i in range(0, flowers): 30 | for j in range(0, len(min_values)): 31 | position[i,j] = random.uniform(min_values[j], max_values[j]) 32 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 33 | return position 34 | 35 | ############################################################################ 36 | 37 | # Function Levy Distribution 38 | def levy_flight(beta = 1.5): 39 | beta = beta 40 | r1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 41 | r2 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 42 | sig_num = gamma(1+beta)*np.sin((np.pi*beta)/2.0) 43 | sig_den = gamma((1+beta)/2)*beta*2**((beta-1)/2) 44 | sigma = (sig_num/sig_den)**(1/beta) 45 | levy = (0.01*r1*sigma)/(abs(r2)**(1/beta)) 46 | return levy 47 | 48 | # Function: Global Pollination 49 | def pollination_global(position, best_global, flower = 0, gama = 0.5, lamb = 1.4, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 50 | x = np.copy(best_global) 51 | for j in range(0, len(min_values)): 52 | x[j] = np.clip((position[flower, j] + gama*levy_flight(lamb)*(position[flower, j] - best_global[j])),min_values[j],max_values[j]) 53 | x[-1] = target_function(x[0:len(min_values)]) 54 | return x 55 | 56 | # Function: Local Pollination 57 | def pollination_local(position, best_global, flower = 0, nb_flower_1 = 0, nb_flower_2 = 1, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 58 | x = np.copy(best_global) 59 | for j in range(0, len(min_values)): 60 | r = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 61 | x[j] = np.clip((position[flower, j] + r*(position[nb_flower_1, j] - position[nb_flower_2, j])),min_values[j],max_values[j]) 62 | x[-1] = target_function(x[0:len(min_values)]) 63 | return x 64 | 65 | ############################################################################ 66 | 67 | # FPA Function 68 | def flower_pollination_algorithm(flowers = 3, min_values = [-5,-5], max_values = [5,5], iterations = 50, gama = 0.5, lamb = 1.4, p = 0.8, target_function = target_function, verbose = True): 69 | count = 0 70 | position = initial_position(flowers, min_values, max_values, target_function) 71 | best_global = np.copy(position[position[:,-1].argsort()][0,:]) 72 | x = np.copy(best_global) 73 | while (count <= iterations): 74 | if (verbose == True): 75 | print('Iteration = ', count, ' f(x) = ', best_global[-1]) 76 | for i in range(0, position.shape[0]): 77 | nb_flower_1 = int(np.random.randint(position.shape[0], size = 1)) 78 | nb_flower_2 = int(np.random.randint(position.shape[0], size = 1)) 79 | while nb_flower_1 == nb_flower_2: 80 | nb_flower_1 = int(np.random.randint(position.shape[0], size = 1)) 81 | r = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 82 | if (r < p): 83 | x = pollination_global(position, best_global, i, gama, lamb, min_values, max_values, target_function) 84 | else: 85 | x = pollination_local(position, best_global, i, nb_flower_1, nb_flower_2, min_values, max_values, target_function) 86 | if (x[-1] <= position[i,-1]): 87 | for j in range(0, position.shape[1]): 88 | position[i,j] = x[j] 89 | value = np.copy(position[position[:,-1].argsort()][0,:]) 90 | if (best_global[-1] > value[-1]): 91 | best_global = np.copy(value) 92 | count = count + 1 93 | return best_global 94 | 95 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/ga.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Genetic Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_population(population_size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | population = np.zeros((population_size, len(min_values) + 1)) 28 | for i in range(0, population_size): 29 | for j in range(0, len(min_values)): 30 | population[i,j] = random.uniform(min_values[j], max_values[j]) 31 | population[i,-1] = target_function(population[i,0:population.shape[1]-1]) 32 | return population 33 | 34 | ############################################################################ 35 | 36 | # Function: Fitness 37 | def fitness_function(population): 38 | fitness = np.zeros((population.shape[0], 2)) 39 | for i in range(0, fitness.shape[0]): 40 | fitness[i,0] = 1/(1+ population[i,-1] + abs(population[:,-1].min())) 41 | fit_sum = fitness[:,0].sum() 42 | fitness[0,1] = fitness[0,0] 43 | for i in range(1, fitness.shape[0]): 44 | fitness[i,1] = (fitness[i,0] + fitness[i-1,1]) 45 | for i in range(0, fitness.shape[0]): 46 | fitness[i,1] = fitness[i,1]/fit_sum 47 | return fitness 48 | 49 | # Function: Selection 50 | def roulette_wheel(fitness): 51 | ix = 0 52 | random = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 53 | for i in range(0, fitness.shape[0]): 54 | if (random <= fitness[i, 1]): 55 | ix = i 56 | break 57 | return ix 58 | 59 | # Function: Offspring 60 | def breeding(population, fitness, min_values = [-5,-5], max_values = [5,5], mu = 1, elite = 0, target_function = target_function): 61 | offspring = np.copy(population) 62 | b_offspring = 0 63 | if (elite > 0): 64 | preserve = np.copy(population[population[:,-1].argsort()]) 65 | for i in range(0, elite): 66 | for j in range(0, offspring.shape[1]): 67 | offspring[i,j] = preserve[i,j] 68 | for i in range (elite, offspring.shape[0]): 69 | parent_1, parent_2 = roulette_wheel(fitness), roulette_wheel(fitness) 70 | while parent_1 == parent_2: 71 | parent_2 = random.sample(range(0, len(population) - 1), 1)[0] 72 | for j in range(0, offspring.shape[1] - 1): 73 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 74 | rand_b = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 75 | rand_c = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 76 | if (rand <= 0.5): 77 | b_offspring = 2*(rand_b) 78 | b_offspring = b_offspring**(1/(mu + 1)) 79 | elif (rand > 0.5): 80 | b_offspring = 1/(2*(1 - rand_b)) 81 | b_offspring = b_offspring**(1/(mu + 1)) 82 | if (rand_c >= 0.5): 83 | offspring[i,j] = np.clip(((1 + b_offspring)*population[parent_1, j] + (1 - b_offspring)*population[parent_2, j])/2, min_values[j], max_values[j]) 84 | else: 85 | offspring[i,j] = np.clip(((1 - b_offspring)*population[parent_1, j] + (1 + b_offspring)*population[parent_2, j])/2, min_values[j], max_values[j]) 86 | offspring[i,-1] = target_function(offspring[i,0:offspring.shape[1]-1]) 87 | return offspring 88 | 89 | # Function: Mutation 90 | def mutation(offspring, mutation_rate = 0.1, eta = 1, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 91 | d_mutation = 0 92 | for i in range (0, offspring.shape[0]): 93 | for j in range(0, offspring.shape[1] - 1): 94 | probability = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 95 | if (probability < mutation_rate): 96 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 97 | rand_d = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 98 | if (rand <= 0.5): 99 | d_mutation = 2*(rand_d) 100 | d_mutation = d_mutation**(1/(eta + 1)) - 1 101 | elif (rand > 0.5): 102 | d_mutation = 2*(1 - rand_d) 103 | d_mutation = 1 - d_mutation**(1/(eta + 1)) 104 | offspring[i,j] = np.clip((offspring[i,j] + d_mutation), min_values[j], max_values[j]) 105 | offspring[i,-1] = target_function(offspring[i,0:offspring.shape[1]-1]) 106 | return offspring 107 | 108 | ############################################################################ 109 | 110 | # GA Function 111 | def genetic_algorithm(population_size = 5, mutation_rate = 0.1, elite = 0, min_values = [-5,-5], max_values = [5,5], eta = 1, mu = 1, generations = 50, target_function = target_function, verbose = True): 112 | count = 0 113 | population = initial_population(population_size, min_values, max_values, target_function) 114 | fitness = fitness_function(population) 115 | elite_ind = np.copy(population[population[:,-1].argsort()][0,:]) 116 | while (count <= generations): 117 | if (verbose == True): 118 | print('Generation = ', count, ' f(x) = ', elite_ind[-1]) 119 | offspring = breeding(population, fitness, min_values, max_values, mu, elite, target_function) 120 | population = mutation(offspring, mutation_rate, eta, min_values, max_values, target_function) 121 | fitness = fitness_function(population) 122 | value = np.copy(population[population[:,-1].argsort()][0,:]) 123 | if(elite_ind[-1] > value[-1]): 124 | elite_ind = np.copy(value) 125 | count = count + 1 126 | return elite_ind 127 | 128 | ############################################################################ 129 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/goa.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Grasshopper Optimization Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | 16 | ############################################################################ 17 | 18 | # Function 19 | def target_function(): 20 | return 21 | 22 | ############################################################################ 23 | 24 | # Function: Initialize Variables 25 | def initial_position(grasshoppers = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 26 | position = np.zeros((grasshoppers, len(min_values)+1)) 27 | for i in range(0, grasshoppers): 28 | for j in range(0, len(min_values)): 29 | position[i,j] = random.uniform(min_values[j], max_values[j]) 30 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 31 | return position 32 | 33 | ############################################################################ 34 | 35 | # Function: S 36 | def s_function(r, F, L): 37 | s = F*np.exp(-r/L) - np.exp(-r) 38 | return s 39 | 40 | # Function: Distance Matrix 41 | def build_distance_matrix(position): 42 | a = position[:,:-1] 43 | b = a.reshape(np.prod(a.shape[:-1]), 1, a.shape[-1]) 44 | return np.sqrt(np.einsum('ijk,ijk->ij', b - a, b - a)).squeeze() 45 | 46 | # Function: Update Position 47 | def update_position(position, best_position, min_values, max_values, C, F, L, target_function): 48 | sum_grass = 0 49 | distance_matrix = build_distance_matrix(position) 50 | distance_matrix = 2*(distance_matrix - np.min(distance_matrix))/(np.ptp(distance_matrix)+0.00000001) + 1 51 | np.fill_diagonal(distance_matrix , 0) 52 | for i in range(0, position.shape[0]): 53 | for j in range(0, len(min_values)): 54 | for k in range(0, position.shape[0]): 55 | if (k != i): 56 | sum_grass = sum_grass + C * ((max_values[j] - min_values[j])/2) * s_function(distance_matrix[k, i], F, L) * ((position[k, j] - position[i, j])/distance_matrix[k, i]) 57 | position[i, j] = np.clip(C*sum_grass + best_position[0, j], min_values[j], max_values[j]) 58 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 59 | return position 60 | 61 | ############################################################################ 62 | 63 | # GOA Function 64 | def grasshopper_optimization_algorithm(grasshoppers = 5, min_values = [-5,-5], max_values = [5,5], c_min = 0.00004, c_max = 1, iterations = 1000, F = 0.5, L = 1.5, target_function = target_function, verbose = True): 65 | count = 0 66 | position = initial_position(grasshoppers, min_values, max_values, target_function) 67 | best_position = np.copy(position[np.argmin(position[:,-1]),:].reshape(1,-1)) 68 | while (count <= iterations): 69 | if (verbose == True): 70 | print('Iteration = ', count, ' f(x) = ', best_position[0, -1]) 71 | C = c_max - count*( (c_max - c_min)/iterations) 72 | position = update_position(position, best_position, min_values, max_values, C, F, L, target_function = target_function) 73 | if (np.amin(position[:,-1]) < best_position[0,-1]): 74 | best_position = np.copy(position[np.argmin(position[:,-1]),:].reshape(1,-1)) 75 | count = count + 1 76 | return best_position 77 | 78 | ############################################################################ 79 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/gsa.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Gravitational Search Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import math 15 | import random 16 | import os 17 | 18 | ############################################################################ 19 | 20 | # Function 21 | def target_function(): 22 | return 23 | 24 | ############################################################################ 25 | 26 | # Function: Initialize Variables 27 | def initial_position(swarm_size = 3, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 28 | position = np.zeros((swarm_size, len(min_values)+1)) 29 | for i in range(0, swarm_size): 30 | for j in range(0, len(min_values)): 31 | position[i,j] = random.uniform(min_values[j], max_values[j]) 32 | position[i,-1] = target_function(position[i,:-1]) 33 | return position 34 | 35 | ############################################################################ 36 | 37 | # Function: Build Distance Matrix 38 | def build_distance_matrix(coordinates): 39 | a = coordinates 40 | b = a.reshape(np.prod(a.shape[:-1]), 1, a.shape[-1]) 41 | return np.sqrt(np.einsum('ijk,ijk->ij', b - a, b - a)).squeeze() 42 | 43 | ############################################################################ 44 | 45 | # Function: Force Calculation 46 | def force_acting(position, mass_a, mass_p, g_const, k_best): 47 | eps = 2.2204e-16 48 | r_ij = build_distance_matrix(position) 49 | f_i = np.zeros((position.shape[0], position.shape[1]-1)) 50 | for d in range(0, position.shape[1]-1): 51 | f_ij = np.zeros((position.shape[0], position.shape[0])) 52 | for i in range(0, f_ij.shape[0]): 53 | for j in range(0, f_ij.shape[1]): 54 | if (i != j): 55 | f_ij[i,j] = g_const*( ( (mass_p[i]*mass_a[j])/(r_ij[i,j] + eps) ) * (position[j, d] - position[i, d]) ) 56 | f_ij[j,i] = f_ij[i,j] 57 | for i in range(0, f_i.shape[0]): 58 | for j in range(0, k_best): 59 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 60 | f_i[i, d] = f_i[i, d] + rand* f_ij[i,j] 61 | return f_i 62 | 63 | # Function: Update Mass 64 | def update_mass(position, best_t, worst_t): 65 | mass = np.zeros((position.shape[0], 1)) 66 | for i in range(0, position.shape[0]): 67 | mass[i, 0] = (position[i,-1] - worst_t[-1])/(best_t[-1] - worst_t[-1]) 68 | mass = mass/np.sum(mass) 69 | return mass 70 | 71 | # Function: Updtade Velocity 72 | def update_velocity(velocity, accelaration): 73 | new_velocity = np.copy(velocity) 74 | for i in range(0, velocity.shape[0]): 75 | for j in range(0, velocity.shape[1]): 76 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 77 | new_velocity[i,j] = rand*velocity[i,j] + accelaration[i,j] 78 | return new_velocity 79 | 80 | # Function: Updtade Position 81 | def update_position(position, velocity, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 82 | new_position = np.copy(position) 83 | for i in range(0, position.shape[0]): 84 | for j in range(0, position.shape[1] - 1): 85 | new_position[i,j] = np.clip((position[i,j] + velocity[i,j]), min_values[j], max_values[j]) 86 | new_position[i,-1] = target_function(new_position[i,:-1]) 87 | if (new_position[i,-1] < position[i,-1]): 88 | position[i,:] = np.copy(new_position[i,:]) 89 | return position 90 | 91 | ############################################################################ 92 | 93 | # GSA Function 94 | def gravitational_search_algorithm(swarm_size = 5, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True): 95 | count = 0 96 | position = initial_position(swarm_size, min_values, max_values, target_function) 97 | velocity = np.zeros((position.shape[0], len(min_values))) 98 | best_global = np.copy(position[position[:,-1].argsort()][ 0,:]) 99 | best_t = np.copy(best_global) 100 | worst_t = np.copy(position[position[:,-1].argsort()][-1,:]) 101 | while (count <= iterations): 102 | if (verbose == True): 103 | print('Iteration = ', count, ' f(x) = ', best_global[-1]) 104 | g_const = 100*math.exp(-20*(count/iterations)) 105 | mass = update_mass(position, best_t, worst_t) 106 | k_best = position.shape[0] - (position.shape[0] * (count/iterations)) 107 | force = force_acting(position, mass, mass, g_const, np.clip(int(k_best), 1, position.shape[0])) 108 | accelaration = np.nan_to_num(force/mass) 109 | velocity = update_velocity(velocity, accelaration) 110 | position = update_position(position, velocity, min_values, max_values, target_function) 111 | best_t = np.copy(position[position[:,-1].argsort()][ 0,:]) 112 | worst_t = np.copy(position[position[:,-1].argsort()][-1,:]) 113 | if (best_global[-1] > best_t[-1]): 114 | best_global = np.copy(best_t) 115 | count = count + 1 116 | return best_global 117 | 118 | ############################################################################ 119 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/gwo.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Grey Wolf Optimizer 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_position(pack_size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | position = np.zeros((pack_size, len(min_values)+1)) 28 | for i in range(0, pack_size): 29 | for j in range(0, len(min_values)): 30 | position[i,j] = random.uniform(min_values[j], max_values[j]) 31 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 32 | return position 33 | 34 | ############################################################################ 35 | 36 | # Function: Initialize Alpha 37 | def alpha_position(dimension = 2, target_function = target_function): 38 | alpha = np.zeros((1, dimension + 1)) 39 | for j in range(0, dimension): 40 | alpha[0,j] = 0.0 41 | alpha[0,-1] = target_function(alpha[0,0:alpha.shape[1]-1]) 42 | return alpha 43 | 44 | # Function: Initialize Beta 45 | def beta_position(dimension = 2, target_function = target_function): 46 | beta = np.zeros((1, dimension + 1)) 47 | for j in range(0, dimension): 48 | beta[0,j] = 0.0 49 | beta[0,-1] = target_function(beta[0,0:beta.shape[1]-1]) 50 | return beta 51 | 52 | # Function: Initialize Delta 53 | def delta_position(dimension = 2, target_function = target_function): 54 | delta = np.zeros((1, dimension + 1)) 55 | for j in range(0, dimension): 56 | delta[0,j] = 0.0 57 | delta[0,-1] = target_function(delta[0,0:delta.shape[1]-1]) 58 | return delta 59 | 60 | # Function: Updtade Pack by Fitness 61 | def update_pack(position, alpha, beta, delta): 62 | updated_position = np.copy(position) 63 | for i in range(0, position.shape[0]): 64 | if (updated_position[i,-1] < alpha[0,-1]): 65 | alpha[0,:] = np.copy(updated_position[i,:]) 66 | if (updated_position[i,-1] > alpha[0,-1] and updated_position[i,-1] < beta[0,-1]): 67 | beta[0,:] = np.copy(updated_position[i,:]) 68 | if (updated_position[i,-1] > alpha[0,-1] and updated_position[i,-1] > beta[0,-1] and updated_position[i,-1] < delta[0,-1]): 69 | delta[0,:] = np.copy(updated_position[i,:]) 70 | return alpha, beta, delta 71 | 72 | # Function: Updtade Position 73 | def update_position(position, alpha, beta, delta, a_linear_component = 2, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 74 | updated_position = np.copy(position) 75 | for i in range(0, updated_position.shape[0]): 76 | for j in range (0, len(min_values)): 77 | r1_alpha = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 78 | r2_alpha = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 79 | a_alpha = 2*a_linear_component*r1_alpha - a_linear_component 80 | c_alpha = 2*r2_alpha 81 | distance_alpha = abs(c_alpha*alpha[0,j] - position[i,j]) 82 | x1 = alpha[0,j] - a_alpha*distance_alpha 83 | r1_beta = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 84 | r2_beta = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 85 | a_beta = 2*a_linear_component*r1_beta - a_linear_component 86 | c_beta = 2*r2_beta 87 | distance_beta = abs(c_beta*beta[0,j] - position[i,j]) 88 | x2 = beta[0,j] - a_beta*distance_beta 89 | r1_delta = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 90 | r2_delta = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 91 | a_delta = 2*a_linear_component*r1_delta - a_linear_component 92 | c_delta = 2*r2_delta 93 | distance_delta = abs(c_delta*delta[0,j] - position[i,j]) 94 | x3 = delta[0,j] - a_delta*distance_delta 95 | updated_position[i,j] = np.clip(((x1 + x2 + x3)/3),min_values[j],max_values[j]) 96 | updated_position[i,-1] = target_function(updated_position[i,0:updated_position.shape[1]-1]) 97 | return updated_position 98 | 99 | ############################################################################ 100 | 101 | # GWO Function 102 | def grey_wolf_optimizer(pack_size = 5, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True): 103 | count = 0 104 | alpha = alpha_position(dimension = len(min_values), target_function = target_function) 105 | beta = beta_position(dimension = len(min_values), target_function = target_function) 106 | delta = delta_position(dimension = len(min_values), target_function = target_function) 107 | position = initial_position(pack_size = pack_size, min_values = min_values, max_values = max_values, target_function = target_function) 108 | while (count <= iterations): 109 | if (verbose == True): 110 | print('Iteration = ', count, ' f(x) = ', alpha[0][-1]) 111 | a_linear_component = 2 - count*(2/iterations) 112 | alpha, beta, delta = update_pack(position, alpha, beta, delta) 113 | position = update_position(position, alpha, beta, delta, a_linear_component = a_linear_component, min_values = min_values, max_values = max_values, target_function = target_function) 114 | count = count + 1 115 | return alpha 116 | 117 | ############################################################################ 118 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/hho.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Harris Hawks Optimization 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | from scipy.special import gamma 18 | 19 | ############################################################################ 20 | 21 | # Function 22 | def target_function(): 23 | return 24 | 25 | ############################################################################ 26 | 27 | # Function: Initialize Variables 28 | def initial_position(hawks = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 29 | position = np.zeros((hawks, len(min_values)+1)) 30 | for i in range(0, hawks): 31 | for j in range(0, len(min_values)): 32 | position[i,j] = random.uniform(min_values[j], max_values[j]) 33 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 34 | return position 35 | 36 | ############################################################################ 37 | 38 | # Function: Levy Distribution Vector 39 | def levy_flight(dimensions, beta = 1.5): 40 | levy = np.zeros((1, dimensions)) 41 | for j in range(0, levy.shape[1]): 42 | beta = beta 43 | r1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 44 | r2 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 45 | sig_num = gamma(1+beta)*np.sin((np.pi*beta)/2.0) 46 | sig_den = gamma((1+beta)/2)*beta*2**((beta-1)/2) 47 | sigma = (sig_num/sig_den)**(1/beta) 48 | levy[0, j] = (0.01*r1*sigma)/(abs(r2)**(1/beta)) 49 | return levy[0] 50 | 51 | # Function: Updtade Rabbit Position by Fitness 52 | def update_rabbit_position(position_h, position_r): 53 | for i in range(0, position_h.shape[0]): 54 | if (position_h[i,-1] < position_r[-1]): 55 | position_r = np.copy(position_h[i, :]) 56 | return position_r 57 | 58 | # Function: Updtade Hawks Position 59 | def update_hawks_position(position_h, position_r, e_r_factor, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 60 | for i in range(0, position_h.shape[0]): 61 | escaping_energy = e_r_factor * (2*(int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1)) -1) 62 | if abs(escaping_energy) >= 1: 63 | rand_1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 64 | idx = random.choice(list(range(0, position_h.shape[1]))) 65 | hawk = position_h[idx, :] 66 | if (rand_1 < 0.5): 67 | a = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 68 | b = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 69 | position_h[i, :-1] = hawk[:-1] - a * abs(hawk[:-1] - 2 * b * position_h[i, :-1]) 70 | elif (rand_1 >= 0.5): 71 | c = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 72 | d = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 73 | position_h[i, :-1] = (position_r[:-1] - position_h[i, :-1].mean(0)) - c * (np.asarray(max_values) - np.asarray(min_values)) * d + np.asarray(min_values) 74 | elif abs(escaping_energy) < 1: 75 | rand_2 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 76 | if (rand_2 >= 0.5 and abs(escaping_energy) < 0.5): # Hard Besiege 77 | position_h[i, :-1] = (position_r[:-1]) - escaping_energy * abs(position_r[:-1] - position_h[i, :-1]) 78 | if (rand_2 >= 0.5 and abs(escaping_energy) >= 0.5): # Soft Besiege 79 | e = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 80 | jump_strength = 2 * (1 - e) 81 | position_h[i, :-1] = (position_r[:-1] - position_h[i, :-1]) - escaping_energy * abs(jump_strength * position_r[:-1] - position_h[i, :-1]) 82 | if (rand_2 < 0.5 and abs(escaping_energy) >= 0.5): # Soft Besiege 83 | f = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 84 | jump_strength = 2 * (1 - f) 85 | x1 = position_r[:-1] - escaping_energy * abs(jump_strength * position_r[:-1] - position_h[i, :-1]) 86 | for j in range (0, len(min_values)): 87 | x1[j] = np.clip(x1[j], min_values[j], max_values[j]) 88 | t_x1 = target_function(x1) 89 | if (t_x1 < position_h[i, -1]): 90 | position_h[i, :-1] = np.copy(x1) 91 | position_h[i, -1] = t_x1 92 | else: 93 | x2 = position_r[:-1] - escaping_energy* abs(jump_strength * position_r[:-1] - position_h[i, :-1])+ np.multiply(np.random.randn(len(min_values)), levy_flight(len(min_values), 1.5)) 94 | for j in range (0, len(min_values)): 95 | x2[j] = np.clip(x2[j], min_values[j], max_values[j]) 96 | t_x2 = target_function(x2) 97 | if (t_x2 < position_h[i, -1]): 98 | position_h[i, :-1] = np.copy(x2) 99 | position_h[i, -1] = t_x2 100 | if (rand_2 < 0.5 and abs(escaping_energy) < 0.5): # Hard besiege 101 | g = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 102 | jump_strength = 2 * (1 -g) 103 | x1 = position_r[:-1] - escaping_energy * abs(jump_strength * position_r[:-1] - position_h[i, :-1].mean(0)) 104 | for j in range (0, len(min_values)): 105 | x1[j] = np.clip(x1[j], min_values[j], max_values[j]) 106 | t_x1 = target_function(x1) 107 | if (t_x1 < position_h[i, -1]): 108 | position_h[i, :-1] = np.copy(x1) 109 | position_h[i, -1] = t_x1 110 | else: 111 | x2 = position_r[:-1] - escaping_energy * abs(jump_strength * position_r[:-1] - position_h[i, :-1].mean(0)) + np.multiply(np.random.randn(len(min_values)), levy_flight(len(min_values), 1.5)) 112 | for j in range (0, len(min_values)): 113 | x2[j] = np.clip(x2[j], min_values[j], max_values[j]) 114 | t_x2 = target_function(x2) 115 | if (t_x2 < position_h[i, -1]): 116 | position_h[i, :-1] = np.copy(x2) 117 | position_h[i, -1] = t_x2 118 | return position_h 119 | 120 | ############################################################################ 121 | 122 | # HHO Function 123 | def harris_hawks_optimization(hawks = 5, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True): 124 | count = 0 125 | position_h = initial_position(hawks = hawks, min_values = min_values, max_values = max_values, target_function = target_function) 126 | position_r = np.copy(position_h[0, :]) 127 | while (count <= iterations): 128 | if (verbose == True): 129 | print('Iteration = ', count, ' f(x) = ', position_r[-1]) 130 | position_r = update_rabbit_position(position_h, position_r) 131 | e_r_factor = 2 * (1 - (count / iterations)) 132 | position_h = update_hawks_position(position_h, position_r, e_r_factor, min_values, max_values, target_function) 133 | count = count + 1 134 | return position_r 135 | 136 | ############################################################################ 137 | 138 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/i_gwo.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Improved Grey Wolf Optimizer 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_position(pack_size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | position = np.zeros((pack_size, len(min_values)+1)) 28 | for i in range(0, pack_size): 29 | for j in range(0, len(min_values)): 30 | position[i,j] = random.uniform(min_values[j], max_values[j]) 31 | position[i,-1] = target_function(position[i,:-1]) 32 | return position 33 | 34 | ############################################################################ 35 | 36 | # Function: Initialize Alpha 37 | def alpha_position(dimension = 2, target_function = target_function): 38 | alpha = np.zeros((1, dimension + 1)) 39 | for j in range(0, dimension): 40 | alpha[0,j] = 0.0 41 | alpha[0,-1] = target_function(alpha[0,0:alpha.shape[1]-1]) 42 | return alpha 43 | 44 | # Function: Initialize Beta 45 | def beta_position(dimension = 2, target_function = target_function): 46 | beta = np.zeros((1, dimension + 1)) 47 | for j in range(0, dimension): 48 | beta[0,j] = 0.0 49 | beta[0,-1] = target_function(beta[0,0:beta.shape[1]-1]) 50 | return beta 51 | 52 | # Function: Initialize Delta 53 | def delta_position(dimension = 2, target_function = target_function): 54 | delta = np.zeros((1, dimension + 1)) 55 | for j in range(0, dimension): 56 | delta[0,j] = 0.0 57 | delta[0,-1] = target_function(delta[0,0:delta.shape[1]-1]) 58 | return delta 59 | 60 | # Function: Updtade Pack by Fitness 61 | def update_pack(position, alpha, beta, delta): 62 | updated_position = np.copy(position) 63 | for i in range(0, position.shape[0]): 64 | if (updated_position[i,-1] < alpha[0,-1]): 65 | alpha[0,:] = np.copy(updated_position[i,:]) 66 | if (updated_position[i,-1] > alpha[0,-1] and updated_position[i,-1] < beta[0,-1]): 67 | beta[0,:] = np.copy(updated_position[i,:]) 68 | if (updated_position[i,-1] > alpha[0,-1] and updated_position[i,-1] > beta[0,-1] and updated_position[i,-1] < delta[0,-1]): 69 | delta[0,:] = np.copy(updated_position[i,:]) 70 | return alpha, beta, delta 71 | 72 | # Function: Updtade Position 73 | def update_position(position, alpha, beta, delta, a_linear_component = 2, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 74 | updated_position = np.copy(position) 75 | for i in range(0, updated_position.shape[0]): 76 | for j in range (0, len(min_values)): 77 | r1_alpha = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 78 | r2_alpha = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 79 | a_alpha = 2*a_linear_component*r1_alpha - a_linear_component 80 | c_alpha = 2*r2_alpha 81 | distance_alpha = abs(c_alpha*alpha[0,j] - position[i,j]) 82 | x1 = alpha[0,j] - a_alpha*distance_alpha 83 | r1_beta = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 84 | r2_beta = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 85 | a_beta = 2*a_linear_component*r1_beta - a_linear_component 86 | c_beta = 2*r2_beta 87 | distance_beta = abs(c_beta*beta[0,j] - position[i,j]) 88 | x2 = beta[0,j] - a_beta*distance_beta 89 | r1_delta = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 90 | r2_delta = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 91 | a_delta = 2*a_linear_component*r1_delta - a_linear_component 92 | c_delta = 2*r2_delta 93 | distance_delta = abs(c_delta*delta[0,j] - position[i,j]) 94 | x3 = delta[0,j] - a_delta*distance_delta 95 | updated_position[i,j] = np.clip(((x1 + x2 + x3)/3), min_values[j], max_values[j]) 96 | updated_position[i,-1] = target_function(updated_position[i,:-1]) 97 | return updated_position 98 | 99 | ############################################################################ 100 | 101 | # Function: Distance Calculations 102 | def euclidean_distance(x, y): 103 | distance = 0 104 | for j in range(0, len(x)): 105 | distance = (x[j] - y[j])**2 + distance 106 | return distance**(1/2) 107 | 108 | # Function: Build Distance Matrix 109 | def build_distance_matrix(coordinates): 110 | a = coordinates 111 | b = a.reshape(np.prod(a.shape[:-1]), 1, a.shape[-1]) 112 | return np.sqrt(np.einsum('ijk,ijk->ij', b - a, b - a)).squeeze() 113 | 114 | # Function: Improve Position 115 | def improve_position(position, updt_position, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 116 | improve_position = np.copy(position) 117 | dist_matrix = build_distance_matrix(position[:,:-1]) 118 | for i in range(0, position.shape[0]): 119 | dist = euclidean_distance(position[i, :-1], updt_position[i, :-1]) 120 | idx = [k for k in range(0, dist_matrix[i,:].shape[0]) if dist_matrix[i, k] <= dist] 121 | for j in range(0, len(min_values)): 122 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 123 | ix_1 = random.sample(idx, 1)[0] 124 | ix_2 = random.sample(range(0, position.shape[0] - 1), 1)[0] 125 | improve_position[i, j] = np.clip(improve_position[i, j] + rand*(position[ix_1, j] - position[ix_2, j]), min_values[j], max_values[j]) 126 | improve_position[i,-1] = target_function(improve_position[i,:-1]) 127 | min_position = min(position[i,-1], updt_position[i,-1], improve_position[i,-1]) 128 | if (updt_position[i,-1] == min_position): 129 | improve_position[i,:] = np.copy(updt_position[i,:]) 130 | elif (position[i,-1] == min_position): 131 | improve_position[i,:] = np.copy(position[i,:]) 132 | return improve_position 133 | 134 | ############################################################################ 135 | 136 | # iGWO Function 137 | def improved_grey_wolf_optimizer(pack_size = 5, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True): 138 | count = 0 139 | alpha = alpha_position(dimension = len(min_values), target_function = target_function) 140 | beta = beta_position(dimension = len(min_values), target_function = target_function) 141 | delta = delta_position(dimension = len(min_values), target_function = target_function) 142 | position = initial_position(pack_size, min_values, max_values, target_function) 143 | while (count <= iterations): 144 | if (verbose == True): 145 | print('Iteration = ', count, ' f(x) = ', alpha[0][-1]) 146 | a_linear_component = 2 - count*(2/iterations) 147 | alpha, beta, delta = update_pack(position, alpha, beta, delta) 148 | updt_position = update_position(position, alpha, beta, delta, a_linear_component, min_values, max_values, target_function) 149 | position = improve_position(position, updt_position, min_values, max_values, target_function) 150 | count = count + 1 151 | return alpha 152 | 153 | ############################################################################ 154 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/i_woa.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Improved Whale Optimization Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import math 15 | import random 16 | import os 17 | 18 | ############################################################################ 19 | 20 | # Function 21 | def target_function(): 22 | return 23 | 24 | ############################################################################ 25 | 26 | # Function: Initialize Variables 27 | def initial_position(hunting_party = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 28 | position = np.zeros((hunting_party, len(min_values)+1)) 29 | for i in range(0, hunting_party): 30 | for j in range(0, len(min_values)): 31 | position[i,j] = random.uniform(min_values[j], max_values[j]) 32 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 33 | return position 34 | 35 | ############################################################################ 36 | 37 | # Function: Initialize Alpha 38 | def leader_position(dimension = 2, target_function = target_function): 39 | leader = np.zeros((1, dimension+1)) 40 | for j in range(0, dimension): 41 | leader[0,j] = 0.0 42 | leader[0,-1] = target_function(leader[0,0:leader.shape[1]-1]) 43 | return leader 44 | 45 | # Function: Updtade Leader by Fitness 46 | def update_leader(position, leader): 47 | for i in range(0, position.shape[0]): 48 | if (leader[0,-1] > position[i,-1]): 49 | for j in range(0, position.shape[1]): 50 | leader[0,j] = position[i,j] 51 | return leader 52 | 53 | # Function: Updtade Position 54 | def update_position(position, leader, a_linear_component = 2, b_linear_component = 1, spiral_param = 1, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 55 | for i in range(0, position.shape[0]): 56 | r1_leader = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 57 | r2_leader = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 58 | a_leader = 2*a_linear_component*r1_leader - a_linear_component 59 | c_leader = 2*r2_leader 60 | p = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 61 | for j in range (0, len(min_values)): 62 | if (p < 0.5): 63 | if (abs(a_leader) >= 1): 64 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 65 | rand_leader_index = math.floor(position.shape[0]*rand); 66 | x_rand = position[rand_leader_index, :] 67 | distance_x_rand = abs(c_leader*x_rand[j] - position[i,j]) 68 | position[i,j] = np.clip( x_rand[j] - a_leader*distance_x_rand, min_values[j], max_values[j]) 69 | elif (abs(a_leader) < 1): 70 | distance_leader = abs(c_leader*leader[0,j] - position[i,j]) 71 | position[i,j] = np.clip(leader[0,j] - a_leader*distance_leader, min_values[j], max_values[j]) 72 | elif (p >= 0.5): 73 | distance_Leader = abs(leader[0,j] - position[i,j]) 74 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 75 | m_param = (b_linear_component - 1)*rand + 1 76 | position[i,j] = np.clip( (distance_Leader*math.exp(spiral_param*m_param)*math.cos(m_param*2*math.pi) + leader[0,j]), min_values[j], max_values[j]) 77 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 78 | return position 79 | 80 | ############################################################################ 81 | 82 | # Function: Fitness 83 | def fitness_function(position): 84 | fitness = np.zeros((position.shape[0], 2)) 85 | for i in range(0, fitness.shape[0]): 86 | fitness[i,0] = 1/(1+ position[i,-1] + abs(position[:,-1].min())) 87 | fit_sum = fitness[:,0].sum() 88 | fitness[0,1] = fitness[0,0] 89 | for i in range(1, fitness.shape[0]): 90 | fitness[i,1] = (fitness[i,0] + fitness[i-1,1]) 91 | for i in range(0, fitness.shape[0]): 92 | fitness[i,1] = fitness[i,1]/fit_sum 93 | return fitness 94 | 95 | # Function: Selection 96 | def roulette_wheel(fitness): 97 | ix = 0 98 | random = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 99 | for i in range(0, fitness.shape[0]): 100 | if (random <= fitness[i, 1]): 101 | ix = i 102 | break 103 | return ix 104 | 105 | # Function: Offspring 106 | def breeding(position, fitness, min_values = [-5,-5], max_values = [5,5], mu = 1, target_function = target_function): 107 | offspring = np.copy(position) 108 | for i in range (0, offspring.shape[0]): 109 | parent_1, parent_2 = roulette_wheel(fitness), roulette_wheel(fitness) 110 | while parent_1 == parent_2: 111 | parent_2 = random.sample(range(0, len(position) - 1), 1)[0] 112 | for j in range(0, offspring.shape[1] - 1): 113 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 114 | rand_b = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 115 | rand_c = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 116 | if (rand <= 0.5): 117 | b_offspring = 2*(rand_b) 118 | b_offspring = b_offspring**(1/(mu + 1)) 119 | elif (rand > 0.5): 120 | b_offspring = 1/(2*(1 - rand_b)) 121 | b_offspring = b_offspring**(1/(mu + 1)) 122 | if (rand_c >= 0.5): 123 | offspring[i,j] = np.clip(((1 + b_offspring)*position[parent_1, j] + (1 - b_offspring)*position[parent_2, j])/2, min_values[j], max_values[j]) 124 | else: 125 | offspring[i,j] = np.clip(((1 - b_offspring)*position[parent_1, j] + (1 + b_offspring)*position[parent_2, j])/2, min_values[j], max_values[j]) 126 | offspring[i,-1] = target_function(offspring[i,0:offspring.shape[1]-1]) 127 | return offspring 128 | 129 | ############################################################################ 130 | 131 | # iWOA Function 132 | def improved_whale_optimization_algorithm(hunting_party = 5, spiral_param = 1, mu = 1, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True): 133 | count = 0 134 | position = initial_position(hunting_party, min_values, max_values, target_function) 135 | leader = leader_position(dimension = len(min_values), target_function = target_function) 136 | while (count <= iterations): 137 | if (verbose == True): 138 | print('Iteration = ', count, ' f(x) = ', leader[0,-1]) 139 | a_linear_component = 2 - count*( 2/iterations) 140 | b_linear_component = -1 + count*(-1/iterations) 141 | leader = update_leader(position, leader) 142 | position = update_position(position, leader, a_linear_component, b_linear_component, spiral_param, min_values, max_values, target_function) 143 | fitness = fitness_function(position) 144 | position = breeding(position, fitness, min_values, max_values, mu, target_function) 145 | leader = update_leader(position, leader) 146 | count = count + 1 147 | return leader 148 | 149 | ############################################################################ 150 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/jso.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Raiser /// Prof. Valdecy Pereira, D.Sc. 4 | # University of Chinese Academy of Sciences (China) /// UFF - Universidade Federal Fluminense (Brazil) 5 | # email: github.com/mpraiser /// valdecy.pereira@gmail.com 6 | # Metaheuristic: Jellyfish Search Optimizer 7 | 8 | # Raiser /// PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_position(jellyfishes = 5, min_values = [-5,-5], max_values = [5,5], eta = 4, target_function = target_function): 27 | position = np.zeros((jellyfishes, len(min_values)+1)) 28 | x = [] 29 | for j in range(0, len(min_values)): 30 | x_0 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 31 | while ([x_0] in [0.00, 0.25, 0.50, 0.75, 1.00]): 32 | x_0 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 33 | x.append(x_0) 34 | for i in range(0, jellyfishes): 35 | for j in range(0, len(min_values)): 36 | x[j] = eta*x[j]*(1 - x[j]) 37 | b = min_values[j] 38 | a = max_values[j] - b 39 | position[i,j] = x[j]*a + b 40 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 41 | return position 42 | 43 | ############################################################################ 44 | 45 | # Function: Updtade Jellyfishes Position 46 | def update_jellyfishes_position(position, best_position, beta, gamma, c_t, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 47 | mu = position.mean(axis = 0) 48 | if (c_t >= 0.5): 49 | for i in range(0, position.shape[0]): 50 | for j in range(0, len(min_values)): 51 | rand_1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 52 | rand_2 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 53 | position[i,j] = np.clip(position[i,j] + rand_1*(best_position[0, j] - beta*rand_2*mu[j]), min_values[j], max_values[j]) 54 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 55 | else: 56 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 57 | if (rand > 1 - c_t): 58 | for i in range(0, position.shape[0]): 59 | for j in range(0, len(min_values)): 60 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 61 | position[i,j] = np.clip(position[i,j] + gamma*rand*(max_values[j] - min_values[j]), min_values[j], max_values[j]) 62 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 63 | else: 64 | for i in range(0, position.shape[0]): 65 | candidates = [item for item in list(range(0, position.shape[0])) if item != i] 66 | k = random.choice(candidates) 67 | for j in range(0, len(min_values)): 68 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 69 | if (position[i, -1] >= position[k, -1]): 70 | direction = position[k, j] - position[i, j] 71 | else: 72 | direction = position[i, j] - position[k, j] 73 | position[i, j] = np.clip(position[i, j] + rand*direction, min_values[j], max_values[j]) 74 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 75 | return position 76 | 77 | ############################################################################ 78 | 79 | # Function: Jellyfish Search Optimizer 80 | def jellyfish_search_optimizer(jellyfishes = 5, min_values = [-5,-5], max_values = [5,5], eta = 4, beta = 3, gamma = 0.1, c_0 = 0.5, iterations = 50, target_function = target_function, verbose = True): 81 | count = 0 82 | eta = np.clip(eta, 3.57, 4) 83 | position = initial_position(jellyfishes, min_values, max_values, eta, target_function) 84 | best_position = np.copy(position[np.argmin(position[:,-1]),:].reshape(1,-1)) 85 | while (count <= iterations): 86 | if (verbose == True): 87 | print('Iteration = ', count, ' f(x) = ', best_position[0, -1]) 88 | rand = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 89 | c_t = abs( (1 - count/iterations) * (2*rand - 1) ) 90 | position = update_jellyfishes_position(position, best_position, beta, gamma, c_t, min_values, max_values, target_function) 91 | if (np.amin(position[:,-1]) < best_position[0,-1]): 92 | best_position = np.copy(position[np.argmin(position[:,-1]),:].reshape(1,-1)) 93 | count = count + 1 94 | return best_position 95 | 96 | ############################################################################ 97 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/jy.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Jaya (Sanskrit Word for Victory) 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_position(size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | position = np.zeros((size, len(min_values)+1)) 28 | for i in range(0, size): 29 | for j in range(0, len(min_values)): 30 | position[i,j] = random.uniform(min_values[j], max_values[j]) 31 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 32 | return position 33 | 34 | ############################################################################ 35 | 36 | # Function: Updtade Position by Fitness 37 | def update_bw_positions(position, best_position, worst_position): 38 | for i in range(0, position.shape[0]): 39 | if (position[i,-1] < best_position[-1]): 40 | best_position = np.copy(position[i, :]) 41 | if (position[i,-1] > worst_position[-1]): 42 | worst_position = np.copy(position[i, :]) 43 | return best_position, worst_position 44 | 45 | # Function: Search 46 | def update_position(position, best_position, worst_position, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 47 | candidate = np.copy(position[0, :]) 48 | for i in range(0, position.shape[0]): 49 | for j in range(0, len(min_values)): 50 | a = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 51 | b = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 52 | candidate[j] = np.clip(position[i, j] + a * (best_position[j] - abs(position[i, j])) - b * ( worst_position[j] - abs(position[i, j])), min_values[j], max_values[j] ) 53 | candidate[-1] = target_function(candidate[:-1]) 54 | if (candidate[-1] < position[i,-1]): 55 | position[i,:] = np.copy(candidate) 56 | return position 57 | 58 | ############################################################################ 59 | 60 | # Jaya Function 61 | def victory(size = 5, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True): 62 | count = 0 63 | position = initial_position(size, min_values, max_values, target_function) 64 | best_position = np.copy(position[0, :]) 65 | best_position[-1] = float('+inf') 66 | worst_position = np.copy(position[0, :]) 67 | worst_position[-1] = 0 68 | while (count <= iterations): 69 | if (verbose == True): 70 | print('Iteration = ', count, ' f(x) = ', best_position[-1]) 71 | position = update_position(position, best_position, worst_position, min_values, max_values, target_function) 72 | best_position, worst_position = update_bw_positions(position, best_position, worst_position) 73 | count = count + 1 74 | return best_position 75 | 76 | ############################################################################ 77 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/memetic_a.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Memetic Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_population(population_size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | population = np.zeros((population_size, len(min_values) + 1)) 28 | for i in range(0, population_size): 29 | for j in range(0, len(min_values)): 30 | population[i,j] = random.uniform(min_values[j], max_values[j]) 31 | population[i,-1] = target_function(population[i,0:population.shape[1]-1]) 32 | return population 33 | 34 | ############################################################################ 35 | 36 | # Function: Fitness 37 | def fitness_function(population): 38 | fitness = np.zeros((population.shape[0], 2)) 39 | for i in range(0, fitness.shape[0]): 40 | fitness[i,0] = 1/(1+ population[i,-1] + abs(population[:,-1].min())) 41 | fit_sum = fitness[:,0].sum() 42 | fitness[0,1] = fitness[0,0] 43 | for i in range(1, fitness.shape[0]): 44 | fitness[i,1] = (fitness[i,0] + fitness[i-1,1]) 45 | for i in range(0, fitness.shape[0]): 46 | fitness[i,1] = fitness[i,1]/fit_sum 47 | return fitness 48 | 49 | # Function: Selection 50 | def roulette_wheel(fitness): 51 | ix = 0 52 | random = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 53 | for i in range(0, fitness.shape[0]): 54 | if (random <= fitness[i, 1]): 55 | ix = i 56 | break 57 | return ix 58 | 59 | # Function: Offspring 60 | def breeding(population, fitness, min_values = [-5,-5], max_values = [5,5], mu = 1, elite = 0, target_function = target_function): 61 | offspring = np.copy(population) 62 | b_offspring = 0 63 | if (elite > 0): 64 | preserve = np.copy(population[population[:,-1].argsort()]) 65 | for i in range(0, elite): 66 | for j in range(0, offspring.shape[1]): 67 | offspring[i,j] = preserve[i,j] 68 | for i in range (elite, offspring.shape[0]): 69 | parent_1, parent_2 = roulette_wheel(fitness), roulette_wheel(fitness) 70 | while parent_1 == parent_2: 71 | parent_2 = random.sample(range(0, len(population) - 1), 1)[0] 72 | for j in range(0, offspring.shape[1] - 1): 73 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 74 | rand_b = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 75 | rand_c = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 76 | if (rand <= 0.5): 77 | b_offspring = 2*(rand_b) 78 | b_offspring = b_offspring**(1/(mu + 1)) 79 | elif (rand > 0.5): 80 | b_offspring = 1/(2*(1 - rand_b)) 81 | b_offspring = b_offspring**(1/(mu + 1)) 82 | if (rand_c >= 0.5): 83 | offspring[i,j] = np.clip(((1 + b_offspring)*population[parent_1, j] + (1 - b_offspring)*population[parent_2, j])/2, min_values[j], max_values[j]) 84 | else: 85 | offspring[i,j] = np.clip(((1 - b_offspring)*population[parent_1, j] + (1 + b_offspring)*population[parent_2, j])/2, min_values[j], max_values[j]) 86 | offspring[i,-1] = target_function(offspring[i,0:offspring.shape[1]-1]) 87 | return offspring 88 | 89 | # Function: Crossover Hill Clibing 90 | def xhc(offspring, fitness, min_values = [-5,-5], max_values = [5,5], mu = 1, target_function = target_function): 91 | offspring_xhc = np.zeros((2, len(min_values) + 1)) 92 | b_offspring = 0 93 | for _ in range (0, offspring.shape[0]): 94 | parent_1, parent_2 = roulette_wheel(fitness), roulette_wheel(fitness) 95 | while parent_1 == parent_2: 96 | parent_2 = random.sample(range(0, len(offspring) - 1), 1)[0] 97 | for j in range(0, offspring.shape[1] - 1): 98 | rand = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 99 | rand_b = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 100 | if (rand <= 0.5): 101 | b_offspring = 2*(rand_b) 102 | b_offspring = b_offspring**(1/(mu + 1)) 103 | elif (rand > 0.5): 104 | b_offspring = 1/(2*(1 - rand_b)) 105 | b_offspring = b_offspring**(1/(mu + 1)) 106 | offspring_xhc[0,j] = np.clip(((1 + b_offspring)*offspring[parent_1, j] + (1 - b_offspring)*offspring[parent_2, j])/2, min_values[j], max_values[j]) 107 | offspring_xhc[1,j] = np.clip(((1 - b_offspring)*offspring[parent_1, j] + (1 + b_offspring)*offspring[parent_2, j])/2, min_values[j], max_values[j]) 108 | offspring_xhc[0,-1] = target_function(offspring_xhc[0,0:offspring_xhc.shape[1]-1]) 109 | offspring_xhc[1,-1] = target_function(offspring_xhc[1,0:offspring_xhc.shape[1]-1]) 110 | if (offspring_xhc[1,-1] < offspring_xhc[0,-1]): 111 | for k in range(0, offspring.shape[1]): 112 | offspring_xhc[0, k] = offspring_xhc[1,k] 113 | if (offspring[parent_1, -1] < offspring[parent_2, -1]): 114 | if (offspring_xhc[0,-1] < offspring[parent_1, -1]): 115 | for k in range(0, offspring.shape[1]): 116 | offspring[parent_1, k] = offspring_xhc[0,k] 117 | elif(offspring[parent_2, -1] < offspring[parent_1, -1]): 118 | if (offspring_xhc[0,-1] < offspring[parent_2, -1]): 119 | for k in range(0, offspring.shape[1]): 120 | offspring[parent_2, k] = offspring_xhc[0,k] 121 | return offspring 122 | 123 | # Function: Mutation 124 | def mutation(offspring, mutation_rate = 0.1, eta = 1, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 125 | d_mutation = 0 126 | for i in range (0, offspring.shape[0]): 127 | for j in range(0, offspring.shape[1] - 1): 128 | probability = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 129 | if (probability < mutation_rate): 130 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 131 | rand_d = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 132 | if (rand <= 0.5): 133 | d_mutation = 2*(rand_d) 134 | d_mutation = d_mutation**(1/(eta + 1)) - 1 135 | elif (rand > 0.5): 136 | d_mutation = 2*(1 - rand_d) 137 | d_mutation = 1 - d_mutation**(1/(eta + 1)) 138 | offspring[i,j] = np.clip((offspring[i,j] + d_mutation), min_values[j], max_values[j]) 139 | offspring[i,-1] = target_function(offspring[i,0:offspring.shape[1]-1]) 140 | return offspring 141 | 142 | ############################################################################ 143 | 144 | # MA Function 145 | def memetic_algorithm(population_size = 5, mutation_rate = 0.1, elite = 0, min_values = [-5,-5], max_values = [5,5], eta = 1, mu = 1, std = 0.1, generations = 50, target_function = target_function, verbose = True): 146 | count = 0 147 | population = initial_population(population_size, min_values, max_values, target_function) 148 | fitness = fitness_function(population) 149 | elite_ind = np.copy(population[population[:,-1].argsort()][0,:]) 150 | while (count <= generations): 151 | if (verbose == True): 152 | print('Generation = ', count, ' f(x) = ', round(elite_ind[-1],4)) 153 | offspring = breeding(population, fitness, min_values, max_values, mu, elite, target_function) 154 | population = mutation(offspring, mutation_rate, eta, min_values, max_values, target_function) 155 | population = xhc(population, fitness, min_values, max_values, mu, target_function) 156 | if ((population[:,0:population.shape[1]-1].std())/len(min_values) < std): 157 | if (verbose == True): 158 | print('Reinitializing Population') 159 | population = initial_population(population_size, min_values, max_values, target_function) 160 | fitness = fitness_function(population) 161 | if(elite_ind[-1] > population[population[:,-1].argsort()][0,:][-1]): 162 | elite_ind = np.copy(population[population[:,-1].argsort()][0,:]) 163 | count = count + 1 164 | return elite_ind 165 | 166 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/mfa.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import math 16 | import os 17 | 18 | ############################################################################ 19 | 20 | # Function 21 | def target_function(): 22 | return 23 | 24 | ############################################################################ 25 | 26 | # Function: Initialize Variables 27 | def initial_moths(swarm_size = 3, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 28 | position = np.zeros((swarm_size, len(min_values)+1)) 29 | for i in range(0, swarm_size): 30 | for j in range(0, len(min_values)): 31 | position[i,j] = random.uniform(min_values[j], max_values[j]) 32 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 33 | return position 34 | 35 | ############################################################################ 36 | 37 | # Function: Update Flames 38 | def update_flames(flames, position): 39 | population = np.vstack([flames, position]) 40 | flames = np.copy(population[population[:,-1].argsort()][:flames.shape[0],:]) 41 | return flames 42 | 43 | # Function: Update Position 44 | def update_position(position, flames, flame_number = 1, b_constant = 1, a_linear_component = 1, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 45 | for i in range (0, position.shape[0]): 46 | for j in range(0, len(min_values)): 47 | if (i <= flame_number): 48 | flame_distance = abs(flames[i,j] - position[i,j]) 49 | rnd_1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 50 | rnd_2 = (a_linear_component - 1)*rnd_1 + 1 51 | position[i,j] = flame_distance*math.exp(b_constant *rnd_2)*math.cos(rnd_2*2*math.pi) + flames[i,j] 52 | elif(i > flame_number): 53 | flame_distance = abs(flames[i,j] - position[i,j]) 54 | rnd_1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 55 | rnd_2 = (a_linear_component - 1)*rnd_1 + 1 56 | position[i,j] = np.clip((flame_distance*math.exp(b_constant *rnd_2)*math.cos(rnd_2*2*math.pi) + flames[flame_number,j]), min_values[j], max_values[j]) 57 | position[i, -1] = target_function(position[i, 0:position.shape[1]-1]) 58 | return position 59 | 60 | ############################################################################ 61 | 62 | # MFA Function 63 | def moth_flame_algorithm(swarm_size = 3, min_values = [-5,-5], max_values = [5,5], generations = 50, b_constant = 1, target_function = target_function, verbose = True): 64 | count = 0 65 | position = initial_moths(swarm_size, min_values, max_values, target_function) 66 | flames = np.copy(position[position[:,-1].argsort()][:,:]) 67 | best_moth = np.copy(flames[0,:]) 68 | while (count <= generations): 69 | if (verbose == True): 70 | print('Generation: ', count, ' f(x) = ', best_moth[-1]) 71 | flame_number = round(position.shape[0] - count*((position.shape[0] - 1)/generations)) 72 | a_linear_component = -1 + count*((-1)/generations) 73 | position = update_position(position, flames, flame_number, b_constant, a_linear_component, min_values, max_values, target_function) 74 | flames = update_flames(flames, position) 75 | count = count + 1 76 | if (best_moth[-1] > flames[0, -1]): 77 | best_moth = np.copy(flames[0,:]) 78 | return best_moth 79 | 80 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/mvo.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Multi-Verse Optimizer 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import math 15 | import random 16 | import os 17 | 18 | ############################################################################ 19 | 20 | # Function 21 | def target_function(): 22 | return 23 | 24 | ############################################################################ 25 | 26 | # Function: Initialize Variables 27 | def initial_universes(universes = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 28 | cosmos = np.zeros((universes, len(min_values) + 1)) 29 | for i in range(0, universes): 30 | for j in range(0, len(min_values)): 31 | cosmos[i,j] = random.uniform(min_values[j], max_values[j]) 32 | cosmos[i,-1] = target_function(cosmos[i,0:cosmos.shape[1]-1]) 33 | return cosmos 34 | 35 | ############################################################################ 36 | 37 | # Function: Fitness 38 | def fitness_function(cosmos): 39 | fitness = np.zeros((cosmos.shape[0], 2)) 40 | for i in range(0, fitness.shape[0]): 41 | fitness[i,0] = 1/(1+ cosmos[i,-1] + abs(cosmos[:,-1].min())) 42 | fit_sum = fitness[:,0].sum() 43 | fitness[0,1] = fitness[0,0] 44 | for i in range(1, fitness.shape[0]): 45 | fitness[i,1] = (fitness[i,0] + fitness[i-1,1]) 46 | for i in range(0, fitness.shape[0]): 47 | fitness[i,1] = fitness[i,1]/fit_sum 48 | return fitness 49 | 50 | # Function: Selection 51 | def roulette_wheel(fitness): 52 | ix = 0 53 | random = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 54 | for i in range(0, fitness.shape[0]): 55 | if (random <= fitness[i, 1]): 56 | ix = i 57 | break 58 | return ix 59 | 60 | # Function: Big Bang 61 | def big_bang(cosmos, fitness, best_universe, wormhole_existence_probability, travelling_distance_rate, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 62 | for i in range(0,cosmos.shape[0]): 63 | for j in range(0,len(min_values)): 64 | r1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 65 | if (r1 < fitness[i, 1]): 66 | white_hole_i = roulette_wheel(fitness) 67 | cosmos[i,j] = cosmos[white_hole_i,j] 68 | r2 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 69 | if (r2 < wormhole_existence_probability): 70 | r3 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 71 | if (r3 <= 0.5): 72 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 73 | cosmos[i,j] = best_universe [j] + travelling_distance_rate*((max_values[j] - min_values[j])*rand + min_values[j]) 74 | elif (r3 > 0.5): 75 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 76 | cosmos[i,j] = np.clip((best_universe [j] - travelling_distance_rate*((max_values[j] - min_values[j])*rand + min_values[j])),min_values[j],max_values[j]) 77 | cosmos[i, -1] = target_function(cosmos[i, 0:cosmos.shape[1]-1]) 78 | return cosmos 79 | 80 | ############################################################################ 81 | 82 | # MVO Function 83 | def muti_verse_optimizer(universes = 5, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True): 84 | count = 0 85 | cosmos = initial_universes(universes, min_values, max_values, target_function) 86 | fitness = fitness_function(cosmos) 87 | best_universe = np.copy(cosmos[cosmos[:,-1].argsort()][0,:]) 88 | wormhole_existence_probability_max = 1.0 89 | wormhole_existence_probability_min = 0.2 90 | while (count <= iterations): 91 | if (verbose == True): 92 | print('Iteration = ', count, ' f(x) = ', best_universe[-1]) 93 | wormhole_existence_probability = wormhole_existence_probability_min + count*((wormhole_existence_probability_max - wormhole_existence_probability_min)/iterations) 94 | travelling_distance_rate = 1 - (math.pow(count,1/6)/math.pow(iterations,1/6)) 95 | cosmos = big_bang(cosmos, fitness, best_universe, wormhole_existence_probability, travelling_distance_rate, min_values, max_values, target_function) 96 | fitness = fitness_function(cosmos) 97 | value = np.copy(cosmos[cosmos[:,-1].argsort()][0,:]) 98 | if(best_universe[-1] > value[-1]): 99 | best_universe = np.copy(value) 100 | count = count + 1 101 | return best_universe 102 | 103 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/pfa.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Pathfinder Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_population(population_size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | population = np.zeros((population_size, len(min_values) + 1)) 28 | for i in range(0, population_size): 29 | for j in range(0, len(min_values)): 30 | population[i,j] = random.uniform(min_values[j], max_values[j]) 31 | population[i,-1] = target_function(population[i, 0:population.shape[1]-1]) 32 | return population 33 | 34 | ############################################################################ 35 | 36 | # Function: Build Distance Matrix 37 | def build_distance_matrix(population): 38 | a = np.copy(population[:,:-1]) 39 | b = a.reshape(np.prod(a.shape[:-1]), 1, a.shape[-1]) 40 | return np.sqrt(np.einsum('ijk,ijk->ij', b - a, b - a)).squeeze() 41 | 42 | # Function: Update Pathfinder 43 | def update_pathfinder(pathfinder, population, count, iterations, min_values = [-5, -5], max_values = [5, 5], target_function = target_function): 44 | u2 = np.random.uniform(-1, 1, 1)[0] 45 | r3 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 46 | A = u2*np.exp( (-2*count)/iterations ) 47 | local_best = np.copy(population[population[:,-1].argsort()][ 0,:]) 48 | pf = pathfinder + 2*r3*(pathfinder - local_best) + A 49 | for j in range(0, len(min_values)): 50 | pf[j] = np.clip(pf[j], min_values[j], max_values[j]) 51 | pf[-1] = target_function(pf[0:pf.shape[0]-1]) 52 | if (pathfinder[-1] > pf[-1]): 53 | pathfinder = np.copy(pf) 54 | return pathfinder 55 | 56 | # Function: Update Position 57 | def update_position(pathfinder, population, count, iterations, min_values = [-5, -5], max_values = [5, 5], target_function = target_function): 58 | dist = build_distance_matrix(population) 59 | u1 = np.random.uniform(-1, 1, 1)[0] 60 | r1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 61 | r2 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 62 | alpha = np.random.uniform(1, 2, 1)[0] 63 | beta = np.random.uniform(1, 2, 1)[0] 64 | new_p = np.zeros((population.shape[0]**2, population.shape[1])) 65 | c = 0 66 | for i in range(0, population.shape[0]): 67 | for j in range(0, population.shape[0]): 68 | if (sum(population[i,:] - population[j,:]) == 0): 69 | new_p[c,:] = initial_population(1, min_values, max_values, target_function) 70 | else: 71 | e = (1 - (count/iterations))*u1*dist[i, j] 72 | new_p[c,:] = population[i,:] + alpha*r1*(population[j,:]-population[i,:]) + beta*r2*(pathfinder-population[i,:]) + e 73 | for k in range(0, len(min_values)): 74 | new_p[c, k] = np.clip(new_p[c,k], min_values[k], max_values[k]) 75 | new_p[c,-1] = target_function(new_p[c, 0:new_p.shape[1]-1]) 76 | c = c + 1 77 | new_p = np.vstack([population, new_p]) 78 | new_p = new_p[new_p[:, -1].argsort()] 79 | new_p = new_p[:population.shape[0],:] 80 | return new_p 81 | 82 | ############################################################################ 83 | 84 | # Function: PFA 85 | def pathfinder_algorithm(population_size = 5, min_values = [-5, -5], max_values = [5, 5], iterations = 100, target_function = target_function, verbose = True): 86 | count = 0 87 | population = initial_population(population_size, min_values, max_values, target_function) 88 | pathfinder = np.copy(population[population[:,-1].argsort()][ 0,:]) 89 | while (count <= iterations): 90 | if (verbose == True): 91 | print('Iteration = ', count, ' f(x) = ', pathfinder[-1]) 92 | population = update_position(pathfinder, population, count, iterations, min_values, max_values, target_function) 93 | value = np.copy(population[population[:,-1].argsort()][ 0,:]) 94 | if (pathfinder[-1] > value[-1]): 95 | pathfinder = np.copy(value) 96 | pathfinder = update_pathfinder(pathfinder, population, count, iterations, min_values, max_values, target_function) 97 | count = count + 1 98 | return pathfinder 99 | 100 | ############################################################################ 101 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/pso.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Particle Swarm Optimization 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_position(swarm_size = 3, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | position = np.zeros((swarm_size, len(min_values)+1)) 28 | for i in range(0, swarm_size): 29 | for j in range(0, len(min_values)): 30 | position[i,j] = random.uniform(min_values[j], max_values[j]) 31 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 32 | return position 33 | 34 | ############################################################################ 35 | 36 | # Function: Initialize Velocity 37 | def initial_velocity(position, min_values = [-5,-5], max_values = [5,5]): 38 | init_velocity = np.zeros((position.shape[0], len(min_values))) 39 | for i in range(0, init_velocity.shape[0]): 40 | for j in range(0, init_velocity.shape[1]): 41 | init_velocity[i,j] = random.uniform(min_values[j], max_values[j]) 42 | return init_velocity 43 | 44 | # Function: Individual Best 45 | def individual_best_matrix(position, i_b_matrix): 46 | for i in range(0, position.shape[0]): 47 | if(i_b_matrix[i,-1] > position[i,-1]): 48 | for j in range(0, position.shape[1]): 49 | i_b_matrix[i,j] = position[i,j] 50 | return i_b_matrix 51 | 52 | # Function: Velocity 53 | def velocity_vector(position, init_velocity, i_b_matrix, best_global, w = 0.5, c1 = 2, c2 = 2): 54 | r1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 55 | r2 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 56 | velocity = np.zeros((position.shape[0], init_velocity.shape[1])) 57 | for i in range(0, init_velocity.shape[0]): 58 | for j in range(0, init_velocity.shape[1]): 59 | velocity[i,j] = w*init_velocity[i,j] + c1*r1*(i_b_matrix[i,j] - position[i,j]) + c2*r2*(best_global[j] - position[i,j]) 60 | return velocity 61 | 62 | # Function: Updtade Position 63 | def update_position(position, velocity, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 64 | for i in range(0, position.shape[0]): 65 | for j in range(0, position.shape[1] - 1): 66 | position[i,j] = np.clip((position[i,j] + velocity[i,j]), min_values[j], max_values[j]) 67 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 68 | return position 69 | 70 | ############################################################################ 71 | 72 | # PSO Function 73 | def particle_swarm_optimization(swarm_size = 3, min_values = [-5,-5], max_values = [5,5], iterations = 50, decay = 0, w = 0.9, c1 = 2, c2 = 2, target_function = target_function, verbose = True): 74 | count = 0 75 | position = initial_position(swarm_size, min_values, max_values, target_function) 76 | init_velocity = initial_velocity(position, min_values, max_values) 77 | i_b_matrix = np.copy(position) 78 | best_global = np.copy(position[position[:,-1].argsort()][0,:]) 79 | while (count <= iterations): 80 | if (verbose == True): 81 | print('Iteration = ', count, ' f(x) = ', best_global[-1]) 82 | position = update_position(position, init_velocity, min_values, max_values, target_function) 83 | i_b_matrix = individual_best_matrix(position, i_b_matrix) 84 | value = np.copy(i_b_matrix[i_b_matrix[:,-1].argsort()][0,:]) 85 | if (best_global[-1] > value[-1]): 86 | best_global = np.copy(value) 87 | if (decay > 0): 88 | n = decay 89 | w = w*(1 - ((count-1)**n)/(iterations**n)) 90 | c1 = (1-c1)*(count/iterations) + c1 91 | c2 = (1-c2)*(count/iterations) + c2 92 | init_velocity = velocity_vector(position, init_velocity, i_b_matrix, best_global, w = w, c1 = c1, c2 = c2) 93 | count = count + 1 94 | return best_global 95 | 96 | ############################################################################ 97 | -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/random_s.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Random Search 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_position(solutions = 3, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | position = np.zeros((solutions, len(min_values) + 1)) 28 | for i in range(0, solutions): 29 | for j in range(0, len(min_values)): 30 | position[i,j] = random.uniform(min_values[j], max_values[j]) 31 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 32 | return position 33 | 34 | # Function: Updtade Position 35 | def update_position(position, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 36 | updated_position = np.copy(position) 37 | for i in range(0, updated_position.shape[0]): 38 | for j in range(0, len(min_values)): 39 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 40 | updated_position[i,j] = np.clip(min_values[j] + (max_values[j] - min_values[j])*rand, min_values[j], max_values[j]) 41 | updated_position[i,-1] = target_function(updated_position[i,0:updated_position.shape[1]-1]) 42 | return updated_position 43 | 44 | ############################################################################ 45 | 46 | # RS Function 47 | def random_search(solutions = 5, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True): 48 | count = 0 49 | position = initial_position(solutions, min_values, max_values, target_function) 50 | best_solution = np.copy(position[position [:,-1].argsort()][0,:]) 51 | while (count <= iterations): 52 | if (verbose == True): 53 | print('Iteration = ', count, ' f(x) = ', best_solution[-1]) 54 | position = update_position(position, min_values, max_values, target_function) 55 | if(best_solution[-1] > position[position [:,-1].argsort()][0,:][-1]): 56 | best_solution = np.copy(position[position [:,-1].argsort()][0,:]) 57 | count = count + 1 58 | return best_solution 59 | 60 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/sa.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Simulated Annealing 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_guess(min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | n = 1 28 | guess = np.zeros((n, len(min_values) + 1)) 29 | for j in range(0, len(min_values)): 30 | guess[0,j] = random.uniform(min_values[j], max_values[j]) 31 | guess[0,-1] = target_function(guess[0,0:guess.shape[1]-1]) 32 | return guess 33 | 34 | ############################################################################ 35 | 36 | # Function: Epson Vector 37 | def epson_vector(guess, mu = 0, sigma = 1): 38 | epson = np.zeros((1, guess.shape[1]-1)) 39 | for j in range(0, guess.shape[1]-1): 40 | epson[0,j] = float(np.random.normal(mu, sigma, 1)) 41 | return epson 42 | 43 | # Function: Updtade Solution 44 | def update_solution(guess, epson, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 45 | updated_solution = np.copy(guess) 46 | for j in range(0, guess.shape[1] - 1): 47 | if (guess[0,j] + epson[0,j] > max_values[j]): 48 | updated_solution[0,j] = random.uniform(min_values[j], max_values[j]) 49 | elif (guess[0,j] + epson[0,j] < min_values[j]): 50 | updated_solution[0,j] = random.uniform(min_values[j], max_values[j]) 51 | else: 52 | updated_solution[0,j] = guess[0,j] + epson[0,j] 53 | updated_solution[0,-1] = target_function(updated_solution[0,0:updated_solution.shape[1]-1]) 54 | return updated_solution 55 | 56 | ############################################################################ 57 | 58 | # SA Function 59 | def simulated_annealing(min_values = [-5,-5], max_values = [5,5], mu = 0, sigma = 1, initial_temperature = 1.0, temperature_iterations = 1000, final_temperature = 0.0001, alpha = 0.9, target_function = target_function, verbose = True): 60 | guess = initial_guess(min_values, max_values, target_function) 61 | epson = epson_vector(guess, mu = mu, sigma = sigma) 62 | best = np.copy(guess) 63 | fx_best = guess[0,-1] 64 | temperature = float(initial_temperature) 65 | while (temperature > final_temperature): 66 | for repeat in range(0, temperature_iterations): 67 | if (verbose == True): 68 | print('Temperature = ', round(temperature, 4), ' ; iteration = ', repeat, ' ; f(x) = ', round(best[0, -1], 4)) 69 | fx_old = guess[0,-1] 70 | epson = epson_vector(guess, mu, sigma) 71 | new_guess = update_solution(guess, epson, min_values, max_values, target_function) 72 | fx_new = new_guess[0,-1] 73 | delta = (fx_new - fx_old) 74 | r = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1) 75 | p = np.exp(-delta/temperature) 76 | if (delta < 0 or r <= p): 77 | guess = np.copy(new_guess) 78 | if (fx_new < fx_best): 79 | fx_best = fx_new 80 | best = np.copy(guess) 81 | temperature = alpha*temperature 82 | return best 83 | 84 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/sine_cosine_a.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Sine Cosine Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import math 15 | import random 16 | import os 17 | 18 | ############################################################################ 19 | 20 | # Function 21 | def target_function(): 22 | return 23 | 24 | ############################################################################ 25 | 26 | # Function: Initialize Variables 27 | def initial_position(solutions = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 28 | position = np.zeros((solutions, len(min_values)+1)) 29 | for i in range(0, solutions): 30 | for j in range(0, len(min_values)): 31 | position[i,j] = random.uniform(min_values[j], max_values[j]) 32 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 33 | return position 34 | 35 | ############################################################################ 36 | 37 | # Function: Updtade Position 38 | def update_position(position, destination, r1 = 2, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 39 | for i in range(0, position.shape[0]): 40 | for j in range (0, len(min_values)): 41 | r2 = 2*math.pi*(int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1)) 42 | r3 = 2*(int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1)) 43 | r4 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 44 | if (r4 < 0.5): 45 | position[i,j] = np.clip((position[i,j] + (r1*math.sin(r2)*abs(r3*destination[j] - position[i,j]))),min_values[j],max_values[j]) 46 | else: 47 | position[i,j] = np.clip((position[i,j] + (r1*math.cos(r2)*abs(r3*destination[j] - position[i,j]))),min_values[j],max_values[j]) 48 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 49 | return position 50 | 51 | ############################################################################ 52 | 53 | # SCA Function 54 | def sine_cosine_algorithm(solutions = 5, a_linear_component = 2, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True): 55 | count = 0 56 | position = initial_position(solutions, min_values, max_values, target_function) 57 | destination = np.copy(position[position[:,-1].argsort()][0,:]) 58 | while (count <= iterations): 59 | if (verbose == True): 60 | print('Iteration = ', count, ' f(x) = ', destination[-1]) 61 | r1 = a_linear_component - count*(a_linear_component/iterations) 62 | position = update_position(position, destination, r1 , min_values, max_values, target_function) 63 | value = np.copy(position[position[:,-1].argsort()][0,:]) 64 | if (destination[-1] > value[-1]): 65 | destination = np.copy(value) 66 | count = count + 1 67 | return destination 68 | 69 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/sos.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Symbiotic Organisms Search 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_population(population_size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | population = np.zeros((population_size, len(min_values) + 1)) 28 | for i in range(0, population_size): 29 | for j in range(0, len(min_values)): 30 | population[i,j] = random.uniform(min_values[j], max_values[j]) 31 | population[i,-1] = target_function(population[i,0:population.shape[1]-1]) 32 | return population 33 | 34 | ############################################################################ 35 | 36 | # Function: Mutation 37 | def mutation(population, mutation_rate = 0.1, eta = 1, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 38 | d_mutation = 0 39 | for i in range (0, population.shape[0]): 40 | for j in range(0, population.shape[1] - 1): 41 | probability = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 42 | if (probability < mutation_rate): 43 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 44 | rand_d = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 45 | if (rand <= 0.5): 46 | d_mutation = 2*(rand_d) 47 | d_mutation = d_mutation**(1/(eta + 1)) - 1 48 | elif (rand > 0.5): 49 | d_mutation = 2*(1 - rand_d) 50 | d_mutation = 1 - d_mutation**(1/(eta + 1)) 51 | population[i,j] = np.clip((population[i,j] + d_mutation), min_values[j], max_values[j]) 52 | population[i,-1] = target_function(population[i,0:population.shape[1]-1]) 53 | return population 54 | 55 | ############################################################################ 56 | 57 | # Function: Mutualism Phase 58 | def mutualism(population, elite_ind, target_function = target_function): 59 | x_list = [i for i in range(0, population.shape[0])] 60 | population_i = np.copy(population) 61 | population_j = np.copy(population) 62 | for i in range(0, population.shape[0]): 63 | x_list.remove(i) 64 | j = random.choice(x_list) 65 | r1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 66 | r2 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 67 | mv = (population[i,:] + population[j,:])/2 68 | b1 = random.choice([1,2]) 69 | b2 = random.choice([1,2]) 70 | population_i[i,:] = population[i,:] + r1*(elite_ind - mv*b1) 71 | population_j[i,:] = population[j,:] + r2*(elite_ind - mv*b2) 72 | population_i[i,-1] = target_function(population_i[i,0:population_i.shape[1]-1]) 73 | population_j[i,-1] = target_function(population_j[i,0:population_j.shape[1]-1]) 74 | x_list.append(i) 75 | population = np.vstack([population, population_i, population_j]) 76 | population = population[population[:, -1].argsort()] 77 | population = population[:population_i.shape[0],:] 78 | return population 79 | 80 | # Function: Comensalism Phase 81 | def comensalism(population, elite_ind, target_function = target_function): 82 | x_list = [i for i in range(0, population.shape[0])] 83 | population_i = np.copy(population) 84 | for i in range(0, population.shape[0]): 85 | x_list.remove(i) 86 | j = random.choice(x_list) 87 | r = random.uniform(-1, 1) 88 | population_i[i,:] = population[i,:] + r*(elite_ind - population[j,:]) 89 | population_i[i,-1] = target_function(population_i[i,0:population_i.shape[1]-1]) 90 | x_list.append(i) 91 | population = np.vstack([population, population_i]) 92 | population = population[population[:, -1].argsort()] 93 | population = population[:population_i.shape[0],:] 94 | return population 95 | 96 | # Function: Parasitism Phase 97 | def parasitism(population, eta = 1, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 98 | population_i = np.copy(population) 99 | population_i = mutation(population_i, 1, eta, min_values, max_values, target_function) 100 | population = np.vstack([population, population_i]) 101 | population = population[population[:, -1].argsort()] 102 | population = population[:population_i.shape[0],:] 103 | return population 104 | 105 | ############################################################################ 106 | 107 | # SOS Function 108 | def symbiotic_organisms_search(population_size = 5, min_values = [-5,-5], max_values = [5,5], eta = 1, generations = 50, target_function = target_function, verbose = True): 109 | count = 0 110 | population = initial_population(population_size, min_values, max_values, target_function) 111 | elite_ind = np.copy(population[population[:,-1].argsort()][0,:]) 112 | while (count <= generations): 113 | if (verbose == True): 114 | print('Generation = ', count, ' f(x) = ', elite_ind[-1]) 115 | population = mutualism(population, elite_ind, target_function) 116 | population = comensalism(population, elite_ind, target_function) 117 | population = parasitism(population, eta, min_values, max_values, target_function) 118 | value = np.copy(population[population[:,-1].argsort()][0,:]) 119 | if(elite_ind[-1] > value[-1]): 120 | elite_ind = np.copy(value) 121 | count = count + 1 122 | return elite_ind 123 | 124 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/spbo.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Student Psychology Based Optimization 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_population(population_size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | population = np.zeros((population_size, len(min_values) + 1)) 28 | for i in range(0, population_size): 29 | for j in range(0, len(min_values)): 30 | population[i,j] = random.uniform(min_values[j], max_values[j]) 31 | population[i,-1] = target_function(population[i,0:population.shape[1]-1]) 32 | return population 33 | 34 | ############################################################################ 35 | 36 | # Function: Update Best Student 37 | def update_best_student(population, best_student, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 38 | idx = list(range(0, population.shape[0])) 39 | idx = random.choice(idx) 40 | k = [1, 2] 41 | k = random.choice(k) 42 | n_b = np.copy(best_student) 43 | for j in range(0, len(min_values)): 44 | r1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 45 | n_b[j] = np.clip(n_b[j] + ((-1)**k)*r1*(n_b[j] - population[idx, j]), min_values[j], max_values[j]) 46 | n_b[-1] = target_function(n_b[:-1]) 47 | if (n_b[-1] > best_student[-1]): 48 | n_b = np.copy(best_student) 49 | return n_b 50 | 51 | # Function: Update Good Student Type A 52 | def update_good_student_a(population, best_student, type_idx, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 53 | n_p = np.copy(population) 54 | for i in type_idx: 55 | for j in range(0, len(min_values)): 56 | r1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 57 | n_p[i, j] = np.clip(population[i, j] + r1*(best_student[j] - population[i, j]), min_values[j], max_values[j]) 58 | n_p[i,-1] = target_function(n_p[0,0:n_p.shape[1]-1]) 59 | return n_p[type_idx,:] 60 | 61 | # Function: Update Good Student Type B 62 | def update_good_student_b(population, best_student, type_idx, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 63 | n_p = np.copy(population) 64 | for i in type_idx: 65 | for j in range(0, len(min_values)): 66 | r1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 67 | r2 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 68 | n_p[i, j] = np.clip(population[i, j] + r1*(best_student[j] - population[i, j]) + (r2*(population[i, j] - population[type_idx, j].mean())), min_values[j], max_values[j]) 69 | n_p[i,-1] = target_function(n_p[0,0:n_p.shape[1]-1]) 70 | return n_p[type_idx,:] 71 | 72 | # Function: Update Average Student 73 | def update_average_student(population, type_idx, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 74 | n_p = np.copy(population) 75 | for i in type_idx: 76 | for j in range(0, len(min_values)): 77 | r1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 78 | n_p[i, j] = np.clip(population[i, j] + r1*(np.mean(population[type_idx, j]) - population[i, j]), min_values[j], max_values[j]) 79 | n_p[i,-1] = target_function(n_p[0,0:n_p.shape[1]-1]) 80 | return n_p[type_idx,:] 81 | 82 | # Function: Update Random Student 83 | def update_random_student(population, type_idx, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 84 | n_p = np.copy(population) 85 | for i in type_idx: 86 | for j in range(0, len(min_values)): 87 | r1 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 88 | n_p[i, j] = np.clip(np.min(population[:, j]) + r1*(np.max(population[:, j]) - np.min(population[:, j])), min_values[j], max_values[j]) 89 | n_p[i,-1] = target_function(n_p[0,0:n_p.shape[1]-1]) 90 | return n_p[type_idx,:] 91 | 92 | ############################################################################ 93 | 94 | # Function: Segments 95 | def segments(population): 96 | n = len(population) - 1 97 | x = [] 98 | a, b, c, d = 0, 0, 0, 0 99 | for i in range(0, n): 100 | a = i 101 | for j in range(i + 1, n): 102 | b = j 103 | for k in range(j + 1, n): 104 | c = k 105 | for L in range(k + 1, n + (i > 0)): 106 | d = L 107 | x.append((a, b, c, d)) 108 | return x 109 | 110 | # Function: Classify Class 111 | def classify_class(population, x): 112 | p_lst = list(range(0, len(population))) 113 | random.shuffle(p_lst) 114 | y = random.sample(x, 1)[0] 115 | i, j, k, L = y 116 | ga = p_lst[ :i] 117 | gb = p_lst[i:j] 118 | av = p_lst[j:L] 119 | rd = p_lst[L: ] 120 | return ga, gb, av, rd 121 | 122 | ############################################################################ 123 | 124 | # Function: Student Psychology Based Optimization 125 | def student_psychology_based_optimization(population_size = 5, min_values = [-5,-5], max_values = [5,5], generations = 5000, target_function = target_function, verbose = True): 126 | size = max(5, population_size) 127 | count = 0 128 | population = initial_population(size, min_values, max_values, target_function) 129 | best_student = np.copy(population[population[:,-1].argsort()][0,:]) 130 | x = segments(population) 131 | while (count <= generations): 132 | if (verbose == True): 133 | print('Generation = ', count, ' f(x) = ', best_student[-1]) 134 | ga, gb, av, rd = classify_class(population, x) 135 | best_student = update_best_student(population, best_student, min_values, max_values, target_function) 136 | population_1 = update_good_student_a(population, best_student, ga, min_values, max_values, target_function) 137 | population_2 = update_good_student_b(population, best_student, gb, min_values, max_values, target_function) 138 | population_3 = update_average_student(population, av, min_values, max_values, target_function) 139 | population_4 = update_random_student(population, rd, min_values, max_values, target_function) 140 | population = np.vstack([population, population_1, population_2, population_3, population_4]) 141 | population = population[population[:, -1].argsort()] 142 | value = np.copy(population[0,:]) 143 | population = population[:size,:] 144 | if (best_student[-1] > value[-1]): 145 | best_student = np.copy(value) 146 | count = count + 1 147 | return best_student 148 | 149 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/ssa.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Salp Swarm Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import math 15 | import random 16 | import os 17 | 18 | ############################################################################ 19 | 20 | # Function 21 | def target_function(): 22 | return 23 | 24 | ############################################################################ 25 | 26 | # Function: Initialize Variables 27 | def initial_position(swarm_size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 28 | position = np.zeros((swarm_size, len(min_values) + 1)) 29 | for i in range(0, swarm_size): 30 | for j in range(0, len(min_values)): 31 | position[i,j] = random.uniform(min_values[j], max_values[j]) 32 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 33 | return position 34 | 35 | ############################################################################ 36 | 37 | # Function: Initialize Food Position 38 | def food_position(dimension = 2, target_function = target_function): 39 | food = np.zeros((1, dimension+1)) 40 | for j in range(0, dimension): 41 | food[0,j] = 0.0 42 | food[0,-1] = target_function(food[0,0:food.shape[1]-1]) 43 | return food 44 | 45 | # Function: Updtade Food Position by Fitness 46 | def update_food(position, food): 47 | for i in range(0, position.shape[0]): 48 | if (food[0,-1] > position[i,-1]): 49 | for j in range(0, position.shape[1]): 50 | food[0,j] = position[i,j] 51 | return food 52 | 53 | # Function: Updtade Position 54 | def update_position(position, food, c1 = 1, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 55 | for i in range(0, position.shape[0]): 56 | if (i <= position.shape[0]/2): 57 | for j in range (0, len(min_values)): 58 | c2 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 59 | c3 = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 60 | if (c3 >= 0.5): #c3 < 0.5 61 | position[i,j] = np.clip((food[0,j] + c1*((max_values[j] - min_values[j])*c2 + min_values[j])), min_values[j],max_values[j]) 62 | else: 63 | position[i,j] = np.clip((food[0,j] - c1*((max_values[j] - min_values[j])*c2 + min_values[j])), min_values[j],max_values[j]) 64 | elif (i > position.shape[0]/2 and i < position.shape[0] + 1): 65 | for j in range (0, len(min_values)): 66 | position[i,j] = np.clip(((position[i - 1,j] + position[i,j])/2), min_values[j],max_values[j]) 67 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 68 | return position 69 | 70 | ############################################################################ 71 | 72 | # SSA Function 73 | def salp_swarm_algorithm(swarm_size = 5, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True): 74 | count = 0 75 | position = initial_position(swarm_size, min_values, max_values, target_function) 76 | food = food_position(dimension = len(min_values), target_function = target_function) 77 | while (count <= iterations): 78 | if (verbose == True): 79 | print('Iteration = ', count, ' f(x) = ', food[0,-1]) 80 | c1 = 2*math.exp(-(4*(count/iterations))**2) 81 | food = update_food(position, food) 82 | position = update_position(position, food, c1, min_values, max_values, target_function) 83 | count = count + 1 84 | return food 85 | 86 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/tlbo.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Teaching Learning Based Optimization 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import random 15 | import os 16 | 17 | ############################################################################ 18 | 19 | # Function 20 | def target_function(): 21 | return 22 | 23 | ############################################################################ 24 | 25 | # Function: Initialize Variables 26 | def initial_population(population_size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 27 | population = np.zeros((population_size, len(min_values) + 1)) 28 | for i in range(0, population_size): 29 | for j in range(0, len(min_values)): 30 | population[i,j] = random.uniform(min_values[j], max_values[j]) 31 | population[i,-1] = target_function(population[i,0:population.shape[1]-1]) 32 | return population 33 | 34 | ############################################################################ 35 | 36 | # Function: Update Population 37 | def update_population(population, teacher, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 38 | mean = population.mean(axis = 0) 39 | offspring = np.zeros((population.shape)) 40 | for i in range(0, population.shape[0]): 41 | teaching_factor = random.choice([1, 2]) 42 | r_i = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 43 | for j in range(0, len(min_values)): 44 | offspring[i, j] = np.clip(population[i, j] + r_i*(teacher[j] - teaching_factor*mean[j]), min_values[j], max_values[j]) 45 | offspring[i,-1] = target_function(offspring[i,0:offspring.shape[1]-1]) 46 | population = np.vstack([population, offspring]) 47 | population = population[population[:, -1].argsort()] 48 | population = population[:offspring.shape[0],:] 49 | return population 50 | 51 | # Function: Update Learners 52 | def update_learners(population, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 53 | offspring = np.zeros((population.shape)) 54 | for i in range(0, population.shape[0]): 55 | r_i = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 56 | idx = list(range(0, population.shape[0])) 57 | idx.remove(i) 58 | idx = random.choice(idx) 59 | for j in range(0, len(min_values)): 60 | if (population[i, -1] < population[idx, -1]): 61 | offspring[i, j] = np.clip(population[i, j] + r_i*(population[i, j] - population[idx, j]), min_values[j], max_values[j]) 62 | else: 63 | offspring[i, j] = np.clip(population[i, j] + r_i*(population[idx, j] - population[i, j]), min_values[j], max_values[j]) 64 | offspring[i,-1] = target_function(offspring[i,0:offspring.shape[1]-1]) 65 | population = np.vstack([population, offspring]) 66 | population = population[population[:, -1].argsort()] 67 | population = population[:offspring.shape[0],:] 68 | return population 69 | 70 | ############################################################################ 71 | 72 | # Function: Teaching Learning Based Optimization 73 | def teaching_learning_based_optimization(population_size = 5, min_values = [-5,-5], max_values = [5,5], generations = 100, target_function = target_function, verbose = True): 74 | count = 0 75 | population = initial_population(population_size, min_values, max_values, target_function) 76 | teacher = np.copy(population[population[:,-1].argsort()][0,:]) 77 | while (count <= generations): 78 | if (verbose == True): 79 | print('Generation = ', count, ' f(x) = ', teacher[-1]) 80 | population = update_population(population, teacher, min_values, max_values, target_function) 81 | value = np.copy(population[population[:,-1].argsort()][0,:]) 82 | if (teacher[-1] > value[-1]): 83 | teacher = np.copy(value) 84 | population = update_learners(population, min_values, max_values, target_function) 85 | value = np.copy(population[population[:,-1].argsort()][0,:]) 86 | if (teacher[-1] > value[-1]): 87 | teacher = np.copy(value) 88 | count = count + 1 89 | return teacher 90 | 91 | ############################################################################ -------------------------------------------------------------------------------- /pyMetaheuristic/algorithm/whale_optimization_a.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Metaheuristic: Whale Optimization Algorithm 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import numpy as np 14 | import math 15 | import random 16 | import os 17 | 18 | ############################################################################ 19 | 20 | # Function 21 | def target_function(): 22 | return 23 | 24 | ############################################################################ 25 | 26 | # Function: Initialize Variables 27 | def initial_position(hunting_party = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 28 | position = np.zeros((hunting_party, len(min_values)+1)) 29 | for i in range(0, hunting_party): 30 | for j in range(0, len(min_values)): 31 | position[i,j] = random.uniform(min_values[j], max_values[j]) 32 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 33 | return position 34 | 35 | ############################################################################ 36 | 37 | # Function: Initialize Alpha 38 | def leader_position(dimension = 2, target_function = target_function): 39 | leader = np.zeros((1, dimension+1)) 40 | for j in range(0, dimension): 41 | leader[0,j] = 0.0 42 | leader[0,-1] = target_function(leader[0,0:leader.shape[1]-1]) 43 | return leader 44 | 45 | # Function: Updtade Leader by Fitness 46 | def update_leader(position, leader): 47 | for i in range(0, position.shape[0]): 48 | if (leader[0,-1] > position[i,-1]): 49 | for j in range(0, position.shape[1]): 50 | leader[0,j] = position[i,j] 51 | return leader 52 | 53 | # Function: Updtade Position 54 | def update_position(position, leader, a_linear_component = 2, b_linear_component = 1, spiral_param = 1, min_values = [-5,-5], max_values = [5,5], target_function = target_function): 55 | for i in range(0, position.shape[0]): 56 | r1_leader = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 57 | r2_leader = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 58 | a_leader = 2*a_linear_component*r1_leader - a_linear_component 59 | c_leader = 2*r2_leader 60 | p = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 61 | for j in range (0, len(min_values)): 62 | if (p < 0.5): 63 | if (abs(a_leader) >= 1): 64 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 65 | rand_leader_index = math.floor(position.shape[0]*rand); 66 | x_rand = position[rand_leader_index, :] 67 | distance_x_rand = abs(c_leader*x_rand[j] - position[i,j]) 68 | position[i,j] = np.clip( x_rand[j] - a_leader*distance_x_rand, min_values[j], max_values[j]) 69 | elif (abs(a_leader) < 1): 70 | distance_leader = abs(c_leader*leader[0,j] - position[i,j]) 71 | position[i,j] = np.clip(leader[0,j] - a_leader*distance_leader, min_values[j], max_values[j]) 72 | elif (p >= 0.5): 73 | distance_Leader = abs(leader[0,j] - position[i,j]) 74 | rand = int.from_bytes(os.urandom(8), byteorder = 'big') / ((1 << 64) - 1) 75 | m_param = (b_linear_component - 1)*rand + 1 76 | position[i,j] = np.clip( (distance_Leader*math.exp(spiral_param*m_param)*math.cos(m_param*2*math.pi) + leader[0,j]), min_values[j], max_values[j]) 77 | position[i,-1] = target_function(position[i,0:position.shape[1]-1]) 78 | return position 79 | 80 | ############################################################################ 81 | 82 | # WOA Function 83 | def whale_optimization_algorithm(hunting_party = 5, spiral_param = 1, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True): 84 | count = 0 85 | position = initial_position(hunting_party, min_values, max_values, target_function) 86 | leader = leader_position(dimension = len(min_values), target_function = target_function) 87 | while (count <= iterations): 88 | if (verbose == True): 89 | print('Iteration = ', count, ' f(x) = ', leader[0,-1]) 90 | a_linear_component = 2 - count*( 2/iterations) 91 | b_linear_component = -1 + count*(-1/iterations) 92 | leader = update_leader(position, leader) 93 | position = update_position(position, leader, a_linear_component, b_linear_component, spiral_param, min_values, max_values, target_function) 94 | count = count + 1 95 | return leader 96 | 97 | ############################################################################ 98 | -------------------------------------------------------------------------------- /pyMetaheuristic/test_function/__init__.py: -------------------------------------------------------------------------------- 1 | from .single import * 2 | -------------------------------------------------------------------------------- /pyMetaheuristic/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from .graphs import * 2 | -------------------------------------------------------------------------------- /pyMetaheuristic/utils/graphs.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | 3 | # Created by: Prof. Valdecy Pereira, D.Sc. 4 | # UFF - Universidade Federal Fluminense (Brazil) 5 | # email: valdecy.pereira@gmail.com 6 | # Graphs #from ..utils import * 7 | 8 | # PEREIRA, V. (2022). GitHub repository: https://github.com/Valdecy/pyMetaheuristic 9 | 10 | ############################################################################ 11 | 12 | # Required Libraries 13 | import itertools 14 | import numpy as np 15 | import plotly.graph_objects as go 16 | import plotly.io as pio 17 | 18 | from scipy.sparse.linalg import svds 19 | 20 | ############################################################################ 21 | 22 | # Function: Solution Plot 23 | def plot_single_function(min_values, max_values, target_function, step = [0.1, 0.1], solution = [ ], proj_view = '3D', view = 'browser'): 24 | if (view == 'browser' ): 25 | pio.renderers.default = 'browser' 26 | x = [] 27 | data = [] 28 | for j in range(0, len(min_values)): 29 | values = np.arange(min_values[j], max_values[j], step[j]) 30 | x.append(values) 31 | cartesian_product = list(itertools.product(*x)) 32 | front = np.array(cartesian_product, dtype = np.dtype('float')) 33 | front = np.c_[ front, np.zeros(len(cartesian_product)) ] 34 | value = [target_function(item) for item in cartesian_product] 35 | front[:, -1] = value 36 | nid_list = [ 'f(x) = '+str(round(item, 4)) for item in value] 37 | if (proj_view == '1D' or proj_view == '1d' or proj_view == '2D' or proj_view == '2d'): 38 | if (len(solution) > 0): 39 | sol = np.array(solution) 40 | c_sol = ['f(x) = '+str(round(target_function(item), 2)) for item in sol] 41 | if ( (proj_view == '1D' or proj_view == '1d') and len(min_values) > 1): 42 | if (sol.shape[0] == 1): 43 | sol = np.vstack([sol, sol]) 44 | sol, _, _ = svds(sol, k = 1) 45 | if ( (proj_view == '2D' or proj_view == '2d') and len(min_values) > 2): 46 | if (sol.shape[0] == 1): 47 | sol = np.vstack([sol, sol]) 48 | sol, _, _ = svds(sol, k = 2) 49 | s_trace = go.Scatter(x = sol[:, 0], 50 | y = sol[:, 1], 51 | opacity = 1, 52 | mode = 'markers+text', 53 | marker = dict(symbol = 'circle-dot', size = 10, color = 'red'), 54 | hovertext = c_sol, 55 | name = '' 56 | ) 57 | data.append(s_trace) 58 | if ( len(min_values) > 2): 59 | sol, _, _ = svds(front[:,:-1], k = 2) 60 | front[:,0] = sol[:,0] 61 | front[:,1] = sol[:,1] 62 | n_trace = go.Scatter(x = front[:, 0], 63 | y = front[:, 1], 64 | opacity = 0.5, 65 | mode = 'markers+text', 66 | marker = dict(symbol = 'circle-dot', size = 5, color = -front[:,-1]), 67 | hovertext = nid_list, 68 | name = '' 69 | ) 70 | data.append(n_trace) 71 | layout = go.Layout(showlegend = False, 72 | hovermode = 'closest', 73 | margin = dict(b = 10, l = 5, r = 5, t = 10), 74 | plot_bgcolor = 'white', 75 | xaxis = dict( showgrid = False, 76 | zeroline = False, 77 | showticklabels = True, 78 | tickmode = 'array', 79 | ), 80 | yaxis = dict( showgrid = False, 81 | zeroline = False, 82 | showticklabels = True, 83 | tickmode = 'array', 84 | ) 85 | ) 86 | fig_aut = go.Figure(data = data, layout = layout) 87 | fig_aut.update_traces(textfont_size = 10, textfont_color = 'white') 88 | fig_aut.show() 89 | elif (proj_view == '3D' or proj_view == '3d'): 90 | if (len(solution) > 0): 91 | sol = np.array(solution) 92 | c_val = [target_function(item) for item in sol] 93 | if ( len(min_values) > 2): 94 | if (sol.shape[0] == 1): 95 | sol = np.vstack([sol, sol]) 96 | sol, _, _ = svds(sol, k = 2) 97 | s_trace = go.Scatter3d(x = sol[:, 0], 98 | y = sol[:, 1], 99 | z = c_val, 100 | opacity = 1, 101 | mode = 'markers+text', 102 | marker = dict(size = 10, color = 'red'), 103 | name = '' 104 | ) 105 | data.append(s_trace) 106 | if ( len(min_values) > 2): 107 | sol, _, _ = svds(front[:,:-1], k = 2) 108 | front[:,0] = sol[:,0] 109 | front[:,1] = sol[:,1] 110 | n_trace = go.Scatter3d(x = front[:, 0], 111 | y = front[:, 1], 112 | z = front[:,-1], 113 | opacity = 0.5, 114 | mode = 'markers+text', 115 | marker = dict(size = 5, color = -front[:,-1]), 116 | name = '' 117 | ) 118 | data.append(n_trace) 119 | layout = go.Layout(showlegend = False, 120 | hovermode = 'closest', 121 | margin = dict(b = 10, l = 5, r = 5, t = 10), 122 | plot_bgcolor = 'white', 123 | ) 124 | fig_aut = go.Figure(data = data, layout = layout) 125 | fig_aut.update_traces(textfont_size = 10, textfont_color = 'white') 126 | fig_aut.update_scenes(xaxis_visible = False, yaxis_visible = False, zaxis_visible = False) 127 | fig_aut.show() 128 | else: 129 | dict_list = [] 130 | color_lst = [0]*front.shape[0] 131 | if (len(solution) > 0): 132 | for i in range(0, len(solution)): 133 | sol = np.array(solution[i]) 134 | front = np.r_[front, np.zeros((1, front.shape[1])) ] 135 | color_lst.append(1) 136 | for j in range(0, sol.shape[0]): 137 | front[-1, j] = sol[j] 138 | for j in range(0, len(min_values)): 139 | dict_list.append(dict(range = [min_values[j]*1.00, max_values[j]*1.00], label = 'x'+str(j+1), values = front[:,j])) 140 | lines = go.Parcoords( 141 | line = dict(color = color_lst, colorscale = [[0,'lightblue'], [0.5,'lightblue'], [1,'red']]), 142 | dimensions = dict_list 143 | ) 144 | fig_aut = go.Figure(data = lines) 145 | fig_aut.update_layout(font = dict(family = 'Arial Black', size = 15, color = 'black')) 146 | fig_aut.show() 147 | return 148 | 149 | ############################################################################ 150 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | from pathlib import Path 3 | 4 | this_directory = Path(__file__).parent 5 | long_description = (this_directory / 'README.md').read_text() 6 | 7 | setup( 8 | name='pyMetaheuristic', 9 | version='1.4.1', 10 | license='GNU', 11 | author='Valdecy Pereira', 12 | author_email='valdecy.pereira@gmail.com', 13 | url='https://github.com/Valdecy/pyMetaheuristic', 14 | packages=find_packages(), 15 | install_requires=[ 16 | 'numpy', 17 | 'plotly', 18 | 'scipy' 19 | ], 20 | description='A Metaheuristics Library', 21 | long_description=long_description, 22 | long_description_content_type='text/markdown', 23 | ) 24 | --------------------------------------------------------------------------------