Skip to content

Commit 333c405

Browse files
authored
Merge pull request #2 from zStupan/update
Update FA and switch to poetry
2 parents aec16a3 + c7f3d2b commit 333c405

File tree

6 files changed

+104
-158
lines changed

6 files changed

+104
-158
lines changed

FireflyAlgorithm.py

Lines changed: 28 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,28 @@
1-
import random
2-
import math
3-
4-
5-
class FireflyAlgorithm():
6-
7-
def __init__(self, D, NP, nFES, alpha, betamin, gamma, LB, UB, function):
8-
self.D = D # dimension of the problem
9-
self.NP = NP # population size
10-
self.nFES = nFES # number of function evaluations
11-
self.alpha = alpha # alpha parameter
12-
self.betamin = betamin # beta parameter
13-
self.gamma = gamma # gamma parameter
14-
# sort of fireflies according to fitness value
15-
self.Index = [0] * self.NP
16-
self.Fireflies = [[0 for i in range(self.D)]
17-
for j in range(self.NP)] # firefly agents
18-
self.Fireflies_tmp = [[0 for i in range(self.D)] for j in range(
19-
self.NP)] # intermediate pop
20-
self.Fitness = [0.0] * self.NP # fitness values
21-
self.I = [0.0] * self.NP # light intensity
22-
self.nbest = [0.0] * self.D # the best solution found so far
23-
self.LB = LB # lower bound
24-
self.UB = UB # upper bound
25-
self.fbest = None # the best
26-
self.evaluations = 0
27-
self.Fun = function
28-
29-
def init_ffa(self):
30-
for i in range(self.NP):
31-
for j in range(self.D):
32-
self.Fireflies[i][j] = random.uniform(
33-
0, 1) * (self.UB - self.LB) + self.LB
34-
self.Fitness[i] = 1.0 # initialize attractiveness
35-
self.I[i] = self.Fitness[i]
36-
37-
def alpha_new(self, a):
38-
delta = 1.0 - math.pow((math.pow(10.0, -4.0) / 0.9), 1.0 / float(a))
39-
return (1 - delta) * self.alpha
40-
41-
def sort_ffa(self):
42-
self.Index = [i for i in range(self.NP)]
43-
self.I, self.Fitness, self.Index = [list(l) for l in zip(*sorted(zip(self.I, self.Fitness, self.Index)))]
44-
45-
def replace_ffa(self): # replace the old population according to the new Index values
46-
# copy original population to a temporary area
47-
for i in range(self.NP):
48-
for j in range(self.D):
49-
self.Fireflies_tmp[i][j] = self.Fireflies[i][j]
50-
51-
# generational selection in the sense of an EA
52-
for i in range(self.NP):
53-
for j in range(self.D):
54-
self.Fireflies[i][j] = self.Fireflies_tmp[self.Index[i]][j]
55-
56-
def FindLimits(self, k):
57-
for i in range(self.D):
58-
if self.Fireflies[k][i] < self.LB:
59-
self.Fireflies[k][i] = self.LB
60-
if self.Fireflies[k][i] > self.UB:
61-
self.Fireflies[k][i] = self.UB
62-
63-
def move_ffa(self):
64-
for i in range(self.NP):
65-
scale = abs(self.UB - self.LB)
66-
for j in range(self.NP):
67-
r = 0.0
68-
for k in range(self.D):
69-
r += (self.Fireflies[i][k] - self.Fireflies[j][k]) * \
70-
(self.Fireflies[i][k] - self.Fireflies[j][k])
71-
r = math.sqrt(r)
72-
if self.I[i] > self.I[j]: # brighter and more attractive
73-
beta0 = 1.0
74-
beta = (beta0 - self.betamin) * \
75-
math.exp(-self.gamma * math.pow(r, 2.0)) + self.betamin
76-
for k in range(self.D):
77-
r = random.uniform(0, 1)
78-
tmpf = self.alpha * (r - 0.5) * scale
79-
self.Fireflies[i][k] = self.Fireflies[i][
80-
k] * (1.0 - beta) + self.Fireflies_tmp[j][k] * beta + tmpf
81-
self.FindLimits(i)
82-
83-
def Run(self):
84-
self.init_ffa()
85-
86-
while self.evaluations < self.nFES:
87-
88-
# optional reducing of alpha
89-
self.alpha = self.alpha_new(self.nFES/self.NP)
90-
91-
# evaluate new solutions
92-
for i in range(self.NP):
93-
self.Fitness[i] = self.Fun(self.D, self.Fireflies[i])
94-
self.evaluations = self.evaluations + 1
95-
self.I[i] = self.Fitness[i]
96-
97-
# ranking fireflies by their light intensity
98-
self.sort_ffa()
99-
# replace old population
100-
self.replace_ffa()
101-
# find the current best
102-
self.fbest = self.I[0]
103-
# move all fireflies to the better locations
104-
self.move_ffa()
105-
106-
return self.fbest
1+
import numpy as np
2+
from numpy.random import default_rng
3+
4+
5+
def FireflyAlgorithm(function, dim, lb, ub, max_evals, pop_size=20, alpha=1.0, betamin=1.0, gamma=0.01, seed=None):
6+
rng = default_rng(seed)
7+
fireflies = rng.uniform(lb, ub, (pop_size, dim))
8+
intensity = np.apply_along_axis(function, 1, fireflies)
9+
best = np.min(intensity)
10+
11+
evaluations = pop_size
12+
new_alpha = alpha
13+
search_range = ub - lb
14+
15+
while evaluations <= max_evals:
16+
new_alpha *= 0.97
17+
for i in range(pop_size):
18+
for j in range(pop_size):
19+
if intensity[i] >= intensity[j]:
20+
r = np.sum(np.square(fireflies[i] - fireflies[j]), axis=-1)
21+
beta = betamin * np.exp(-gamma * r)
22+
steps = new_alpha * (rng.random(dim) - 0.5) * search_range
23+
fireflies[i] += beta * (fireflies[j] - fireflies[i]) + steps
24+
fireflies[i] = np.clip(fireflies[i], lb, ub)
25+
intensity[i] = function(fireflies[i])
26+
evaluations += 1
27+
best = min(intensity[i], best)
28+
return best

