├── DESCRIPTION.rst ├── README.md ├── SwarmPackagePy ├── __init__.py ├── aba.py ├── animation.py ├── ba.py ├── bfo.py ├── ca.py ├── chso.py ├── cso.py ├── fa.py ├── fwa.py ├── gsa.py ├── gwo.py ├── hs.py ├── intelligence.py ├── pso.py ├── ssa.py ├── test.py ├── testFunctions.py └── wsa.py ├── example.py ├── setup.py └── test.py /DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | *SwarmPackagePy* is the package, witch contains the following swarm optimization algorithms: 2 | 3 | 1. Artificial Bee Algorithm 4 | 2. Bat Algorithm 5 | 3. Bacterial Foraging Optimization 6 | 4. Cat Swarm Optimization 7 | 5. Chicken Swarm Optimization 8 | 6. Cuckoo Search Optimization 9 | 7. Firefly algorithm 10 | 8. Firework Algorithm 11 | 9. Gravitational Search Algorithm 12 | 10. Grey Wolf Optimizer 13 | 11. Harmony Search 14 | 12. Particle Swarm Optimization 15 | 13. Social Spider Algorithm 16 | 14. Whale Swarm Algorithm 17 | 18 | Every algorithm has arguments listed below: 19 | 20 | * n: number of agents 21 | * function: test function 22 | * lb: lower limits for plot axes 23 | * ub: upper limits for plot axes 24 | * dimension: space dimension 25 | * iteration: number of iterations 26 | 27 | Every algorithm has methods listed below: 28 | 29 | * get_agents(): returns a history of all agents of the algorithm 30 | * get_Gbest(): returns the best position of algorithm 31 | 32 | All documentation you can view on the github repository https://github.com/SISDevelop/SwarmPackagePy. 33 | For all questions and suggestions contact us at swarm.team.dev@gmail.com. For more info you could also write to: 34 | 35 | * team leads - vllitskevich@gmail.com, polly.bartoshevic@gmail.com, 36 | * programmers - alexeymaleyko@gmail.com, b317.forinko@gmail.com, vladislaw.kapustin@gmail.com. 37 | 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # SwarmPackagePy 3 | **SwarmPackagePy** is a Library of swarm optimization algorithms. It includes 14 optimization algorithms and each can be used for solving specific optimization problem. You can find the principles they operate on and pseudo codes below.
4 | 5 | Provides:
6 | - Swarm optimization algorithms. 7 | - Test functions for swarm algorithms. 8 | - Animation of minimum find process.
9 |
Every algorithm has arguments listed below:
10 | - **n**: number of agents 11 | - **function**: test function 12 | - **lb**: lower limits for plot axes 13 | - **ub**: upper limits for plot axes 14 | - **dimension**: space dimension 15 | - **iteration**: number of iterations
16 |
Every algorithm has methods listed below:
17 | - **get_agents()**: returns a history of all agents of the algorithm 18 | - **get_Gbest()**: returns the best position of algorithm
19 |
If an algorithm accepts some additional arguments or methods they will be described in its "Arguments" or "Methods" section. 20 | 21 | For all questions and suggestions contact us at swarm.team.dev@gmail.com. For more info you could also write to:
22 | * team leads - vllitskevich@gmail.com, polly.bartoshevic@gmail.com, 23 | * programmers - alexeymaleyko@gmail.com, b317.forinko@gmail.com, vladislaw.kapustin@gmail.com. 24 | 25 | ## Table of contents 26 | * [Installation](#installation)
27 | * [Bacterial Foraging Optimization](#bacterial-foraging-optimization)
28 | * [Gray Wolf Optimization](#gray-wolf-optimization)
29 | * [Bat Algorithm](#bat-algorithm)
30 | * [Artificial Bee Algorithm](#artificial-bee-algorithm)
31 | * [Firefly Algorithm](#firefly-algorithm)
32 | * [Cuckoo Search Optimization](#cuckoo-search-optimization)
33 | * [Whale Swarm Algorithm](#whale-swarm-algorithm)
34 | * [Firework Algorithm](#firework-algorithm)
35 | * [Particle Swarm Optimization](#particle-swarm-optimization)
36 | * [Chicken Swarm Optimization](#chicken-swarm-optimization)
37 | * [Social Spider Algorightm](#social-spider-algorightm)
38 | * [Cat Algorithm](#cat-algorithm)
39 | * [Harmony Search](#harmony-search)
40 | * [Gravitational Search Algorithm](#gravitational-search-algorithm)
41 | * [Tests](#tests)
42 | * [Animation](#animation)
43 | 44 | ### Installation 45 | #### Requirements 46 | - python (version >= 3.5 if you are going to run tests; for all other actions you can use python any version)
47 | - numpy
48 | - pytest (if you are going to run tests)
49 | - matplotlib (if you are going to watch animation)
50 | - pandas (if you are going to watch 3D animation)
51 | #### Installation 52 | You can install **SwarmPackagePy** from PyPI repositories using pip. Command bellow will do this: 53 | ``` 54 | pip install SwarmPackagePy 55 | ``` 56 | Or you can just clone this repository and at the main folder execute command: 57 | ``` 58 | cd SwarmPackagePy/ 59 | python setup.py install 60 | ``` 61 | 62 | ### Bacterial Foraging Optimization 63 | #### Description 64 | The **Bacterial Foraging Optimization**, proposed by Passino is inspired by the social foraging behavior of Escherichia coli (next E.coli).
65 | During foraging of the real bacteria, locomotion is achieved by a set of tensile flagella. 66 | Flagella help an E.coli bacterium to tumble or swim, which are two basic operations performed by a bacterium at the 67 | time of foraging. When they rotate the flagella in the clockwise direction, each flagellum pulls 68 | on the cell. That results in the moving of flagella independently and finally the bacterium tumbles with 69 | lesser number of tumbling whereas in a harmful place it tumbles frequently to find a nutrient gradient. 70 | Moving the flagella in the counterclockwise direction helps the bacterium to swim at a very fast rate. 71 | In the above-mentioned algorithm the bacteria undergoes chemotaxis, where they like to move towards 72 | a nutrient gradient and avoid noxious environment. Generally the bacteria move for a longer distance 73 | in a friendly environment.
74 | When they get food in sufficient, they are increased in length and in presence of suitable temperature 75 | they break in the middle to from an exact replica of itself. This phenomenon inspired Passino to 76 | introduce an event of reproduction in BFO. Due to the occurrence of sudden environmental changes 77 | or attack, the chemotactic progress may be destroyed and a group of bacteria may move to some other 78 | places or some other may be introduced in the swarm of concern. This constitutes the event of 79 | elimination-dispersal in the real bacterial population, where all the bacteria in a region are killed or a 80 | group is dispersed into a new part of the environment.
81 | Bacterial Foraging Optimization has three main steps: 82 | * Chemotaxis 83 | * Reproduction 84 | * Elimination and Dispersal 85 | #### Mathematical model 86 | _Chemotaxis:_ This process simulates the movement of an E.coli cell through swimming and 87 | tumbling via flagella. Biologically an E.coli bacterium can move in two different ways. It can 88 | swim for a period of time in the same direction or it may tumble, and alternate between these 89 | two modes of operation for the entire lifetime. 90 | _Reproduction:_ The least healthy bacteria eventually die while each of the healthier bacteria (those 91 | yielding lower value of the objective function) asexually split into two bacteria, which are then 92 | placed in the same location. This keeps the swarm size constant. 93 | _Elimination and Dispersal:_ Gradual or sudden changes in the local environment where a 94 | bacterium population lives may occur due to various reasons e.g. a significant local rise of 95 | temperature may kill a group of bacteria that are currently in a region with a high concentration of 96 | nutrient gradients. Events can take place in such a fashion that all the bacteria in a region are killed 97 | or a group is dispersed into a new location. To simulate this phenomenon in BFO some bacteria 98 | are liquidated at random with a very small probability while the new replacements are randomly 99 | initialized over the search space. 100 | #### Algorithm 101 |
102 | BEGIN
103 |  Initialize randomly the bacteria foraging optimization population
104 |  Calculate the fitness of each agent
105 |  Set global best agent to best agent
106 |  FOR number of iterations
107 |   FOR number of chemotactic steps
108 |    FOR each search agent
109 |     Move agent to the random direction
110 |     Calculate the fitness of the moved agent
111 |     FOR swimming length
112 |      IF current fitness is better than previous
113 |       Move agent to the same direction
114 |      ELSE
115 |       Move agent to the random direction
116 |      END IF
117 |     END FOR
118 |    END FOR
119 |    Calculate the fitness of each agent
120 |   END FOR
121 |   Compute and sort sum of fitness function of all chemotactic loops (health of agent)
122 |   Let live and split only half of the population according to their health
123 |   IF not the last iteration
124 |    FOR each search agent
125 |     With some probability replace agent with new random generated
126 |    END FOR
127 |   END IF
128 |   Update the best search agent
129 |  Calculate the fitness of each agent
130 | END
131 | 
132 | #### Arguments 133 | The bfo method accepts the following arguments:
134 | **param Nc** number of chemotactic steps
135 | **param Ns** swimming length
136 | **param C** the size of step taken in the random direction specified by the tumble
137 | **param Ped** elimination-dispersal probability
138 | #### Method invocation 139 | The method can be invoked by passing the arguments in the following order: 140 | ``` 141 | SwarmPackagePy.bfo(n, function, lb, ub, dimension, iteration, Nc, Ns, C, Ped) 142 | ``` 143 | ### Gray Wolf Optimization 144 | #### Description 145 | The **Gray Wolf Optimization algorithm** mimics the leadership hierarchy and 146 | hunting mechanism of gray wolves in nature. Wolves live in a pack. 147 | The average pack consists of a family of 5–12 animals. 148 | wolves have strict social hierarchy which is represented by the division of a pack into four 149 | levels: alpha, beta, delta, and omega.
150 | _Alpha_ wolves are the leaders of their pack. They are responsible for making decisions, but sometimes 151 | alphas can obey to other wolfes of the pack.
152 | _Beta_ wolves help alphas make decisions, every beta is a candidate 153 | to become an alpha if an alpha has died or aged. 154 | A beta respects an alpha and transfers commands to the pack, ensures discipline among inferior wolves 155 | and provides a feedback from the pack to an alpha.
156 | _Delta_ wolves have to submit to alphas and betas, but they dominate the omega.
157 | Finally, _omega_ wolves have to obey all other wolves. Sometimes they play a role of caretakers.

158 | Gray wolf hunting has three main phases: 159 | * Tracking, chasing, and approaching the prey 160 | * Pursuing, encircling, and harassing the prey until it stops moving 161 | * Attack towards the prey 162 | #### Mathematical model 163 | In mathematical model of the social hierarchy 164 | of wolves is mapped to the solution fit. The fittest 165 | solution is considered to be the alpha. Beta and delta are the second and 166 | third best solutions respectively. 167 | The rest of the candidate solutions are assumed to be omega.
168 | Alpha, beta and delta lead the hunting (optimization) and omega wolves follow these three wolves. 169 | #### Algorithm 170 |
171 | BEGIN
172 |   Initialize randomly the gray wolf population
173 |   Find 1st, 2nd and 3rd best agents (α, β, δ)
174 |   Set global best agent to the 1st best agent
175 |   Calculate the fitness of each search agent
176 |   WHILE count < max number of iterations
177 |     FOR each search agent
178 |       Update te position of the current search agent
179 |     END FOR
180 |     Update α, β and δ
181 |     Calculate the fitness of all search agents
182 |     Update the best search agent, the 2nd best serach agent, and the 3rd best search agent
183 |     ADD 1 to count
184 |   END WHILE
185 |   RETURN the best search agent
186 | END
187 | 
188 | #### Arguments 189 | The gwo method accepts the following arguments:
190 | **n**: number of agents
191 | **function**: test function
192 | **lb**: lower limits for plot axes
193 | **ub**: upper limits for plot axes
194 | **dimension**: space dimension
195 | **iteration**: number of iterations 196 | #### Methods 197 | The gwo method has the following additional methods:
198 | **get_leaders()**: return alpha, beta, delta leaders of grey wolfs 199 | #### Method invocation 200 | The method can be invoked by passing the arguments in the following order: 201 | ``` 202 | SwarmPackagePy.pso(n, function, lb, ub, dimension, iteration) 203 | ``` 204 | ### Bat Algorithm 205 | #### Description 206 | The **Bat Algorithm** is based on the bats echolocation ability. By using echolocation bats can detect 207 | their food and preys and even distinguish between the different kinds of insects in the darkness. 208 | A bat emits a loud sound and listens to the echo which is created from the sound reflection from the surrounding objects. 209 | Sounds emmited by a bat are vary in properties and can be used depending on the hunting strategy.
210 | Each sound impulse lasts from 8 to 10 milliseconds and has constant frequency between 25 and 150 KHz. 211 | A bat can emit from 10 to 20 of supersonic impulses per second, an impulse lasts from 5 to 20 milliseconds. 212 | The number of signals emited by a bat can be increased during a hunt to 200. 213 | #### Mathematical model 214 | The Bat Algorithm uses the following principles: 215 | 1. A bat uses echolocation for distance estimation and "knows" the difference between the food/prey and an obstacle 216 | 2. Bats fly randomly with a velocity of νi in the position xi, fixed frequency fmin, variable wavelength λ and loudness A0 for the search of a prey. They can automatically adjust the wave length (or frequency) of emitted sound impulse and level of emission r ∈ [0, 1] depending on the proximity to the victim. 217 | 3. While the loudness can be changed by different means we assume that the loudness vary from big positive value A0 to minimum constant Amin. 218 | In addition to these simplified principles, lets use the next approximations: frequency f from the segment [fmin, fmax] corresponds to the wavelength segment [λmin, λmax]. For instance, a frequency segment [20 KHz, 500 KHz] corresponds to wavelength segment [0.7 mm, 17 mm].
219 | For this tast any wave length can be used. Moreover, it is unnecessary to use wave lengths, instead we can change the frequency and leave the wave length to be constant. 220 | #### Algorithm 221 |
222 | BEGIN
223 | Objective function f(x), x=(x1, ...,xd)T
224 | Initialize the bat population xi (i= 1, 2, ..., n) and vi
225 | Define pulse frequency fi at xi
226 | Initialize pulse rates ri and the loudness Ai
227 |   WHILE count < max number of iterations
228 |     Generate new solutions by adjusting frequency, and updating velocities and locations/solutions
229 |     IF rand > ri
230 |       Select a solution among the best solutions
231 |       Generate a local solution around the selected best solution
232 |     END IF
233 |     Generate a new solution by flying randomly
234 |     IF rand < Ai AND f(xi) < f(x*)
235 |       Accept the new solutions
236 |       Increase ri and reduce Ai
237 |     END IF
238 |     Rank the bats and find the current best x*
239 |   END WHILE
240 |   Postprocess results and visualization
241 |   
242 | #### Arguments 243 | The ba method accepts the following arguments:
244 | - r0: level of impulse emission (default value is 0.9)
245 | - V0: volume of sound (default value is 0.5)
246 | - fmin: min wave frequency (default value is 0)
247 | - fmax: max wave frequency (default value is 0.02)
248 | fmin = 0 and fmax =0.02 - the bests values
249 | - alpha: constant for change a volume of sound (default value is 0.9)
250 | - csi: constant for change a level of impulse emission (default value is 0.9) 251 | #### Method invocation 252 | The method can be invoked by passing the arguments in the following order: 253 | ``` 254 | SwarmPackagePy.ba(n, function, lb, ub, dimension, iteration, r0, V0, fmin, fmax, alpha, csi) 255 | ``` 256 | ### Artificial Bee Algorithm 257 | The aim of a bee swarm is to find the area of a field with the highest density of flowers. WIthout any knoledge about a field bees begin the search of flowers from random positions with random velocity vectors. Each bee can remember positions where the maximul quantity of flowers was found and know where other bees found the maximum density of flowers. When a bee chooses between the place where it found the maximum quantity of flowers and the place which was reported by others, the bee rushes in direction between these two points and desides between personal memory and social reflex. On its way the bee can find a place with more high concentration of flowers than were found previously. In the future this place can be marked as the one with the highest concentration of flowers found by a swarm. After that the whole swarm will rush in the direction of this place, remembering though their own observations. Thus, bees research a field by flying to palces with the highest consentration of flowers. They also continuously compare places they flew over with previously found ones in order to found the absolute maxim concentration of flowers. In the end, a bee ends its flight in the place with the maximum concentration of flowers. Soon the whole swarm will locate in the neighborhood of that place. 258 | #### Mathematical model 259 | In the Artificial Bee Algorithm model, the colony consists of three groups of bees: employed bees, onlookers and scouts. Scouts perform random search, employed bees collect previously found food and onlookers watch the dances of employed bees and choose food sources depending on dances. Onlookers and scouts are called non-working bees. Communication between bees is based on dances. Before a bee starts to collect food it watches dances of other bees. A dance is the way bees describe where food is.
260 | Working and non-working bees search for rich food sources near their hive. A working bee keeps the information about a food source and share it with onlookers. Working bees whose solutions can't be improved after a definite number of attempts become scouts and their solutions are not used after that. The number of food sources represents the nuber of solutions in the population. The position of a food source represents a possible solution to the optimization problem and the nectar amount of a food source corresponds to the quality (fitness) of the associated solution. 261 | #### Algorithm 262 |
263 | BEGIN
264 | Initialize the population
265 | Find current best agent for the initial iteration
266 | Calculate the number of scouts, onlookers and employed bees
267 | SET global best to current best
268 | FOR iterator = 0 : iteration
269 |   evaluate fitness for each agent
270 |   sort fitness in ascending order and get best agents
271 |   from best agents list select agents from a to c
272 |   Create new bees which will fly to the best solution
273 |   Evaluate current best agent
274 |   IF function(current best) < function (global best)
275 |     global best = current best
276 |   END IF
277 | END FOR
278 | Save global best
279 | 
280 | #### Arguments 281 | The aba method accepts only standard arguments
282 | #### Method invocation 283 | The method can be invoked by passing the arguments in the following order: 284 | ``` 285 | SwarmPackagePy.aba(n, function, lb, ub, dimension, iteration) 286 | ``` 287 | ### Firefly Algorithm 288 | Most species of fireflies are able to glow producing short flashes. It is considered that the main function of flashes are to attract fireflies of the opposite sex and potential preys. Besides, a signal flash can communicate to a predator that a firefly has a bitter taste. 289 | #### Mathematical model 290 | The Firefly Algorithm is based on two important things: the change in light intensity and attractiveness. For simplicity, it is assumed that the attractiveness of a firefly is defined by its brightness which is connected with the objective function.
291 | The algorithm utilizes the following firefly behaviour model:
292 | 1. All fireflies are able to attract each other independently of their gender; 293 | 2. A firefly attractiveness for other individuals is proportional to its brightness. 294 | 3. Less attractive fireflies move in the direction of the most attractive one. 295 | 4. As the distance between two fireflies increases, the visible brightness of the given firefly for the other decreases. 296 | 5. If a firefly sees no firefly that is brighter than itself, it moves randomly. 297 | #### Algorithm 298 |
299 |   Objective function f(x), x=(x1, x2, ... , xd)T
300 |   Initialize a population of fireflies xi(i = 1, 2, ... , n)
301 |   Define light absorption coefficient gamma
302 |   WHILE count < MaximumGeneratons
303 |     FOR i = 1 : n (all n fireflies)
304 |       FOR j = 1 : i
305 |       Light intensity Ii at xi is determined by f(xi)
306 |       IF Ii > Ij
307 |           Move firefly i towards j in all d dimensions
308 |         ELSE
309 |           Move firefly i randomly
310 |         END IF
311 |         Attractiveness changes with distance r via exp[-γ r2]
312 |       Determine new solutions and revise light intensity
313 |       END FOR j
314 |     END FOR i
315 |     Rank the fireflies according to light intensity and find the current best
316 |   END WHILE
317 |   
318 | #### Arguments 319 | The fa method accepts the following arguments:
320 | - csi: mutual attraction (default value is 1) 321 | - psi: light absorption coefficient of the medium (default value is 1) 322 | - alpha0: initial value of the free randomization parameter alpha (default value is 1) 323 | - alpha1: final value of the free randomization parameter alpha (default value is 0.1) 324 | - norm0: first parameter for a normal (Gaussian) distribution (default value is 0) 325 | - norm1: second parameter for a normal (Gaussian) distribution (default value is 0.1) 326 | #### Method invocation 327 | The method can be invoked by passing the arguments in the following order: 328 | ``` 329 | SwarmPackagePy.fa(n, function, lb, ub, dimension, iteration, csi, psi, alpha0, alpha1, norm0, norm1) 330 | ``` 331 | ### Cuckoo Search Optimization 332 | #### Mathematical model 333 | In the CSO algorithm each egg in a nest represents the solution and a cuckoo's egg - the new one. The aim is to use potentially the best new solutions in order to substitute the less good solutions in nests. In the simliest case, each nest contains one egg. 334 | The algorithm is based on the following rules: 335 | 1. Every cuckoo lay one egg in a time in a randomly chosen nest; 336 | 2. The best nests with the eggs of high quality pass into a new generation; 337 | 3. An egg laid by a cuckoo in a nest can be found by the nest owner with probability ξa∈(0,1) and removed from the nest. 338 | The CSO algorithm scheme could be described in the following form: 339 | 1. Initialize the population S={si, i∈[1:|S}]} from |S| foreign nests and a cuckoo, i.e. define the initial values of for vector components Xi, i∈[:|S|]} and cuckoo's initial position vector XC; 340 | 2. Make a number of cuckoo's random moves in the search space by performing Levy flights and find the new cuckoo's position XC; 341 | 3. Randomly pick a newt si, i∈[1:|S|] and if f(XC) > f(Xi) then substitute an egg in this nest to the cuckoo's egg, i.e. Xi = XC; 342 | 4. With the probability ξa remove a nubmer of the worst randomely chosen nests (including probably si nest) from population and create the same number of new nests according to the 1st step rules; 343 | 5. Until the stop condition is not sutisfied, proceed to the 2nd step. 344 | #### Algorithm 345 |
346 |   BEGIN
347 |     Generate initial population of n nests xj, (j = 1, 2, ... ,n)
348 |     REPEAT
349 |       Place cuckoo to point xi randomly by performing Levy flights
350 |       Choose nest j among n nests randomly
351 |       IF Fi < Fj
352 |       Replace xj on new solution
353 |       END IF
354 |       Delete from the population nests found with pa probability and build the same number of new nests
355 |       SAVE best solution (nest)
356 |     UNTIL stop criteria
357 |     Postprocess results and visualization
358 |   END
359 |   
360 | #### Arguments 361 | The cso method accepts the following arguments:
362 | - pa: probability of cuckoo's egg detection (default value is 0.5) 363 | - nest: number of nests (default value is 100) 364 | #### Methods 365 | The cso method has the following additional methods:
366 | **get_nests()**: return a history of cuckoos nests 367 | #### Method invocation 368 | The method can be invoked by passing the arguments in the following order: 369 | ``` 370 | SwarmPackagePy.cso(n, function, lb, ub, dimension, iteration, pa=0.25, nest=100) 371 | ``` 372 | ### Whale Swarm Algorithm 373 | Whales are social animal and live in groups. Whales produces sounds of a very wide range. These sounds can often be linked to important functions such as their migration, feeding and mating patterns. Moreover, a large part of sounds made by whales are ultrasound. They determine foods azimuth and keep in touch with each other from a great distance by the ultrasound.
374 | When a whale has found food source, it will make sounds to notify other whales nearby of the quality and quantity of food. So each whale will receive lots of notifications from the neighbors, and then move to hte proper place to find food based on these notifications. 375 | #### Mathematical model 376 | The Whale Swarm Algorithm employes the following rules:
377 | 1. All the whales communicate with each other by ultrasound in the search area; 378 | 2. Each whale has a certain degree of computing ability to calculate the distance to other whales 379 | 3. The quality and quantity of food found by each whale are associated to its fitness 380 | 4. The movement of a whale s guided by the nearest one among the whales that are better (judged by fitness) than it. 381 | #### Algorithm: 382 |
383 |  BEGIN
384 |   Initialize agents
385 |   Find current best
386 |   global best = current best
387 |   FOR t = 0 : number of iterations
388 |     FOR each agent
389 |       find better and nearest
390 |       IF  Exists
391 |         move current agent in direction of its better and nearest
392 |       END IF
393 |       find current best
394 |       IF current best better than global best
395 |         SET global best to current best
396 |       END IF
397 |     END FOR
398 |    Save golobal best
399 |  END
400 |  
401 | #### Arguments 402 | The wsa method accepts the following arguments:
403 | - ro0: intensity of ultrasound at the origin of source 404 | - eta: probability of message distortion at large distances 405 | #### Method invocation 406 | The method can be invoked by passing the arguments in the following order: 407 | ``` 408 | SwarmPackagePy.wsa(n, function, lb, ub, dimension, iteration, ro0=2, eta=0.005) 409 | ``` 410 | ### Firework Algorithm 411 | The way fireworks explode is similar to the way an individual searches the optimal solution in swarm intelligence algorithms. As a swarm intelligence algorithm, fireworks algorithm consists of four parts, i.e., the explosion operator, mutation operator, mapping rule and selection strategy. The effect of the explosion operator is to generate sparks around fireworks. The number and amplitude of the sparks are governed by the explosion operator. After that, some sparks are produced by mutation operator. The mutation operator utilizes Gaussian operator to produce sparks in Gaussian distribution. 412 | Under the effect of the two operators, if the produced spark is not in the feasible region, the mapping rule will map the new generated sparks into the feasible region. 413 | To select the sparks for next generation, the selection strategy is used. Fireworks algorithm runs iteratively until it reaches the termination conditions 414 | #### Algorithm 415 |
416 |  BEGIN
417 |   Initialize agents
418 |   Find current best
419 |   global best = current best
420 | 
421 |   FOR i= 0 : nuber of agents
422 |     evaluate function value for current best and worst
423 |     FOR each agent
424 |       perform explosion
425 |       perform gausian mutation
426 |    END FOR
427 |    apply mapping rule
428 |    Select new agents according to the selection strategy
429 |    IF current best better than global best
430 |         SET global best to current best
431 |    END IF
432 |    END FOR
433 |   save global best
434 | END
435 | 
436 | #### Arguments 437 | The fwa method accepts the following arguments:
438 | - m1: number of normal sparks 439 | - m2: number of Gaussian sparks 440 | #### Method invocation 441 | The method can be invoked by passing the arguments in the following order: 442 | ``` 443 | SwarmPackagePy.wsa( n, function, lb, ub, dimension, iteration, m1, m2, eps, amp) 444 | ``` 445 | ### Particle Swarm Optimization 446 | A flock of birds is a good example of the collective behavior of animals. Flying in a big groups, they almost never collide with each other. A flock moves smoothly and is coordinated as if it is controlled by something and it's not about the leader of the flock. A flock of birds is a swarm intelligence and birds in it act according to certain rules.
447 | The rules are the following: 448 | 1) Every bird tries to avoid collision with others; 449 | 2) Every bird moves in the close birds direction; 450 | 3) Birds try to move on the equal distance from each other; 451 | 4) A bird shares information with neighbours. 452 | #### Mathematical model 453 | In the PSO, agents are particles in the optimization task parameters space. On each iteration particles have some position and a velocity vector. For each position of a particle the corresponding objective function value is calculated and on the basis of that value a particle changes its position and velocity according to certain rules. The pso is a stochastic optimization method. It doesn't update existing populations but works with one static population which members steadily improve as they receive more information about the search space. 454 | #### Algorithm 455 | ``` 456 | BEGIN 457 | Initialize agents 458 | Find current best 459 | Set global best = current best 460 | FOR i= 0 : number of iterations 461 | Calculate particle velocity 462 | Chage particles velocity 463 | Update particles positions 464 | Select new agents according to the selection strategy 465 | IF current best better than global best 466 | SET global best to current best 467 | END IF 468 | END FOR 469 | save global best 470 | END 471 | ``` 472 | #### Arguments 473 | The pso method accepts the following arguments:
474 | - w: balance between the range of research and consideration for suboptimal decisions found (default value is 0.5):
w>1 the particle velocity increases, they fly apart and inspect the space more carefully
w<1 particle velocity decreases, convergence speed depends on parameters c1 and c2
475 | - c1: ratio between "cognitive" and "social" component (default value is 1) 476 | - c2: ratio between "cognitive" and "social" component (default value is 1) 477 | #### Method invocation 478 | The method can be invoked by passing the arguments in the following order: 479 | ``` 480 | SwarmPackagePy.pso(n, function, lb, ub, dimension, iteration, w=0.5, c1=1, c2=1) 481 | ``` 482 | ### Chicken Swarm Optimization 483 | The CHSO algorithm mimics the hierarchal order in the chicken swarm and the behaviours of the chicken swarm. The chicken swarm can be divided into several groups, each of which consists of one rooster and many hens and chicks. Different chickens follow different laws of motions. There exist competitions between different chickens under specific hierarchal order.
484 | Domestic chickens live in flocks. There are over 30 distinct sounds for their communication by which they can communicate alot of information related to nesting, food discovery, mating and danger. Besides learning through trial and error, the chickens would also learn from their previous experience and others' for makein decisions.
485 | A hierarchal order palys a significant fole in the social lives of chickens. The preponderant chickens in a flock willl dominate the weak. There exist the more dominant hens that remain near to the head roosters as well as the more submissive hens nad roosters who stand at the periphery of the group. Removing or adding chickens from an existing group would causes a temporary disruption to the social order until a specific order is establicshed.
486 | #### Mathematical model 487 | In the SHCO algorithm the chickens' behaviours are described by the following rules: 488 | 1. In the chicken swarm, there exist several groups. Each group comprises a dominant rooster, a couple of hens, and chicks. 489 | 2. How to divide the chicken swarm into several groups and determine the identity of the chickens (roosters, hens and chicks) all depend on the fitness values of the chickens themselves. The chickens with best several fitness values would be acted as roosters, each of which would be the head rooster in a group. The chickens with worst several fitness values would be designated as chick. the others would be the hens. The hens randomly choose which group to live in. The mother-child relationship between the hens and the chicks os also randomly established. 490 | 3. The hierarchal order, dominance relationship and mother-child relationship in a group will remain unchanged. These statuses only update every several time steps. 491 | 4. Chickens follow their group-mate rooster to search for food, while they may prevent the ones from eating their own food. Assume chickens would randomly steal the good food already found by others. The chicks search for food around their mother (hen). The dominant individuals have advantage in competition for food. 492 | #### Algorithm 493 | ``` 494 | BEGIN 495 | Initialize a population of N chickens and define the related parameters 496 | Evaluate the N chickens' fitness values 497 | Find current best 498 | Set global best = current best 499 | FOR t = 0 : number of iterations 500 | IF(t % G == 0) 501 | Rank the chickens' fintess values and establish a hierarchal order in the swarm 502 | Divide the swarm into different groups, and determine the relationship 503 | between the chicks and mother hens in a goup 504 | END IF 505 | FOR i = 1 : N 506 | IF i == rooster 507 | Update its solution and location using equation for roosters 508 | END IF 509 | IF i == hen 510 | Update its solution and location using equation for hens 511 | END IF 512 | IF i == chick 513 | Update its solution and location using equation for chicks 514 | END IF 515 | Evaluate current best 516 | IF current best better than global best 517 | SET global best to current best 518 | END IF 519 | END FOR 520 | END 521 | ``` 522 | #### Arguments 523 | The chso method accepts the following arguments:
524 | - G: after what time relationship will be upgraded (default value is 5) 525 | - FL: parameter, which means that the chick would follow its mother to forage for food (0 < FL < 2. Default value is 0.5) 526 | #### Method invocation 527 | The method can be invoked by passing the arguments in the following order: 528 | ``` 529 | SwarmPackagePy.chso(n, function, lb, ub, dimension, iteration, G=5, FL=0.5) 530 | ``` 531 | ### Social Spider Algorightm 532 | The Social Spider Algorightm mimics the social spiders colony behaviour. These spiders form colonies which allow them to remain together on a communal network.
533 | A social spicer colony consists of two main components: its members and its communal network. All members are divided into two different groups: males and females. 534 | #### Mathematical model 535 | The SSO assumes that entire search space is a communal web, where all the social-spiders interact to each other. Each solution within the search space represents a spider position in the communal web. Every spider receives a weight according to the fitness value of the solution that is symbolized by the social-spider. The algorithm models two different search agents (spiders): males and females. Depending on gender, each individual is conducted by a set of different evolutionary operators which mimic different cooperative behaviors that are commonly assumed within the colony. One of characteristics of social-spiders is the highly female-biased populations. 536 | In order to emulate this fact, the algorithm starts by defining the number of female and male spiders that will be characterized as individuals in the search space. 537 | #### Algorithm 538 |
539 | BEGIN
540 |   Create the population of spiders
541 |   Initialize target vibration for each spider
542 |   FOR i = 0 : number of iterations
543 |     FOR each spider in population
544 |       Evaluate the fitness values of a spider
545 |       Generate a vibration at the position of the spider
546 |     END FOR
547 |     FOR each spider in population
548 |       Calculate the intensity of the vibrations generated bu other spiders
549 |       Select the strongest vibration from all vibrations
550 |       IF the intensit of the strongest vibration is larger than target vibration
551 |         target vibration = strongest vibration
552 |       END IF
553 |       Perform a random walk towards target vibration
554 |       Generate a random number rn from [0,1)
555 |       IF rn < pj
556 |         Assign a random position to the spider
557 |       END IF
558 |       Attenuate the intensity of target vibration
559 |     END FOR
560 |   END FOR
561 |   Save the best solution
562 | END
563 | 
564 | #### Arguments 565 | The ssa method accepts the following arguments:
566 | - pf: random parameter from 0 to 1 (default value is 0.4) 567 | #### Method invocation 568 | The method can be invoked by passing the arguments in the following order: 569 | ``` 570 | SwarmPackagePy.ssa(n, function, lb, ub, dimension, iteration, pf=0.4) 571 | ``` 572 | ### Cat Algorithm (Cat Swarm Optimization) 573 | Cat Algorithm mimics the two aspects of cats behaviour: seeking mode and tracking mode. Every cat has its own position composed of M dimensions, velocities for each di-mension, a fitness value, which represents the accommodation of the cat to the fitness function, and a flag to identify whether the cat is in seeking mode or tracing mode. The final solution would be the best position in one of the cats due to CSO keeps the best solution till it reaches the end of iterations. 574 | #### Mathematical model 575 | **Seeking mode** is used to model the situation of the cat, which is resting, looking around and seeking the next position to move to. In seeking mode, the four essential factors are defined: seeking memory pool (SMP), seeking range of the selected dimension (SRD), counts of dimension to change (CDC), and self-position considering (SPC).
576 | For the seeking mode the following algorithm is proposed: 577 |
578 | FOR each cat-agent
579 |   Create j = SMP copies
580 |   IF SPC is true
581 |     j = SMP - 1
582 |     Save copies
583 |   END IF
584 | END FOR
585 | FOR each copy
586 |   Randomly add (or subtract) SRD
587 | END FOR
588 | FOR each copy
589 |   Calculate fitness function value FSi
590 | END FOR
591 | IF all values of the fitness function are not equal to each other
592 |   Calculate Pi
593 | END IF
594 | IF FSi are equal
595 |   Pi = 1
596 | END IF
597 | FSb = FSmin
598 | Replace cat-agent with its copy
599 | 
600 | **Tracing mode** is the second mode of a cat. In this mode the cat tracks down and attacks its prey.
601 | In tracing mode the algorithm works as follows: 602 |
603 | Calculate new velocity vector value for each cat
604 | Calculate new position of a cat
605 | 
606 | #### Algorithm 607 |
608 | Initialize n cats in the domain D randomly (Initially each cat has zero velocity vector)
609 | Generate a flag for each cat
610 | FOR number of iterations
611 |   Calculate Pbest
612 |   Move each cat considering its flag:
613 |     IF flag = 0
614 |       Perform seeking mode
615 |     ELSE
616 |       Perform tracing mode
617 |     END IF
618 |   Redistribute the flags
619 | END FOR
620 | 
621 | #### Arguments 622 | The ca method accepts the following arguments:
623 | - mr: number of cats that hunt (default value is 10) 624 | - smp: seeking memory pool (default value is 2) 625 | - spc: self-position considering (default value is False) 626 | - cdc: counts of dimension to change (default value is 1) 627 | - srd: seeking range of the selected dimension (default value is 0.1) 628 | - w: constant (default value is 0.1) 629 | - c: constant (default value is 1.05) 630 | - csi: constant (default value is 0.6) 631 | #### Method invocation 632 | The method can be invoked by passing the arguments in the following order: 633 | ``` 634 | SwarmPackagePy.ca(n, function, lb, ub, dimension, iteration, mr=10, smp=2, 635 | spc=False, cdc=1, srd=0.1, w=0.1, c=1.05, csi=0.6) 636 | ``` 637 | ### Harmony Search 638 | This algorithm mimics the jazz play technique. In its base lays the observation that an experienced musician can quickly adapt to play with other musicians or improvise a good melody. 639 | #### Mathematical model 640 | Each musician corresponds to an attribute in a candidate solution from a problem domain, and each instrument's pitch and range corresponds to the bounds and constraints on the decision variable. The harmony between the musicians is taken as a complete candidate solution at a given time, and the audiences aesthetic appreciation of the harmony represent the problem specific cost function. The musicians seek harmony over time through small variations and improvisations, which results in an improvement against the cost function. 641 | The information processing objective of the technique is to use good candidate solutions already discovered to influence the creation of new candidate solutions toward locating the problems optima. This is achieved by stochastically creating candidate solutions in a step-wise manner, where each component is either drawn randomly from a memory of high-quality solutions, adjusted from the memory of high-quality solutions, or assigned randomly within the bounds of the problem. The memory of candidate solutions is initially random, and a greedy acceptance criteria is used to admit new candidate solutions only if they have an improved objective value, replacing an existing member. 642 | #### Algorithm 643 |
644 | Step 1. Randomly generate initial harmony in the domain D {hi ∈ D}.
645 | Step 2. On each iteration generate new zero harmony hnew
646 | Step 3. For each component of a new harmony generate a random number ε from 0 to 1. If ε is less than HMCR, then write in the current component the corresponding copmonent from a randomly chosen existing harmony. After that modify the component.
647 | Step 4. IF f(hnew) is better than Gbest, hnew = hGbest
648 | 
649 | #### Arguments 650 | The hs method accepts the following arguments:
651 | - pitch adjusting rate (default value is 0.5) 652 | - hmcr: harmony consideration rate (default value is 0.5) 653 | - bw: bandwidth (default value is 0.5) 654 | #### Method invocation 655 | The method can be invoked by passing the arguments in the following order: 656 | ``` 657 | SwarmPackagePy.hs(n, function, lb, ub, dimension, iteration, par=0.5, hmcr=0.5, bw=0.5) 658 | ``` 659 | ### Gravitational Search Algorithm 660 | The Gravitational Search Algorithm is based on the laws of gravitation and mass interaction. Basically, this algorithm is similar to Particle Swarm Optimization (PSO), since they are both based on the development of a multi-agent system. 661 | #### Mathematical model 662 | GSA operates with two laws:
663 | * law of gravitation: each particle attracts other particles and force of gravity betweent two particles is directly proportional to the product of their masses and inversly proportional to the distance between them (one should pay attention to the fact that, unlike the law of universal gravitation, we don't use the square of the distance, as it results in better results of the algorithm).
664 |
F1 = F2 = G * (m1╳m2)*r-2
665 | 666 | * law of motion: the current velocity of any particle is equal to the sum of the part of the velocity at the previous instant of time and to the change in velocity which is equal to the force the system affects the particle with divided by the inertial mass of the particle. 667 | #### Algorithm 668 |
669 | 1. Generate the system randomly;
670 | 2. Determine the fitness of each particle;
671 | 3. Update the value of the gravitational constant, masses and the best and the worst particle values;
672 | 4. Calculate the resultant force in different directions;
673 | 5. Calculate accelerations and velocities;
674 | 6. Update particles' positions;
675 | 7. Repeat steps 2 to 6 until the stop condition is reached.
676 | 
677 | 
678 | 679 | ### Tests 680 | All algorithms were tested with different test functions. In fact, you can run tests for all the algorithms on your own. All you need to do is to open terminal (console) and insert the following line: 681 | ``` 682 | pytest -v —tb=line test.py 683 | ``` 684 | Every algorithm is tested with the following set of test functions:
685 | - Ackley function 686 | - Bukin function 687 | - Cross in tray function 688 | - Sphere function 689 | - Bohachevsky function 690 | - Sum squares function 691 | - Sum of different powers function 692 | - Booth function 693 | - Matyas function 694 | - McCormick function 695 | - Dixon price function 696 | - Six hump camel function 697 | - Three hump camel function 698 | - Easom function 699 | - Michalewicz function 700 | - Beale function 701 | - drop wave function 702 | 703 | ### Animation 704 | There are 2D animation and 3D animation of search process. The general way to start it is (example for pso algorithm):
705 | #### 2D animation 706 | ``` 707 | # Compute the algorithm 708 | function = SwarmPackagePy.testFunctions.easom_function 709 | alh = SwarmPackagePy.pso(15, function, -10, 10, 2, 20) 710 | # Show animation 711 | animation(alh.get_agents(), function, 10, -10) 712 | ``` 713 | #### 3D animation 714 | ``` 715 | # Compute the algorithm 716 | function = SwarmPackagePy.testFunctions.easom_function 717 | alh = SwarmPackagePy.pso(15, function, -10, 10, 2, 20) 718 | # Show animation 719 | animation3D(alh.get_agents(), function, 10, -10) 720 | ``` 721 | #### Save the animation 722 | You can also save the animation of the search process. To do this, add as an animation argument sr=True. The example of saving animation: 723 | ``` 724 | # Compute the algorithm 725 | function = SwarmPackagePy.testFunctions.easom_function 726 | alh = SwarmPackagePy.pso(15, function, -10, 10, 2, 20) 727 | # Show animation 728 | animation(alh.get_agents(), function, 10, -10, sr=True) 729 | ``` 730 | -------------------------------------------------------------------------------- /SwarmPackagePy/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | SwarmPackagePy 3 | ============== 4 | 5 | 6 | Provides: 7 | 1. Swarm optimization algorithms. 8 | 2. Test functions for swarm algorithms. 9 | 3. Animation of algorithm computation. 10 | 11 | 12 | To compute any algorithm you need to create an object like below 13 | ---------------------------------------------------------------- 14 | 15 | >>> alh = SwarmPackagePy.alg(n, function, lb, ub, dimension, iteration) 16 | 17 | Where: 18 | alg: name of required algorithm 19 | n: number of agents 20 | function: test function (function must be an object, that accepts 21 | coordinates of a point as init parameter) 22 | lb: lower limits for plot axes 23 | ub: upper limits for plot axes 24 | dimension: space dimension 25 | iteration: number of iterations 26 | 27 | !Note: almost every algorithm has additional parameters. But they are all 28 | have default value. To view additional parameters of any algorithm type: 29 | 30 | >>> help(SwarmPackagePy.alg) 31 | 32 | 33 | Example of computation pso algorithm for 2 dimensions with easom function 34 | ------------------------------------------------------------------------- 35 | 36 | >>> function = SwarmPackagePy.testFunctions.easom_function 37 | >>> alh = SwarmPackagePy.pso(15, function, -10, 10, 2, 20) 38 | 39 | To get the best position of an algorithm use "get_Gbest()" method: 40 | 41 | >>> alh.get_Gbest() 42 | 43 | To watch animation for algorithm: 44 | 45 | >>> animation(alh.get_agents(), function, 10, -10, sr=False) 46 | 47 | 48 | 3D version 49 | ---------- 50 | 51 | >>> function = SwarmPackagePy.testFunctions.easom_function 52 | >>> alh = SwarmPackagePy.pso(15, function, -10, 10, 3, 20) 53 | >>> animation3D(alh.get_agents(), function, 10, -10, sr=False) 54 | 55 | Avaible test functions (in SwarmPackagePy.testFunctions) 56 | -------------------------------------------------------- 57 | 58 | ackley_function 59 | bukin_function 60 | cross_in_tray_function 61 | sphere_function 62 | bohachevsky_function 63 | sum_squares_function 64 | sum_of_different_powers_function 65 | booth_function 66 | matyas_function 67 | mccormick_function 68 | dixon_price_function 69 | six_hump_camel_function 70 | three_hump_camel_function 71 | easom_function 72 | michalewicz_function 73 | beale_function 74 | drop_wave_function 75 | """ 76 | 77 | from SwarmPackagePy.aba import aba 78 | from SwarmPackagePy.ba import ba 79 | from SwarmPackagePy.bfo import bfo 80 | from SwarmPackagePy.chso import chso 81 | from SwarmPackagePy.cso import cso 82 | from SwarmPackagePy.fa import fa 83 | from SwarmPackagePy.fwa import fwa 84 | from SwarmPackagePy.gsa import gsa 85 | from SwarmPackagePy.gwo import gwo 86 | from SwarmPackagePy.pso import pso 87 | from SwarmPackagePy.ca import ca 88 | from SwarmPackagePy.hs import hs 89 | from SwarmPackagePy.ssa import ssa 90 | from SwarmPackagePy.wsa import wsa 91 | from SwarmPackagePy.animation import animation, animation3D 92 | 93 | _version_ = '1.0.0' 94 | -------------------------------------------------------------------------------- /SwarmPackagePy/aba.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from random import randint, uniform 3 | 4 | from . import intelligence 5 | 6 | 7 | class aba(intelligence.sw): 8 | """ 9 | Artificial Bee Algorithm 10 | """ 11 | 12 | def __init__(self, n, function, lb, ub, dimension, iteration): 13 | """ 14 | :param n: number of agents 15 | :param function: test function 16 | :param lb: lower limits for plot axes 17 | :param ub: upper limits for plot axes 18 | :param dimension: space dimension 19 | :param iteration: number of iterations 20 | """ 21 | 22 | super(aba, self).__init__() 23 | 24 | self.__function = function 25 | 26 | self.__agents = np.random.uniform(lb, ub, (n, dimension)) 27 | self._points(self.__agents) 28 | 29 | Pbest = self.__agents[np.array([function(x) 30 | for x in self.__agents]).argmin()] 31 | Gbest = Pbest 32 | 33 | if n <= 10: 34 | count = n - n // 2, 1, 1, 1 35 | else: 36 | a = n // 10 37 | b = 5 38 | c = (n - a * b - a) // 2 39 | d = 2 40 | count = a, b, c, d 41 | 42 | for t in range(iteration): 43 | 44 | fitness = [function(x) for x in self.__agents] 45 | sort_fitness = [function(x) for x in self.__agents] 46 | sort_fitness.sort() 47 | 48 | best = [self.__agents[i] for i in 49 | [fitness.index(x) for x in sort_fitness[:count[0]]]] 50 | selected = [self.__agents[i] 51 | for i in [fitness.index(x) 52 | for x in sort_fitness[count[0]:count[2]]]] 53 | 54 | newbee = self.__new(best, count[1], lb, ub) + self.__new(selected, 55 | count[3], 56 | lb, ub) 57 | m = len(newbee) 58 | self.__agents = newbee + list(np.random.uniform(lb, ub, (n - m, 59 | dimension))) 60 | 61 | self.__agents = np.clip(self.__agents, lb, ub) 62 | self._points(self.__agents) 63 | 64 | Pbest = self.__agents[ 65 | np.array([function(x) for x in self.__agents]).argmin()] 66 | if function(Pbest) < function(Gbest): 67 | Gbest = Pbest 68 | 69 | self._set_Gbest(Gbest) 70 | 71 | def __new(self, l, c, lb, ub): 72 | 73 | bee = [] 74 | for i in l: 75 | new = [self.__neighbor(i, lb, ub) for k in range(c)] 76 | bee += new 77 | bee += l 78 | 79 | return bee 80 | 81 | def __neighbor(self, who, lb, ub): 82 | 83 | neighbor = np.array(who) + uniform(-1, 1) * ( 84 | np.array(who) - np.array( 85 | self.__agents[randint(0, len(self.__agents) - 1)])) 86 | neighbor = np.clip(neighbor, lb, ub) 87 | 88 | return list(neighbor) 89 | -------------------------------------------------------------------------------- /SwarmPackagePy/animation.py: -------------------------------------------------------------------------------- 1 | from matplotlib import pyplot as plt 2 | import matplotlib.animation 3 | from matplotlib.ticker import LinearLocator, FormatStrFormatter 4 | from mpl_toolkits.mplot3d import Axes3D 5 | import numpy as np 6 | import pandas as pd 7 | 8 | 9 | def animation(agents, function, lb, ub, sr=False): 10 | 11 | side = np.linspace(lb, ub, (ub - lb) * 5) 12 | X, Y = np.meshgrid(side, side) 13 | Z = np.array([np.array([function([X[i][j], Y[i][j]]) 14 | for j in range(len(X))]) 15 | for i in range(len(X[0]))]) 16 | 17 | fig = plt.figure() 18 | plt.axes(xlim=(lb, ub), ylim=(lb, ub)) 19 | plt.pcolormesh(X, Y, Z, shading='gouraud') 20 | plt.colorbar() 21 | 22 | x = np.array([j[0] for j in agents[0]]) 23 | y = np.array([j[1] for j in agents[0]]) 24 | sc = plt.scatter(x, y, color='black') 25 | 26 | plt.title(function.__name__, loc='left') 27 | 28 | def an(i): 29 | x = np.array([j[0] for j in agents[i]]) 30 | y = np.array([j[1] for j in agents[i]]) 31 | sc.set_offsets(list(zip(x, y))) 32 | plt.title('iteration: {}'.format(i), loc='right') 33 | 34 | ani = matplotlib.animation.FuncAnimation(fig, an, frames=len(agents) - 1) 35 | 36 | if sr: 37 | 38 | ani.save('result.mp4') 39 | 40 | plt.show() 41 | 42 | 43 | def animation3D(agents, function, lb, ub, sr=False): 44 | 45 | side = np.linspace(lb, ub, 45) 46 | X, Y = np.meshgrid(side, side) 47 | zs = np.array([function([x, y]) for x, y in zip(np.ravel(X), np.ravel(Y))]) 48 | Z = zs.reshape(X.shape) 49 | 50 | fig = plt.figure() 51 | 52 | ax = Axes3D(fig) 53 | surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='jet', 54 | linewidth=0, antialiased=False) 55 | ax.set_xlim(lb, ub) 56 | ax.set_ylim(lb, ub) 57 | 58 | ax.zaxis.set_major_locator(LinearLocator(10)) 59 | ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f')) 60 | 61 | fig.colorbar(surf, shrink=0.5, aspect=5) 62 | 63 | iter = len(agents) 64 | n = len(agents[0]) 65 | t = np.array([np.ones(n) * i for i in range(iter)]).flatten() 66 | b = [] 67 | [[b.append(agent) for agent in epoch] for epoch in agents] 68 | c = [function(x) for x in b] 69 | a = np.asarray(b) 70 | df = pd.DataFrame({"time": t, "x": a[:, 0], "y": a[:, 1], "z": c}) 71 | 72 | def update_graph(num): 73 | data = df[df['time'] == num] 74 | graph._offsets3d = (data.x, data.y, data.z) 75 | title.set_text(function.__name__ + " " * 45 + 'iteration: {}'.format( 76 | num)) 77 | 78 | title = ax.set_title(function.__name__ + " " * 45 + 'iteration: 0') 79 | 80 | data = df[df['time'] == 0] 81 | graph = ax.scatter(data.x, data.y, data.z, color='black') 82 | 83 | ani = matplotlib.animation.FuncAnimation(fig, update_graph, iter, 84 | interval=50, blit=False) 85 | 86 | if sr: 87 | 88 | ani.save('result.mp4') 89 | 90 | plt.show() 91 | -------------------------------------------------------------------------------- /SwarmPackagePy/ba.py: -------------------------------------------------------------------------------- 1 | from math import exp 2 | import numpy as np 3 | from random import random 4 | 5 | from . import intelligence 6 | 7 | 8 | class ba(intelligence.sw): 9 | """ 10 | Bat Algorithm 11 | """ 12 | 13 | def __init__(self, n, function, lb, ub, dimension, iteration, r0=0.9, 14 | V0=0.5, fmin=0, fmax=0.02, alpha=0.9, csi=0.9): 15 | """ 16 | :param n: number of agents 17 | :param function: test function 18 | :param lb: lower limits for plot axes 19 | :param ub: upper limits for plot axes 20 | :param dimension: space dimension 21 | :param iteration: number of iterations 22 | :param r0: level of impulse emission (default value is 0.9) 23 | :param V0: volume of sound (default value is 0.5) 24 | :param fmin: min wave frequency (default value is 0) 25 | :param fmax: max wave frequency (default value is 0.02) 26 | fmin = 0 and fmax =0.02 - the bests values 27 | :param alpha: constant for change a volume of sound 28 | (default value is 0.9) 29 | :param csi: constant for change a level of impulse emission 30 | (default value is 0.9) 31 | """ 32 | 33 | super(ba, self).__init__() 34 | 35 | r = [r0 for i in range(n)] 36 | 37 | self.__agents = np.random.uniform(lb, ub, (n, dimension)) 38 | self._points(self.__agents) 39 | 40 | velocity = np.zeros((n, dimension)) 41 | V = [V0 for i in range(n)] 42 | 43 | Pbest = self.__agents[np.array([function(i) 44 | for i in self.__agents]).argmin()] 45 | Gbest = Pbest 46 | 47 | f = fmin + (fmin - fmax) 48 | 49 | for t in range(iteration): 50 | 51 | sol = self.__agents 52 | 53 | F = f * np.random.random((n, dimension)) 54 | velocity += (self.__agents - Gbest) * F 55 | sol += velocity 56 | 57 | for i in range(n): 58 | if random() > r[i]: 59 | sol[i] = Gbest + np.random.uniform(-1, 1, ( 60 | 1, dimension)) * sum(V) / n 61 | 62 | for i in range(n): 63 | if function(sol[i]) < function(self.__agents[i]) \ 64 | and random() < V[i]: 65 | self.__agents[i] = sol[i] 66 | V[i] *= alpha 67 | r[i] *= (1 - exp(-csi * t)) 68 | 69 | self.__agents = np.clip(self.__agents, lb, ub) 70 | self._points(self.__agents) 71 | 72 | Pbest = self.__agents[ 73 | np.array([function(x) for x in self.__agents]).argmin()] 74 | if function(Pbest) < function(Gbest): 75 | Gbest = Pbest 76 | 77 | self._set_Gbest(Gbest) 78 | -------------------------------------------------------------------------------- /SwarmPackagePy/bfo.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from random import random 3 | 4 | from . import intelligence 5 | 6 | 7 | class bfo(intelligence.sw): 8 | """ 9 | Bacteria Foraging Optimization 10 | """ 11 | 12 | def __init__(self, n, function, lb, ub, dimension, iteration, 13 | Nc=2, Ns=12, C=0.2, Ped=1.15): 14 | """ 15 | :param n: number of agents 16 | :param function: test function 17 | :param lb: lower limits for plot axes 18 | :param ub: upper limits for plot axes 19 | :param dimension: space dimension 20 | :param iteration: the number of iterations 21 | :param Nc: number of chemotactic steps (default value is 2) 22 | :param Ns: swimming length (default value is 12) 23 | :param C: the size of step taken in the random direction specified by 24 | the tumble (default value is 0.2) 25 | :param Ped: elimination-dispersal probability (default value is 1.15) 26 | """ 27 | 28 | super(bfo, self).__init__() 29 | 30 | self.__agents = np.random.uniform(lb, ub, (n, dimension)) 31 | self._points(self.__agents) 32 | 33 | n_is_even = True 34 | if n & 1: 35 | n_is_even = False 36 | 37 | J = np.array([function(x) for x in self.__agents]) 38 | Pbest = self.__agents[J.argmin()] 39 | Gbest = Pbest 40 | 41 | C_list = [C - C * 0.9 * i / iteration for i in range(iteration)] 42 | Ped_list = [Ped - Ped * 0.5 * i / iteration for i in range(iteration)] 43 | 44 | J_last = J[::1] 45 | 46 | for t in range(iteration): 47 | 48 | J_chem = [J[::1]] 49 | 50 | for j in range(Nc): 51 | for i in range(n): 52 | dell = np.random.uniform(-1, 1, dimension) 53 | self.__agents[i] += C_list[t] * np.linalg.norm(dell) * dell 54 | 55 | for m in range(Ns): 56 | if function(self.__agents[i]) < J_last[i]: 57 | J_last[i] = J[i] 58 | self.__agents[i] += C_list[t] * np.linalg.norm(dell) \ 59 | * dell 60 | else: 61 | dell = np.random.uniform(-1, 1, dimension) 62 | self.__agents[i] += C_list[t] * np.linalg.norm(dell) \ 63 | * dell 64 | 65 | J = np.array([function(x) for x in self.__agents]) 66 | J_chem += [J] 67 | 68 | J_chem = np.array(J_chem) 69 | 70 | J_health = [(sum(J_chem[:, i]), i) for i in range(n)] 71 | J_health.sort() 72 | alived_agents = [] 73 | for i in J_health: 74 | alived_agents += [list(self.__agents[i[1]])] 75 | 76 | if n_is_even: 77 | alived_agents = 2*alived_agents[:n//2] 78 | self.__agents = np.array(alived_agents) 79 | else: 80 | alived_agents = 2*alived_agents[:n//2] +\ 81 | [alived_agents[n//2]] 82 | self.__agents = np.array(alived_agents) 83 | 84 | if t < iteration - 2: 85 | for i in range(n): 86 | r = random() 87 | if r >= Ped_list[t]: 88 | self.__agents[i] = np.random.uniform(lb, ub, dimension) 89 | 90 | J = np.array([function(x) for x in self.__agents]) 91 | self._points(self.__agents) 92 | 93 | Pbest = self.__agents[J.argmin()] 94 | if function(Pbest) < function(Gbest): 95 | Gbest = Pbest 96 | 97 | self._set_Gbest(Gbest) 98 | -------------------------------------------------------------------------------- /SwarmPackagePy/ca.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from random import choice, randint, random 3 | 4 | from . import intelligence 5 | 6 | 7 | class ca(intelligence.sw): 8 | """ 9 | Cat Algorithm (Cat Swarm Optimization) 10 | """ 11 | 12 | def __init__(self, n, function, lb, ub, dimension, iteration, mr=10, smp=2, 13 | spc=False, cdc=1, srd=0.1, w=0.1, c=1.05, csi=0.6): 14 | """ 15 | :param n: number of agents 16 | :param function: test function 17 | :param lb: lower limits for plot axes 18 | :param ub: upper limits for plot axes 19 | :param dimension: space dimension 20 | :param iteration: number of iterations 21 | :param mr: number of cats that hunt (default value is 10) 22 | :param smp: seeking memory pool (default value is 2) 23 | :param spc: self-position considering (default value is False) 24 | :param cdc: counts of dimension to change (default value is 1) 25 | :param srd: seeking range of the selected dimension 26 | (default value is 0.1) 27 | :param w: constant (default value is 0.1) 28 | :param c: constant (default value is 1.05) 29 | :param csi: constant (default value is 0.6) 30 | """ 31 | 32 | super(ca, self).__init__() 33 | 34 | self.__agents = np.random.uniform(lb, ub, (n, dimension)) 35 | velocity = np.zeros((n, dimension)) 36 | self._points(self.__agents) 37 | 38 | Pbest = self.__agents[np.array([function(x) 39 | for x in self.__agents]).argmin()] 40 | Gbest = Pbest 41 | 42 | flag = self.__set_flag(n, mr) 43 | if spc: 44 | sm = smp - 1 45 | else: 46 | sm = smp 47 | 48 | for t in range(iteration): 49 | 50 | for i in range(n): 51 | 52 | if flag[i] == 0: 53 | 54 | if spc: 55 | 56 | cop = self.__change_copy([self.__agents[i]], cdc, srd)[ 57 | 0] 58 | tmp = [self.__agents[i] for j in range(sm)] 59 | tmp.append(cop) 60 | copycat = np.array(tmp) 61 | 62 | else: 63 | copycat = np.array([self.__agents[i] for j in range( 64 | sm)]) 65 | copycat = self.__change_copy(copycat, cdc, srd) 66 | 67 | if copycat.all() == np.array( 68 | [copycat[0] for j in range(sm)]).all(): 69 | P = np.array([1 for j in range(len(copycat))]) 70 | 71 | else: 72 | 73 | fb = min([function(j) for j in copycat]) 74 | fmax = max([function(j) for j in copycat]) 75 | fmin = min([function(j) for j in copycat]) 76 | P = np.array( 77 | [abs(function(j) - fb) / (fmax - fmin) for j in 78 | copycat]) 79 | self.__agents[i] = copycat[P.argmax()] 80 | 81 | else: 82 | 83 | ww = w + (iteration - t) / (2 * iteration) 84 | cc = c - (iteration - t) / (2 * iteration) 85 | r = random() 86 | velocity[i] = ww * np.array(velocity[i]) + r * cc * ( 87 | np.array(Pbest) - np.array(self.__agents[i])) 88 | vinf, cinf = self.__get_inf(i, velocity, self.__agents, 89 | csi) 90 | self.__agents[i] = list(1 / 2 * (vinf + cinf)) 91 | 92 | Pbest = self.__agents[ 93 | np.array([function(x) for x in self.__agents]).argmin()] 94 | if function(Pbest) < function(Gbest): 95 | Gbest = Pbest 96 | self.__agents = np.clip(self.__agents, lb, ub) 97 | flag = self.__set_flag(n, mr) 98 | self._points(self.__agents) 99 | 100 | self._set_Gbest(Gbest) 101 | 102 | def __set_flag(self, n, mr): 103 | 104 | flag = [0 for i in range(n)] 105 | m = mr 106 | while m > 0: 107 | tmp = randint(0, n - 1) 108 | if flag[tmp] == 0: 109 | flag[tmp] = 1 110 | m -= 1 111 | 112 | return flag 113 | 114 | def __change_copy(self, copycat, cdc, crd): 115 | 116 | for i in range(len(copycat)): 117 | flag = [0 for k in range(len(copycat[i]))] 118 | c = cdc 119 | while c > 0: 120 | tmp = randint(0, len(copycat[i]) - 1) 121 | if flag[tmp] == 0: 122 | c -= 1 123 | copycat[i][tmp] = copycat[i][tmp] + choice([-1, 1]) * crd 124 | 125 | return copycat 126 | 127 | def __get_inf(self, i, velocity, cat, csi): 128 | 129 | if i == 0: 130 | 131 | vinf = np.array(velocity[i]) + (csi * np.array(velocity[1]) + ( 132 | 1 - csi) * np.array(velocity[2])) / 2 + \ 133 | (csi * np.array(velocity[-1]) + (1 - csi) * np.array( 134 | velocity[-2])) / 2 135 | 136 | cinf = np.array(cat[i]) + (csi * np.array(cat[1]) + (1 - csi) * 137 | np.array(cat[2])) / 2 + \ 138 | (csi * np.array(cat[-1]) + (1 - csi) * np.array(cat[-2])) / 2 139 | 140 | elif i == 1: 141 | 142 | vinf = np.array(velocity[i]) + (csi * np.array(velocity[2]) + ( 143 | 1 - csi) * np.array(velocity[3])) / 2 + \ 144 | (csi * np.array(velocity[0]) + (1 - csi) * np.array( 145 | velocity[-1])) / 2 146 | 147 | cinf = np.array(cat[i]) + (csi * np.array(cat[2]) + ( 148 | 1 - csi) * np.array(cat[3])) / 2 + \ 149 | (csi * np.array(cat[0]) + (1 - csi) * np.array(cat[-1])) / 2 150 | 151 | elif i == len(velocity) - 1: 152 | 153 | vinf = np.array(velocity[i]) + (csi * np.array(velocity[0]) + ( 154 | 1 - csi) * np.array(velocity[1])) / 2 + \ 155 | (csi * np.array(velocity[i - 1]) + (1 - csi) * np.array( 156 | velocity[i - 2])) / 2 157 | 158 | cinf = np.array(cat[i]) + (csi * np.array(cat[0]) + (1 - csi 159 | ) * np.array(cat[1])) / 2 + \ 160 | (csi * np.array(cat[i - 1]) + (1 - csi 161 | ) * np.array(cat[i - 2])) / 2 162 | 163 | elif i == len(velocity) - 2: 164 | 165 | vinf = np.array(velocity[i]) + (csi * np.array(velocity[i + 1] 166 | ) + (1 - csi) * np.array(velocity[0])) / 2 + \ 167 | (csi * np.array(velocity[i - 1]) + (1 - csi 168 | ) * np.array(velocity[i - 2])) / 2 169 | 170 | cinf = np.array(cat[i]) + (csi * np.array(cat[i + 1] 171 | ) + (1 - csi) * np.array(cat[0])) / 2 + \ 172 | (csi * np.array(cat[i - 1]) + (1 - csi 173 | ) * np.array(cat[i - 2])) / 2 174 | 175 | else: 176 | 177 | vinf = np.array(velocity[i]) + (csi * np.array(velocity[i + 1]) + ( 178 | 1 - csi) * np.array(velocity[i + 2])) / 2 + \ 179 | (csi * np.array(velocity[i - 1]) + (1 - csi 180 | ) * np.array(velocity[i - 2])) / 2 181 | 182 | cinf = np.array(cat[i]) + (csi * np.array(cat[i + 1] 183 | ) + (1 - csi) * np.array(cat[i + 2])) / 2 + \ 184 | (csi * np.array(cat[i - 1]) + (1 - csi 185 | ) * np.array(cat[i - 2])) / 2 186 | 187 | return vinf, cinf 188 | -------------------------------------------------------------------------------- /SwarmPackagePy/chso.py: -------------------------------------------------------------------------------- 1 | from math import ceil, exp 2 | import numpy as np 3 | from random import choice, shuffle 4 | import warnings 5 | 6 | from . import intelligence 7 | 8 | 9 | warnings.filterwarnings("ignore") 10 | 11 | 12 | class chso(intelligence.sw): 13 | """Chicken Swarm Optimization""" 14 | 15 | def __init__(self, n, function, lb, ub, dimension, iteration, G=5, FL=0.5): 16 | """ 17 | :param n: number of agents 18 | :param function: test function 19 | :param lb: lower limits for plot axes 20 | :param ub: upper limits for plot axes 21 | :param dimension: space dimension 22 | :param iteration: number of iterations 23 | :param G: after what time relationship will be upgraded (default 24 | value is 5) 25 | :param FL: parameter, which means that the chick would follow its 26 | mother to forage for food (0 < FL < 2. Default value is 0.5) 27 | """ 28 | 29 | super(chso, self).__init__() 30 | 31 | rn = ceil(0.15 * n) 32 | hn = ceil(0.7 * n) 33 | cn = n - rn - hn 34 | mn = ceil(0.2 * n) 35 | 36 | self.__agents = np.random.uniform(lb, ub, (n, dimension)) 37 | pbest = self.__agents 38 | self._points(self.__agents) 39 | 40 | fitness = [function(x) for x in self.__agents] 41 | pfit = fitness 42 | 43 | Pbest = self.__agents[np.array(fitness).argmin()] 44 | Gbest = Pbest 45 | 46 | for t in range(iteration): 47 | 48 | if t % G == 0: 49 | 50 | chickens = self.__update_relationship(n, function, rn, hn, 51 | cn, mn) 52 | roosters, hines, chicks = chickens 53 | 54 | for i in roosters: 55 | 56 | k = choice(roosters) 57 | while k == i: 58 | k = choice(roosters) 59 | 60 | if pfit[i] <= pfit[k]: 61 | sigma = 1 62 | else: 63 | sigma = exp((pfit[k] - pfit[i]) / (abs(pfit[i]) + 0.01)) 64 | 65 | self.__agents[i] = pbest[i] * (1 + np.random.normal(0, sigma, 66 | dimension)) 67 | 68 | for i in hines: 69 | 70 | r1 = i[1] 71 | r2 = choice([choice(roosters), choice(hines)[0]]) 72 | while r2 == r1: 73 | r2 = choice([choice(roosters), choice(hines)[0]]) 74 | 75 | s1 = exp((pfit[i[0]] - pfit[r1]) / (abs(pfit[i[0]]) + 0.01)) 76 | 77 | try: 78 | s2 = exp(pfit[r2] - pfit[i[0]]) 79 | except OverflowError: 80 | s2 = float('inf') 81 | 82 | rand1 = np.random.random((1, dimension))[0] 83 | rand2 = np.random.random((1, dimension))[0] 84 | 85 | self.__agents[i[0]] = pbest[i[0]] + s1 * rand1 * ( 86 | pbest[r1] - pbest[i[0]]) + s2 * rand2 * ( 87 | pbest[r2] - pbest[i[0]]) 88 | 89 | for i in chicks: 90 | self.__agents[i[0]] = pbest[i[0]] * FL * (pbest[i[1]] - 91 | pbest[i[0]]) 92 | 93 | self.__kill(n, function, lb, ub, dimension) 94 | 95 | self.__agents = np.clip(self.__agents, lb, ub) 96 | self._points(self.__agents) 97 | 98 | fitness = [function(x) for x in self.__agents] 99 | 100 | for i in range(n): 101 | if fitness[i] < pfit[i]: 102 | pfit[i] = fitness[i] 103 | pbest[i] = self.__agents[i] 104 | 105 | Pbest = self.__agents[np.array(fitness).argmin()] 106 | if function(Pbest) < function(Gbest): 107 | Gbest = Pbest 108 | 109 | self._set_Gbest(Gbest) 110 | 111 | def __update_relationship(self, n, function, rn, hn, cn, mn): 112 | 113 | fitness = [(function(self.__agents[i]), i) for i in range(n)] 114 | fitness.sort() 115 | 116 | chickens = [i[1] for i in fitness] 117 | roosters = chickens[:rn] 118 | hines = chickens[rn:-cn] 119 | chicks = chickens[-cn:] 120 | 121 | shuffle(hines) 122 | mothers = hines[:mn] 123 | 124 | for i in range(cn): 125 | chicks[i] = chicks[i], choice(mothers) 126 | 127 | for i in range(hn): 128 | hines[i] = hines[i], choice(roosters) 129 | 130 | return roosters, hines, chicks 131 | 132 | def __kill(self, n, function, lb, ub, dimension): 133 | 134 | for i in range(n): 135 | 136 | fit = None 137 | 138 | try: 139 | fit = function(self.__agents[i]) 140 | except OverflowError: 141 | for j in range(dimension): 142 | self.__agents[i][j] = round(self.__agents[i][j]) 143 | 144 | if str(fit) == 'nan': 145 | self.__agents[i] = np.random.uniform(lb, ub, (1, dimension)) 146 | -------------------------------------------------------------------------------- /SwarmPackagePy/cso.py: -------------------------------------------------------------------------------- 1 | from math import gamma, pi, sin 2 | import numpy as np 3 | from random import normalvariate, randint, random 4 | 5 | from . import intelligence 6 | 7 | 8 | class cso(intelligence.sw): 9 | """ 10 | Cuckoo Search Optimization 11 | """ 12 | 13 | def __init__(self, n, function, lb, ub, dimension, iteration, pa=0.25, 14 | nest=100): 15 | """ 16 | :param n: number of agents 17 | :param function: test function 18 | :param lb: lower limits for plot axes 19 | :param ub: upper limits for plot axes 20 | :param dimension: space dimension 21 | :param iteration: number of iterations 22 | :param pa: probability of cuckoo's egg detection (default value is 0.25) 23 | :param nest: number of nests (default value is 100) 24 | """ 25 | 26 | super(cso, self).__init__() 27 | 28 | self.__Nests = [] 29 | 30 | beta = 3 / 2 31 | sigma = (gamma(1 + beta) * sin(pi * beta / 2) / ( 32 | gamma((1 + beta) / 2) * beta * 33 | 2 ** ((beta - 1) / 2))) ** (1 / beta) 34 | u = np.array([normalvariate(0, 1) for k in range(dimension)]) * sigma 35 | v = np.array([normalvariate(0, 1) for k in range(dimension)]) 36 | step = u / abs(v) ** (1 / beta) 37 | 38 | self.__agents = np.random.uniform(lb, ub, (n, dimension)) 39 | self.__nests = np.random.uniform(lb, ub, (nest, dimension)) 40 | Pbest = self.__nests[np.array([function(x) 41 | for x in self.__nests]).argmin()] 42 | Gbest = Pbest 43 | self._points(self.__agents) 44 | 45 | for t in range(iteration): 46 | 47 | for i in self.__agents: 48 | val = randint(0, nest - 1) 49 | if function(i) < function(self.__nests[val]): 50 | self.__nests[val] = i 51 | 52 | fnests = [(function(self.__nests[i]), i) for i in range(nest)] 53 | fnests.sort() 54 | fcuckoos = [(function(self.__agents[i]), i) for i in range(n)] 55 | fcuckoos.sort(reverse=True) 56 | 57 | nworst = nest // 2 58 | worst_nests = [fnests[-i - 1][1] for i in range(nworst)] 59 | 60 | for i in worst_nests: 61 | if random() < pa: 62 | self.__nests[i] = np.random.uniform(lb, ub, (1, dimension)) 63 | 64 | if nest > n: 65 | mworst = n 66 | else: 67 | mworst = nest 68 | 69 | for i in range(mworst): 70 | 71 | if fnests[i][0] < fcuckoos[i][0]: 72 | self.__agents[fcuckoos[i][1]] = self.__nests[fnests[i][1]] 73 | 74 | self.__nests = np.clip(self.__nests, lb, ub) 75 | self.__Levyfly(step, Pbest, n, dimension) 76 | self.__agents = np.clip(self.__agents, lb, ub) 77 | self._points(self.__agents) 78 | self.__nest() 79 | 80 | Pbest = self.__nests[np.array([function(x) 81 | for x in self.__nests]).argmin()] 82 | 83 | if function(Pbest) < function(Gbest): 84 | Gbest = Pbest 85 | 86 | self._set_Gbest(Gbest) 87 | 88 | def __nest(self): 89 | self.__Nests.append([list(i) for i in self.__nests]) 90 | 91 | def __Levyfly(self, step, Pbest, n, dimension): 92 | 93 | for i in range(n): 94 | stepsize = 0.2 * step * (self.__agents[i] - Pbest) 95 | self.__agents[i] += stepsize * np.array([normalvariate(0, 1) 96 | for k in range(dimension)]) 97 | 98 | def get_nests(self): 99 | """Return a history of cuckoos nests (return type: list)""" 100 | 101 | return self.__Nests 102 | -------------------------------------------------------------------------------- /SwarmPackagePy/fa.py: -------------------------------------------------------------------------------- 1 | from math import exp 2 | import numpy as np 3 | 4 | from . import intelligence 5 | 6 | 7 | class fa(intelligence.sw): 8 | """ 9 | Firefly Algorithm 10 | """ 11 | 12 | def __init__(self, n, function, lb, ub, dimension, iteration, csi=1, psi=1, 13 | alpha0=1, alpha1=0.1, norm0=0, norm1=0.1): 14 | """ 15 | :param n: number of agents 16 | :param function: test function 17 | :param lb: lower limits for plot axes 18 | :param ub: upper limits for plot axes 19 | :param dimension: space dimension 20 | :param iteration: number of iterations 21 | :param csi: mutual attraction (default value is 1) 22 | :param psi: light absorption coefficient of the medium 23 | (default value is 1) 24 | :param alpha0: initial value of the free randomization parameter alpha 25 | (default value is 1) 26 | :param alpha1: final value of the free randomization parameter alpha 27 | (default value is 0.1) 28 | :param norm0: first parameter for a normal (Gaussian) distribution 29 | (default value is 0) 30 | :param norm1: second parameter for a normal (Gaussian) distribution 31 | (default value is 0.1) 32 | """ 33 | 34 | super(fa, self).__init__() 35 | 36 | self.__agents = np.random.uniform(lb, ub, (n, dimension)) 37 | self._points(self.__agents) 38 | 39 | Pbest = self.__agents[np.array([function(x) 40 | for x in self.__agents]).argmin()] 41 | Gbest = Pbest 42 | 43 | for t in range(iteration): 44 | 45 | alpha = alpha1 + (alpha0 - alpha1) * exp(-t) 46 | 47 | for i in range(n): 48 | fitness = [function(x) for x in self.__agents] 49 | for j in range(n): 50 | if fitness[i] > fitness[j]: 51 | self.__move(i, j, t, csi, psi, alpha, dimension, 52 | norm0, norm1) 53 | else: 54 | self.__agents[i] += np.random.normal(norm0, norm1, 55 | dimension) 56 | 57 | self.__agents = np.clip(self.__agents, lb, ub) 58 | self._points(self.__agents) 59 | 60 | Pbest = self.__agents[ 61 | np.array([function(x) for x in self.__agents]).argmin()] 62 | if function(Pbest) < function(Gbest): 63 | Gbest = Pbest 64 | 65 | self._set_Gbest(Gbest) 66 | 67 | def __move(self, i, j, t, csi, psi, alpha, dimension, norm0, norm1): 68 | 69 | r = np.linalg.norm(self.__agents[i] - self.__agents[j]) 70 | beta = csi / (1 + psi * r ** 2) 71 | 72 | self.__agents[i] = self.__agents[j] + beta * ( 73 | self.__agents[i] - self.__agents[j]) + alpha * exp(-t) * \ 74 | np.random.normal(norm0, 75 | norm1, 76 | dimension) 77 | -------------------------------------------------------------------------------- /SwarmPackagePy/fwa.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import random 3 | 4 | from . import intelligence 5 | 6 | 7 | class fwa(intelligence.sw): 8 | """ 9 | Firework Algorithm 10 | """ 11 | def __init__(self, n, function, lb, ub, dimension, iteration, m1=7, m2=7, eps=0.001, amp=2, a=0.3, b=3): 12 | 13 | """ 14 | :param n: number of fireworks 15 | :param function: test function 16 | :param lb: lower limits for plot axes 17 | :param ub: upper limits for plot axes 18 | :param dimension: space dimension 19 | :param iteration: the number of iterations 20 | :param m1: parameter controlling the number of normal sparks 21 | (default value is 7) 22 | :param m2: parameter controlling the number of Gaussian sparks 23 | (default value is 7) 24 | :param eps: constant used to avoid division by zero (default value is 0.001) 25 | :param amp: amplitude of normal explosion (default value is 2) 26 | :param a: parameter controlling the lower bound for number of normal sparks 27 | (default value is 0.3) 28 | :param b: parameter controlling the upper bound for number of normal sparks, 29 | b must be greater than a (b is set to 3 by default) 30 | """ 31 | 32 | super(fwa, self).__init__() 33 | 34 | self.__agents = np.random.uniform(lb, ub, (n, dimension)) 35 | self._points(self.__agents) 36 | 37 | Pbest = self.__agents[ 38 | np.array([function(x) for x in self.__agents]).argmin()] 39 | Gbest = Pbest 40 | 41 | 42 | for i in range(iteration): 43 | Ymin = function(Pbest) 44 | Ymax = max([function(x) for x in self.__agents]) 45 | sparks = [] 46 | for fw in self.__agents: 47 | self.__explosion_operator(sparks, fw, function, dimension, m1, eps, amp, Ymin, Ymax, a, b) 48 | self.__gaussian_mutation(sparks, fw, dimension, m2) 49 | 50 | self.__mapping_rule(sparks, lb, ub, dimension) 51 | self.__selection(sparks, n, function) 52 | self._points(self.__agents) 53 | 54 | Pbest = self.__agents[ 55 | np.array([function(x) for x in self.__agents]).argmin()] 56 | if function(Pbest) < function(Gbest): 57 | Gbest = Pbest 58 | 59 | self._set_Gbest(Gbest) 60 | 61 | 62 | def __explosion_operator(self, sparks, fw, function, dimension, m, eps, amp, Ymin, Ymax, a, b): 63 | sparks_num = self.__round(m*(Ymax - function(fw) + eps /\ 64 | (sum([Ymax-function(fwk) for fwk in self.__agents]) + eps)), m, a, b) 65 | 66 | amplitude = amp * (function(fw) - Ymax + eps) /\ 67 | (sum([function(fwk) - Ymax for fwk in self.__agents]) + eps) 68 | 69 | for j in range(int(sparks_num)): 70 | sparks.append(np.array(fw)) 71 | for k in range(dimension): 72 | if (random.choice([True, False])): 73 | sparks[-1][k] += random.uniform(-amplitude, amplitude) 74 | 75 | def __gaussian_mutation(self, sparks, fw, dimension, m): 76 | for j in range(m): 77 | g = np.random.normal(1, 1) 78 | sparks.append(np.array(fw)) 79 | for k in range(dimension): 80 | if(random.choice([True, False])): 81 | sparks[-1][k] *= g 82 | 83 | def __mapping_rule(self, sparks, lb, ub, dimension): 84 | for i in range(len(sparks)): 85 | for j in range(dimension): 86 | if(sparks[i][j] > ub or sparks[i][j] < lb): 87 | sparks[i][j] = lb + (sparks[i][j]-lb) % (ub-lb) 88 | 89 | def __selection(self, sparks, n, function): 90 | self.__agents = sorted(np.concatenate((self.__agents,sparks)), key=function)[:n] 91 | 92 | def __round(self, s, m, a, b): 93 | if (s < a*m): 94 | return round(a*m) 95 | elif (s > b*m): 96 | return round(b*m) 97 | else: 98 | return round(s) 99 | 100 | -------------------------------------------------------------------------------- /SwarmPackagePy/gsa.py: -------------------------------------------------------------------------------- 1 | from math import exp 2 | import numpy as np 3 | 4 | from . import intelligence 5 | 6 | 7 | class gsa(intelligence.sw): 8 | """ 9 | Gravitational Search Algorithm 10 | """ 11 | 12 | def __init__(self, n, function, lb, ub, dimension, iteration, G0=3): 13 | """ 14 | :param n: number of agents 15 | :param function: test function 16 | :param lb: lower limits for plot axes 17 | :param ub: upper limits for plot axes 18 | :param dimension: space dimension 19 | :param iteration: number of iterations 20 | :param G0: gravity parameter (default value is 3) 21 | """ 22 | 23 | super(gsa, self).__init__() 24 | 25 | self.__agents = np.random.uniform(lb, ub, (n, dimension)) 26 | self._points(self.__agents) 27 | 28 | Pbest = self.__agents[np.array([function(x) 29 | for x in self.__agents]).argmin()] 30 | Gbest = Pbest 31 | 32 | velocity = np.array([[0 for k in range(dimension)] for i in range(n)]) 33 | 34 | for t in range(iteration): 35 | 36 | csi = np.random.random((n, dimension)) 37 | eps = np.random.random((1, n))[0] 38 | 39 | fitness = np.array([function(x) for x in self.__agents]) 40 | 41 | m = np.array([(function(x) - max(fitness)) / 42 | (min(fitness) - max(fitness)) for x in self.__agents]) 43 | M = np.array([i / sum(m) for i in m]) 44 | 45 | G = G0 / exp(0.01 * t) 46 | a = np.array([sum([eps[j] * G * M[j] * 47 | (self.__agents[j] - self.__agents[i]) / ( 48 | np.linalg.norm(self.__agents[i] - self.__agents[j]) + 0.001) 49 | for j in range(n)]) for i in range(n)]) 50 | 51 | velocity = csi * velocity + np.array([a[i] for i in range(n)]) 52 | self.__agents += velocity 53 | self.__agents = np.clip(self.__agents, lb, ub) 54 | self._points(self.__agents) 55 | 56 | Pbest = self.__agents[ 57 | np.array([function(x) for x in self.__agents]).argmin()] 58 | if function(Pbest) < function(Gbest): 59 | Gbest = Pbest 60 | 61 | self._set_Gbest(Gbest) 62 | -------------------------------------------------------------------------------- /SwarmPackagePy/gwo.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from . import intelligence 4 | 5 | 6 | class gwo(intelligence.sw): 7 | """ 8 | Grey Wolf Optimizer 9 | """ 10 | 11 | def __init__(self, n, function, lb, ub, dimension, iteration): 12 | """ 13 | :param n: number of agents 14 | :param function: test function 15 | :param lb: lower limits for plot axes 16 | :param ub: upper limits for plot axes 17 | :param dimension: space dimension 18 | :param iteration: number of iterations 19 | """ 20 | 21 | super(gwo, self).__init__() 22 | 23 | self.__agents = np.random.uniform(lb, ub, (n, dimension)) 24 | self._points(self.__agents) 25 | alpha, beta, delta = self.__get_abd(n, function) 26 | 27 | Gbest = alpha 28 | 29 | for t in range(iteration): 30 | 31 | a = 2 - 2 * t / iteration 32 | 33 | r1 = np.random.random((n, dimension)) 34 | r2 = np.random.random((n, dimension)) 35 | A1 = 2 * r1 * a - a 36 | C1 = 2 * r2 37 | 38 | r1 = np.random.random((n, dimension)) 39 | r2 = np.random.random((n, dimension)) 40 | A2 = 2 * r1 * a - a 41 | C2 = 2 * r2 42 | 43 | r1 = np.random.random((n, dimension)) 44 | r2 = np.random.random((n, dimension)) 45 | A3 = 2 * r1 * a - a 46 | C3 = 2 * r2 47 | 48 | Dalpha = abs(C1 * alpha - self.__agents) 49 | Dbeta = abs(C2 * beta - self.__agents) 50 | Ddelta = abs(C3 * delta - self.__agents) 51 | 52 | X1 = alpha - A1 * Dalpha 53 | X2 = beta - A2 * Dbeta 54 | X3 = delta - A3 * Ddelta 55 | 56 | self.__agents = (X1 + X2 + X3) / 3 57 | 58 | self.__agents = np.clip(self.__agents, lb, ub) 59 | self._points(self.__agents) 60 | 61 | alpha, beta, delta = self.__get_abd(n, function) 62 | if function(alpha) < function(Gbest): 63 | Gbest = alpha 64 | 65 | self._set_Gbest(Gbest) 66 | alpha, beta, delta = self.__get_abd(n, function) 67 | self.__leaders = list(alpha), list(beta), list(delta) 68 | 69 | def __get_abd(self, n, function): 70 | 71 | result = [] 72 | fitness = [(function(self.__agents[i]), i) for i in range(n)] 73 | fitness.sort() 74 | 75 | for i in range(3): 76 | result.append(self.__agents[fitness[i][1]]) 77 | 78 | return result 79 | 80 | def get_leaders(self): 81 | """Return alpha, beta, delta leaders of grey wolfs""" 82 | 83 | return list(self.__leaders) 84 | -------------------------------------------------------------------------------- /SwarmPackagePy/hs.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from random import randint, random, uniform 3 | 4 | from . import intelligence 5 | 6 | 7 | class hs(intelligence.sw): 8 | """ 9 | Harmony Search 10 | """ 11 | 12 | def __init__(self, n, function, lb, ub, dimension, iteration, par=0.5, 13 | hmcr=0.5, bw=0.5): 14 | """ 15 | :param n: number of agents 16 | :param function: test function 17 | :param lb: lower limits for plot axes 18 | :param ub: upper limits for plot axes 19 | :param dimension: space dimension 20 | :param iteration: number of iterations 21 | :param par: pitch adjusting rate (default value is 0.5) 22 | :param hmcr: harmony consideration rate (default value is 0.5) 23 | :param bw: bandwidth (default value is 0.5) 24 | """ 25 | 26 | super(hs, self).__init__() 27 | 28 | nn = n 29 | 30 | self.__agents = np.random.uniform(lb, ub, (n, dimension)) 31 | self._points(self.__agents) 32 | 33 | Gbest = self.__agents[np.array([function(x) 34 | for x in self.__agents]).argmin()] 35 | worst = np.array([function(x) for x in self.__agents]).argmax() 36 | 37 | for t in range(iteration): 38 | 39 | hnew = [0 for k in range(dimension)] 40 | 41 | for i in range(len(hnew)): 42 | if random() < hmcr: 43 | hnew[i] = self.__agents[randint(0, nn - 1)][i] 44 | if random() < par: 45 | hnew[i] += uniform(-1, 1) * bw 46 | else: 47 | hnew[i] = uniform(lb, ub) 48 | 49 | if function(hnew) < function(self.__agents[worst]): 50 | self.__agents[worst] = hnew 51 | worst = np.array([function(x) for x in self.__agents]).argmax() 52 | 53 | Pbest = self.__agents[ 54 | np.array([function(x) for x in self.__agents]).argmin()] 55 | if function(Pbest) < function(Gbest): 56 | Gbest = Pbest 57 | 58 | self._points(self.__agents) 59 | 60 | self._set_Gbest(Gbest) 61 | -------------------------------------------------------------------------------- /SwarmPackagePy/intelligence.py: -------------------------------------------------------------------------------- 1 | class sw(object): 2 | 3 | def __init__(self): 4 | 5 | self.__Positions = [] 6 | self.__Gbest = [] 7 | 8 | def _set_Gbest(self, Gbest): 9 | self.__Gbest = Gbest 10 | 11 | def _points(self, agents): 12 | self.__Positions.append([list(i) for i in agents]) 13 | 14 | def get_agents(self): 15 | """Returns a history of all agents of the algorithm (return type: 16 | list)""" 17 | 18 | return self.__Positions 19 | 20 | def get_Gbest(self): 21 | """Return the best position of algorithm (return type: list)""" 22 | 23 | return list(self.__Gbest) 24 | -------------------------------------------------------------------------------- /SwarmPackagePy/pso.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from . import intelligence 4 | 5 | 6 | class pso(intelligence.sw): 7 | """ 8 | Particle Swarm Optimization 9 | """ 10 | 11 | def __init__(self, n, function, lb, ub, dimension, iteration, w=0.5, c1=1, 12 | c2=1): 13 | """ 14 | :param n: number of agents 15 | :param function: test function 16 | :param lb: lower limits for plot axes 17 | :param ub: upper limits for plot azes 18 | :param dimension: space dimension 19 | :param iteration: the number of iterations 20 | :param w: balance between the range of research and consideration for 21 | suboptimal decisions found (default value is 0.5): 22 | w>1 the particle velocity increases, they fly apart and inspect 23 | the space more carefully; 24 | w<1 particle velocity decreases, convergence speed depends 25 | on parameters c1 and c2 ; 26 | :param c1: ratio between "cognitive" and "social" component 27 | (default value is 1) 28 | :param c2: ratio between "cognitive" and "social" component 29 | (default value is 1) 30 | """ 31 | 32 | super(pso, self).__init__() 33 | 34 | self.__agents = np.random.uniform(lb, ub, (n, dimension)) 35 | velocity = np.zeros((n, dimension)) 36 | self._points(self.__agents) 37 | 38 | Pbest = self.__agents[np.array([function(x) 39 | for x in self.__agents]).argmin()] 40 | Gbest = Pbest 41 | 42 | for t in range(iteration): 43 | 44 | r1 = np.random.random((n, dimension)) 45 | r2 = np.random.random((n, dimension)) 46 | velocity = w * velocity + c1 * r1 * ( 47 | Pbest - self.__agents) + c2 * r2 * ( 48 | Gbest - self.__agents) 49 | self.__agents += velocity 50 | self.__agents = np.clip(self.__agents, lb, ub) 51 | self._points(self.__agents) 52 | 53 | Pbest = self.__agents[ 54 | np.array([function(x) for x in self.__agents]).argmin()] 55 | if function(Pbest) < function(Gbest): 56 | Gbest = Pbest 57 | 58 | self._set_Gbest(Gbest) 59 | -------------------------------------------------------------------------------- /SwarmPackagePy/ssa.py: -------------------------------------------------------------------------------- 1 | from math import ceil, exp, floor 2 | import numpy as np 3 | from random import random 4 | 5 | from . import intelligence 6 | 7 | 8 | class ssa(intelligence.sw): 9 | """ 10 | Social Spider Optimization 11 | """ 12 | 13 | def __init__(self, n, function, lb, ub, dimension, iteration, pf=0.4): 14 | """ 15 | :param n: number of agents 16 | :param function: test function 17 | :param lb: lower limits for plot axes 18 | :param ub: upper limits for plot axes 19 | :param dimension: space dimension 20 | :param iteration: the number of iterations 21 | :param pf: random parameter from 0 to 1 (default value is 0.4) 22 | """ 23 | 24 | super(ssa, self).__init__() 25 | 26 | self.__agents = np.random.uniform(lb, ub, (n, dimension)) 27 | 28 | nf = floor((0.9 - random() * 0.25) * n) 29 | nm = n - nf 30 | 31 | Nf = self.__agents[:nf] 32 | Nm = self.__agents[nf:] 33 | 34 | r = (ub - lb) / 2 35 | 36 | pb = np.array([function(x) for x in self.__agents]).argmin() 37 | pw = np.array([function(x) for x in self.__agents]).argmax() 38 | Pbest = self.__agents[pb] 39 | Pworst = self.__agents[pw] 40 | Gbest = Pbest 41 | 42 | for t in range(iteration): 43 | 44 | W = (np.array([function(i) for i in self.__agents]) - 45 | function(Pworst)) / (function(Pbest) - function(Pworst)) 46 | Wf = W[:nf] 47 | Wm = W[nf:] 48 | 49 | Distf = [self.__nearest_spider(i, Nf) for i in Nm] 50 | Vibrf = np.array([W[i[1]] * exp(-i[0]**2) for i in Distf]) 51 | 52 | Distb = [np.linalg.norm(i - Pbest) for i in self.__agents] 53 | Vibrb = np.array([W[pb] * exp(-i**2) for i in Distb]) 54 | 55 | Distc = [[(np.linalg.norm(self.__agents[i] - self.__agents[j]), j) 56 | for j in range(n)] for i in range(n)] 57 | for i in range(len(Distc)): 58 | Distc[i].sort() 59 | Vibrc = [] 60 | for i in range(n): 61 | for j in range(1, n): 62 | dist = Distc[i][j][0] 63 | k = Distc[i][j][1] 64 | if W[k] < W[i]: 65 | Vibrc.append(W[k] * exp(-dist**2)) 66 | break 67 | else: 68 | Vibrc.append(W[i]) 69 | Vibrc = np.array(Vibrc) 70 | 71 | fitness = [(function(Nm[i]), i) for i in range(nm)] 72 | fitness.sort() 73 | cent_male = Nm[fitness[ceil(nm/2)][1]] 74 | a = sum([Nm[j] * Wm[j] for j in range(nm)]) / sum([Wm[j] for j 75 | in range(nm)]) 76 | for i in range(n): 77 | 78 | alpha = np.random.random((1, dimension))[0] 79 | betta = np.random.random((1, dimension))[0] 80 | gamma = np.random.random((1, dimension))[0] 81 | 82 | r1 = np.random.random((1, dimension))[0] 83 | r2 = np.random.random((1, dimension))[0] 84 | r3 = np.random.random((1, dimension))[0] 85 | 86 | if i < nf: 87 | if random() < pf: 88 | k = Distc[i][1][1] 89 | self.__agents[i] += alpha * Vibrc[i] * \ 90 | (self.__agents[k] - self.__agents[i]) + betta * \ 91 | Vibrb[i] * (Pbest - self.__agents[i]) + \ 92 | gamma * (r1 - 0.5) 93 | else: 94 | k = Distc[i][1][1] 95 | self.__agents[i] -= alpha * Vibrc[i] * \ 96 | (self.__agents[k] - self.__agents[i]) - betta * \ 97 | Vibrb[i] * (Pbest - self.__agents[i]) + \ 98 | gamma * (r2 - 0.5) 99 | else: 100 | if function(cent_male) > function(self.__agents[i]): 101 | m = i - nf - 1 102 | k = Distf[m][1] 103 | self.__agents[i] += alpha * Vibrf[m] * \ 104 | (self.__agents[k] - self.__agents[i]) +\ 105 | gamma * (r3 - 0.5) 106 | else: 107 | self.__agents[i] += alpha * (a - self.__agents[i]) 108 | 109 | Nf = self.__agents[:nf] 110 | Nm = self.__agents[nf:] 111 | 112 | best = Nm[np.array([function(x) for x in Nm]).argmin()] 113 | indexes = [i for i in range(nf) 114 | if np.linalg.norm(Nf[i] - best) <= r] 115 | nearest = [Nf[i] for i in indexes] 116 | L = len(nearest) 117 | 118 | if L: 119 | P = [Wf[i] / sum([Wf[i] for i in indexes]) for i in indexes] 120 | new_spiders = best + sum([P[i] * nearest[i] for i in range(L)]) 121 | if function(new_spiders) < function(Pworst): 122 | self.__agents[pw] = new_spiders 123 | 124 | self.__agents = np.clip(self.__agents, lb, ub) 125 | self._points(self.__agents) 126 | 127 | pb = np.array([function(x) for x in self.__agents]).argmin() 128 | pw = np.array([function(x) for x in self.__agents]).argmax() 129 | Pbest = self.__agents[pb] 130 | Pworst = self.__agents[pw] 131 | if function(Pbest) < function(Gbest): 132 | Gbest = Pbest 133 | 134 | self._set_Gbest(Gbest) 135 | 136 | def __nearest_spider(self, spider, spiders): 137 | 138 | spudis = list(spiders) 139 | 140 | try: 141 | pos = spudis.index(spider) 142 | spudis.pop(pos) 143 | except ValueError: 144 | pass 145 | 146 | dists = np.array([np.linalg.norm(spider - s) for s in spudis]) 147 | m = dists.argmin() 148 | d = dists[m] 149 | 150 | return d, m 151 | -------------------------------------------------------------------------------- /SwarmPackagePy/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import SwarmPackagePy 4 | from SwarmPackagePy import testFunctions as tf 5 | import pytest 6 | 7 | 8 | def pytest_generate_tests(metafunc): 9 | fdata = [ 10 | # function min value dim domain 11 | (tf.cross_in_tray_function, -2.06261, 2, [-10, 10]), 12 | (tf.sphere_function, 0, 2, [-5.12, 5.12]), 13 | (tf.bohachevsky_function, 0, 2, [-10, 10]), 14 | (tf.sum_of_different_powers_function, 0, 2, [-1, 1]), 15 | (tf.booth_function, 0, 2, [-10, 10]), 16 | (tf.matyas_function, 0, 2, [-10, 10]), 17 | (tf.six_hump_camel_function, -1.0316, 2, [-3, 3]), 18 | (tf.three_hump_camel_function, 0, 2, [-5, 5]), 19 | (tf.easom_function, -1, 2, [-30, 30]), 20 | ] 21 | algs = [ 22 | # (algorithm, number of iterations, agents, additional parameters) 23 | (SwarmPackagePy.aba, 100, 60, []), 24 | (SwarmPackagePy.ba, 100, 60, []), 25 | (SwarmPackagePy.bfo, 100, 20, []), 26 | (SwarmPackagePy.ca, 500, 60, []), 27 | (SwarmPackagePy.cso, 50, 150, []), 28 | (SwarmPackagePy.chso, 150, 60, []), 29 | (SwarmPackagePy.fa, 50, 60, []), 30 | (SwarmPackagePy.fwa, 20, 3, []), 31 | (SwarmPackagePy.gsa, 100, 60, []), 32 | (SwarmPackagePy.gwo, 100, 60, []), 33 | (SwarmPackagePy.hs, 1500, 60, []), 34 | (SwarmPackagePy.pso, 50, 60, []), 35 | (SwarmPackagePy.ssa, 150, 60, []), 36 | (SwarmPackagePy.wsa, 45, 45, []), 37 | ] 38 | tdata = [] 39 | for alg in algs: 40 | for f in fdata: 41 | tdata.append((*alg, *f)) 42 | 43 | metafunc.parametrize(["alg", "iter", "agents", "params", "f", "val", "dim", 44 | "dom"], tdata) 45 | 46 | 47 | def test_alg(alg, agents, iter, params, f, val, dim, dom): 48 | alh = alg(agents, f, *dom, dim, iter, *params) 49 | # print(f(alh.get_Gbest()), val) 50 | assert abs(f(alh.get_Gbest()) - val) < 0.1 51 | -------------------------------------------------------------------------------- /SwarmPackagePy/testFunctions.py: -------------------------------------------------------------------------------- 1 | from math import * 2 | 3 | 4 | def ackley_function(x): 5 | return -exp(-sqrt(0.5*sum([i**2 for i in x]))) - \ 6 | exp(0.5*sum([cos(i) for i in x])) + 1 + exp(1) 7 | 8 | 9 | def bukin_function(x): 10 | return 100*sqrt(abs(x[1]-0.01*x[0]**2)) + 0.01*abs(x[0] + 10) 11 | 12 | 13 | def cross_in_tray_function(x): 14 | return round(-0.0001*(abs(sin(x[0])*sin(x[1])*exp(abs(100 - 15 | sqrt(sum([i**2 for i in x]))/pi))) + 1)**0.1, 7) 16 | 17 | 18 | def sphere_function(x): 19 | return sum([i**2 for i in x]) 20 | 21 | 22 | def bohachevsky_function(x): 23 | return x[0]**2 + 2*x[1]**2 - 0.3*cos(3*pi*x[0]) - 0.4*cos(4*pi*x[1]) + 0.7 24 | 25 | 26 | def sum_squares_function(x): 27 | return sum([(i+1)*x[i]**2 for i in range(len(x))]) 28 | 29 | 30 | def sum_of_different_powers_function(x): 31 | return sum([abs(x[i])**(i+2) for i in range(len(x))]) 32 | 33 | 34 | def booth_function(x): 35 | return (x[0] + 2*x[1] - 7)**2 + (2*x[0] + x[1] - 5)**2 36 | 37 | 38 | def matyas_function(x): 39 | return 0.26*sphere_function(x) - 0.48*x[0]*x[1] 40 | 41 | 42 | def mccormick_function(x): 43 | return sin(x[0] + x[1]) + (x[0] - x[1])**2 - 1.5*x[0] + 2.5*x[1] + 1 44 | 45 | 46 | def dixon_price_function(x): 47 | return (x[0] - 1)**2 + sum([(i+1)*(2*x[i]**2 - x[i-1])**2 48 | for i in range(1, len(x))]) 49 | 50 | 51 | def six_hump_camel_function(x): 52 | return (4 - 2.1*x[0]**2 + x[0]**4/3)*x[0]**2 + x[0]*x[1]\ 53 | + (-4 + 4*x[1]**2)*x[1]**2 54 | 55 | 56 | def three_hump_camel_function(x): 57 | return 2*x[0]**2 - 1.05*x[0]**4 + x[0]**6/6 + x[0]*x[1] + x[1]**2 58 | 59 | 60 | def easom_function(x): 61 | return -cos(x[0])*cos(x[1])*exp(-(x[0] - pi)**2 - (x[1] - pi)**2) 62 | 63 | 64 | def michalewicz_function(x): 65 | return -sum([sin(x[i])*sin((i+1)*x[i]**2/pi)**20 for i in range(len(x))]) 66 | 67 | 68 | def beale_function(x): 69 | return (1.5 - x[0] + x[0]*x[1])**2 + (2.25 - x[0] + x[0]*x[1]**2)**2 + \ 70 | (2.625 - x[0] + x[0]*x[1]**3)**2 71 | 72 | 73 | def drop_wave_function(x): 74 | return -(1 + cos(12*sqrt(sphere_function(x))))/(0.5*sphere_function(x) + 2) 75 | 76 | -------------------------------------------------------------------------------- /SwarmPackagePy/wsa.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from . import intelligence 4 | 5 | 6 | class wsa(intelligence.sw): 7 | """ 8 | Whale Swarm Algorithm 9 | """ 10 | 11 | def __init__(self, n, function, lb, ub, dimension, iteration, ro0=2, 12 | eta=0.005): 13 | """ 14 | :param n: number of agents 15 | :param function: test function 16 | :param lb: lower limits for plot axes 17 | :param ub: upper limits for plot axes 18 | :param dimension: space dimension 19 | :param iteration: the number of iterations 20 | :param ro0: intensity of ultrasound at the origin of source 21 | (default value is 2) 22 | :param eta: probability of message distortion at large distances 23 | (default value is 0.005) 24 | """ 25 | 26 | super(wsa, self).__init__() 27 | 28 | self.__agents = np.random.uniform(lb, ub, (n, dimension)) 29 | self._points(self.__agents) 30 | 31 | Pbest = self.__agents[np.array([function(x) 32 | for x in self.__agents]).argmin()] 33 | Gbest = Pbest 34 | 35 | for t in range(iteration): 36 | new_agents = self.__agents 37 | for i in range(n): 38 | y = self.__better_and_nearest_whale(i, n, function) 39 | if y: 40 | new_agents[i] += np.dot( 41 | np.random.uniform(0, ro0 * 42 | np.exp(-eta * self.__whale_dist(i, y))), 43 | self.__agents[y] - self.__agents[i]) 44 | self.__agents = new_agents 45 | self.__agents = np.clip(self.__agents, lb, ub) 46 | self._points(self.__agents) 47 | 48 | Pbest = self.__agents[np.array([function(x) 49 | for x in self.__agents]).argmin()] 50 | if function(Pbest) < function(Gbest): 51 | Gbest = Pbest 52 | 53 | self._set_Gbest(Gbest) 54 | 55 | def __whale_dist(self, i, j): 56 | return np.linalg.norm(self.__agents[i] - self.__agents[j]) 57 | 58 | def __better_and_nearest_whale(self, u, n, function): 59 | temp = float("inf") 60 | 61 | v = None 62 | for i in range(n): 63 | if function(self.__agents[i]) < function(self.__agents[u]): 64 | dist_iu = self.__whale_dist(i, u) 65 | if dist_iu < temp: 66 | v = i 67 | temp = dist_iu 68 | return v 69 | -------------------------------------------------------------------------------- /example.py: -------------------------------------------------------------------------------- 1 | import SwarmPackagePy 2 | from SwarmPackagePy import testFunctions as tf 3 | from SwarmPackagePy import animation, animation3D 4 | 5 | 6 | alh = SwarmPackagePy.pso(50, tf.easom_function, -10, 10, 2, 20, 7 | w=0.5, c1=1, c2=1) 8 | animation(alh.get_agents(), tf.easom_function, -10, 10) 9 | animation3D(alh.get_agents(), tf.easom_function, -10, 10) 10 | 11 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import codecs 2 | from setuptools import setup, find_packages 3 | import SwarmPackagePy 4 | 5 | with codecs.open('DESCRIPTION.rst', encoding='utf-8') as f: 6 | long_description = f.read() 7 | 8 | setup( 9 | name='SwarmPackagePy', 10 | version=SwarmPackagePy._version_, 11 | packages=find_packages(), 12 | description='Library of swarm optimization algorithms.', 13 | long_description=long_description, 14 | author='SISDevelop', 15 | author_email='swarm.team.dev@gmail.com', 16 | url='https://github.com/SISDevelop/SwarmPackagePy', 17 | license='none', 18 | 19 | keywords='swarm algorithms, python', 20 | install_requires=['numpy', 'matplotlib>=2.0.0', 'pandas', 'pytest'], 21 | platforms=['Unix', 'Windows'] 22 | 23 | ) 24 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import SwarmPackagePy 4 | from SwarmPackagePy import testFunctions as tf 5 | import pytest 6 | 7 | 8 | def pytest_generate_tests(metafunc): 9 | fdata = [ 10 | # function min value dim domain 11 | (tf.cross_in_tray_function, -2.06261, 2, [-10, 10]), 12 | (tf.sphere_function, 0, 2, [-5.12, 5.12]), 13 | (tf.bohachevsky_function, 0, 2, [-10, 10]), 14 | (tf.sum_of_different_powers_function, 0, 2, [-1, 1]), 15 | (tf.booth_function, 0, 2, [-10, 10]), 16 | (tf.matyas_function, 0, 2, [-10, 10]), 17 | (tf.six_hump_camel_function, -1.0316, 2, [-3, 3]), 18 | (tf.three_hump_camel_function, 0, 2, [-5, 5]), 19 | (tf.easom_function, -1, 2, [-30, 30]), 20 | ] 21 | algs = [ 22 | # (algorithm, number of iterations, agents, additional parameters) 23 | (SwarmPackagePy.aba, 100, 60, []), 24 | (SwarmPackagePy.ba, 100, 60, []), 25 | (SwarmPackagePy.bfo, 50, 40, []), 26 | (SwarmPackagePy.ca, 500, 60, []), 27 | (SwarmPackagePy.cso, 50, 150, []), 28 | (SwarmPackagePy.chso, 150, 60, []), 29 | (SwarmPackagePy.fa, 50, 60, []), 30 | (SwarmPackagePy.fwa, 20, 3, []), 31 | (SwarmPackagePy.gsa, 100, 60, []), 32 | (SwarmPackagePy.gwo, 100, 60, []), 33 | (SwarmPackagePy.hs, 1500, 60, []), 34 | (SwarmPackagePy.pso, 50, 60, []), 35 | (SwarmPackagePy.ssa, 150, 60, []), 36 | (SwarmPackagePy.wsa, 45, 45, []), 37 | ] 38 | tdata = [] 39 | for alg in algs: 40 | for f in fdata: 41 | tdata.append((*alg, *f)) 42 | 43 | metafunc.parametrize(["alg", "iter", "agents", "params", "f", "val", "dim", 44 | "dom"], tdata) 45 | 46 | 47 | def test_alg(alg, agents, iter, params, f, val, dim, dom): 48 | alh = alg(agents, f, *dom, dim, iter, *params) 49 | # print(f(alh.get_Gbest()), val) 50 | assert abs(f(alh.get_Gbest()) - val) < 0.1 51 | --------------------------------------------------------------------------------