|
1
|
|
|
"""Grey wolf optimizer. |
|
2
|
|
|
|
|
3
|
|
|
Date: 11.2.2018 |
|
4
|
|
|
|
|
5
|
|
|
Author : Iztok Fister Jr. |
|
6
|
|
|
|
|
7
|
|
|
License: MIT |
|
8
|
|
|
|
|
9
|
|
|
Reference paper: Mirjalili, Seyedali, Seyed Mohammad Mirjalili, and Andrew Lewis. |
|
10
|
|
|
"Grey wolf optimizer." Advances in engineering software 69 (2014): 46-61. |
|
11
|
|
|
#& Grey Wold Optimizer (GWO) source codes version 1.0 (MATLAB) |
|
12
|
|
|
|
|
13
|
|
|
TODO: Validation must be conducted! More tests are required! |
|
14
|
|
|
""" |
|
15
|
|
|
|
|
16
|
|
|
import random |
|
17
|
|
|
|
|
18
|
|
|
__all__ = ['GreyWolfOptimizer'] |
|
19
|
|
|
|
|
20
|
|
|
|
|
21
|
|
|
class GreyWolfOptimizer(object): |
|
22
|
|
|
|
|
23
|
|
|
# pylint: disable=too-many-instance-attributes |
|
24
|
|
View Code Duplication |
def __init__(self, D, NP, nFES, Lower, Upper, function): |
|
|
|
|
|
|
25
|
|
|
self.D = D # dimension of the problem |
|
26
|
|
|
self.NP = NP # population size; number of search agents |
|
27
|
|
|
self.nFES = nFES # number of function evaluations |
|
28
|
|
|
self.Lower = Lower # lower bound |
|
29
|
|
|
self.Upper = Upper # upper bound |
|
30
|
|
|
self.Fun = function |
|
31
|
|
|
|
|
32
|
|
|
self.Positions = [[0 for _i in range(self.D)] # positions of search agents |
|
33
|
|
|
for _j in range(self.NP)] |
|
34
|
|
|
|
|
35
|
|
|
self.evaluations = 0 # evaluations counter |
|
36
|
|
|
|
|
37
|
|
|
# TODO: "-inf" is in the case of maximization problems |
|
38
|
|
|
self.Alpha_pos = [0] * self.D # init of alpha |
|
39
|
|
|
self.Alpha_score = float("inf") |
|
40
|
|
|
|
|
41
|
|
|
self.Beta_pos = [0] * self.D # init of beta |
|
42
|
|
|
self.Beta_score = float("inf") |
|
43
|
|
|
|
|
44
|
|
|
self.Delta_pos = [0] * self.D # init of delta |
|
45
|
|
|
self.Delta_score = float("inf") |
|
46
|
|
|
|
|
47
|
|
|
def initialization(self): |
|
48
|
|
|
# initialization of positions |
|
49
|
|
|
for i in range(self.NP): |
|
50
|
|
|
for j in range(self.D): |
|
51
|
|
|
self.Positions[i][j] = random.random( |
|
52
|
|
|
) * (self.Upper - self.Lower) + self.Lower |
|
53
|
|
|
|
|
54
|
|
|
def bounds(self, position): |
|
55
|
|
|
for i in range(self.D): |
|
56
|
|
|
if position[i] < self.Lower: |
|
57
|
|
|
position[i] = self.Lower |
|
58
|
|
|
if position[i] > self.Upper: |
|
59
|
|
|
position[i] = self.Upper |
|
60
|
|
|
return position |
|
61
|
|
|
|
|
62
|
|
|
# pylint: disable=too-many-locals |
|
63
|
|
|
def move(self): |
|
64
|
|
|
|
|
65
|
|
|
self.initialization() |
|
66
|
|
|
|
|
67
|
|
|
while True: |
|
68
|
|
|
if self.evaluations == self.nFES: |
|
69
|
|
|
break |
|
70
|
|
|
|
|
71
|
|
|
for i in range(self.NP): |
|
72
|
|
|
self.Positions[i] = self.bounds(self.Positions[i]) |
|
73
|
|
|
|
|
74
|
|
|
Fit = self.Fun(self.D, self.Positions[i]) |
|
75
|
|
|
self.evaluations = self.evaluations + 1 |
|
76
|
|
|
|
|
77
|
|
|
if Fit < self.Alpha_score: |
|
78
|
|
|
self.Alpha_score = Fit |
|
79
|
|
|
self.Alpha_pos = self.Positions[i] |
|
80
|
|
|
|
|
81
|
|
|
if ((Fit > self.Alpha_score) and (Fit < self.Beta_score)): |
|
82
|
|
|
self.Beta_score = Fit |
|
83
|
|
|
self.Beta_pos = self.Positions[i] |
|
84
|
|
|
|
|
85
|
|
|
if ((Fit > self.Alpha_score) and (Fit > self.Beta_score) and |
|
86
|
|
|
(Fit < self.Delta_score)): |
|
87
|
|
|
self.Delta_score = Fit |
|
88
|
|
|
self.Delta_pos = self.Positions[i] |
|
89
|
|
|
|
|
90
|
|
|
a = 2 - self.evaluations * ((2) / self.nFES) |
|
91
|
|
|
|
|
92
|
|
|
for i in range(self.NP): |
|
93
|
|
|
for j in range(self.D): |
|
94
|
|
|
|
|
95
|
|
|
r1 = random.random() |
|
96
|
|
|
r2 = random.random() |
|
97
|
|
|
|
|
98
|
|
|
A1 = 2 * a * r1 - a |
|
99
|
|
|
C1 = 2 * r2 |
|
100
|
|
|
|
|
101
|
|
|
D_alpha = abs( |
|
102
|
|
|
C1 * self.Alpha_pos[j] - self.Positions[i][j]) |
|
103
|
|
|
X1 = self.Alpha_pos[j] - A1 * D_alpha |
|
104
|
|
|
|
|
105
|
|
|
r1 = random.random() |
|
106
|
|
|
r2 = random.random() |
|
107
|
|
|
|
|
108
|
|
|
A2 = 2 * a * r1 - a |
|
109
|
|
|
C2 = 2 * r2 |
|
110
|
|
|
|
|
111
|
|
|
D_beta = abs(C2 * self.Beta_pos[j] - self.Positions[i][j]) |
|
112
|
|
|
X2 = self.Beta_pos[j] - A2 * D_beta |
|
113
|
|
|
|
|
114
|
|
|
r1 = random.random() |
|
115
|
|
|
r2 = random.random() |
|
116
|
|
|
|
|
117
|
|
|
A3 = 2 * a * r1 - a |
|
118
|
|
|
C3 = 2 * r2 |
|
119
|
|
|
|
|
120
|
|
|
D_delta = abs( |
|
121
|
|
|
C3 * self.Delta_pos[j] - self.Positions[i][j]) |
|
122
|
|
|
X3 = self.Delta_pos[j] - A3 * D_delta |
|
123
|
|
|
|
|
124
|
|
|
self.Positions[i][j] = (X1 + X2 + X3) / 3 |
|
125
|
|
|
|
|
126
|
|
|
return self.Alpha_score |
|
127
|
|
|
|