README.md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,12 @@ $ dnf install python-fireflyalgorithm
1616
from FireflyAlgorithm import *
1717

1818

19-
def Fun(D, sol):
20-
val = 0.0
21-
for i in range(D):
22-
val = val + sol[i] * sol[i]
23-
return val
19+
def sphere(x):
20+
return np.sum(x ** 2)
2421

2522

26-
Algorithm = FireflyAlgorithm(10, 20, 10000, 0.5, 0.2, 1.0, -2.0, 2.0, Fun)
27-
Best = Algorithm.Run()
28-
29-
print Best
23+
best = FireflyAlgorithm(function=sphere, dim=10, lb=-5, ub=5, max_evals=10000)
24+
print(best)
3025
```
3126

3227
## Reference Papers:

poetry.lock

Lines changed: 46 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[tool.poetry]
2+
name = "FireflyAlgorithm"
3+
version = "0.0.4"
4+
description = "Firefly algorithm implementation."
5+
authors = ["firefly-cpp"]
6+
license = "MIT"
7+
8+
packages = [
9+
{include = "FireflyAlgorithm.py"},
10+
]
11+
12+
[tool.poetry.dependencies]
13+
python = ">=3.7,<3.11"
14+
numpy = "^1.21.2"
15+
16+
[tool.poetry.dev-dependencies]
17+
18+
[build-system]
19+
requires = ["poetry-core>=1.0.0"]
20+
build-backend = "poetry.core.masonry.api"

run.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
from FireflyAlgorithm import *
1+
import numpy as np
2+
from FireflyAlgorithm import FireflyAlgorithm
23

34

4-
def Fun(D, sol):
5-
val = 0.0
6-
for i in range(D):
7-
val = val + sol[i] * sol[i]
8-
return val
5+
def sphere(x):
6+
return np.sum(x ** 2)
97

108

11-
Algorithm = FireflyAlgorithm(10, 20, 10000, 0.5, 0.2, 1.0, -2.0, 2.0, Fun)
12-
Best = Algorithm.Run()
9+
best = FireflyAlgorithm(function=sphere, dim=10, lb=-5, ub=5, max_evals=10000)
1310

14-
print (Best)
11+
print(best)

setup.py

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)