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 init(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
|
|
|
def move(self): |
|
|
|
|
63
|
|
|
|
64
|
|
|
self.init() |
65
|
|
|
|
66
|
|
|
while True: |
67
|
|
|
if self.evaluations == self.nFES: |
68
|
|
|
break |
69
|
|
|
|
70
|
|
|
for i in range(self.NP): |
71
|
|
|
self.Positions[i] = self.bounds(self.Positions[i]) |
72
|
|
|
|
73
|
|
|
Fit = self.Fun(self.D, self.Positions[i]) |
74
|
|
|
self.evaluations = self.evaluations + 1 |
75
|
|
|
|
76
|
|
|
if Fit < self.Alpha_score: |
77
|
|
|
self.Alpha_score = Fit |
78
|
|
|
self.Alpha_pos = self.Positions[i] |
79
|
|
|
|
80
|
|
|
if ((Fit > self.Alpha_score) and (Fit < self.Beta_score)): |
81
|
|
|
self.Beta_score = Fit |
82
|
|
|
self.Beta_pos = self.Positions[i] |
83
|
|
|
|
84
|
|
|
if ((Fit > self.Alpha_score) and (Fit > self.Beta_score) and |
85
|
|
|
(Fit < self.Delta_score)): |
86
|
|
|
self.Delta_score = Fit |
87
|
|
|
self.Delta_pos = self.Positions[i] |
88
|
|
|
|
89
|
|
|
a = 2 - self.evaluations * ((2) / self.nFES) |
90
|
|
|
|
91
|
|
|
for i in range(self.NP): |
92
|
|
|
for j in range(self.D): |
93
|
|
|
|
94
|
|
|
r1 = random.random() |
95
|
|
|
r2 = random.random() |
96
|
|
|
|
97
|
|
|
A1 = 2 * a * r1 - a |
98
|
|
|
C1 = 2 * r2 |
99
|
|
|
|
100
|
|
|
D_alpha = abs( |
101
|
|
|
C1 * self.Alpha_pos[j] - self.Positions[i][j]) |
102
|
|
|
X1 = self.Alpha_pos[j] - A1 * D_alpha |
103
|
|
|
|
104
|
|
|
r1 = random.random() |
105
|
|
|
r2 = random.random() |
106
|
|
|
|
107
|
|
|
A2 = 2 * a * r1 - a |
108
|
|
|
C2 = 2 * r2 |
109
|
|
|
|
110
|
|
|
D_beta = abs(C2 * self.Beta_pos[j] - self.Positions[i][j]) |
111
|
|
|
X2 = self.Beta_pos[j] - A2 * D_beta |
112
|
|
|
|
113
|
|
|
r1 = random.random() |
114
|
|
|
r2 = random.random() |
115
|
|
|
|
116
|
|
|
A3 = 2 * a * r1 - a |
117
|
|
|
C3 = 2 * r2 |
118
|
|
|
|
119
|
|
|
D_delta = abs( |
120
|
|
|
C3 * self.Delta_pos[j] - self.Positions[i][j]) |
121
|
|
|
X3 = self.Delta_pos[j] - A3 * D_delta |
122
|
|
|
|
123
|
|
|
self.Positions[i][j] = (X1 + X2 + X3) / 3 |
124
|
|
|
|
125
|
|
|
return self.Alpha_score |
126
|
|
|
|