| 
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  | 
0 commit comments