Completed
Pull Request — master (#21)
by Grega
01:03
created

GreyWolfOptimizer.run()   A

Complexity

Conditions 1

Size

Total Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
dl 0
loc 2
rs 10
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
from NiaPy.benchmarks.utility import Utility
18
19
__all__ = ['GreyWolfOptimizer']
20
21
22
class GreyWolfOptimizer(object):
23
24
    # pylint: disable=too-many-instance-attributes
25
    def __init__(self, D, NP, nFES, benchmark):
26
        self.benchmark = Utility.get_benchmark(benchmark)
27
        self.D = D  # dimension of the problem
28
        self.NP = NP  # population size; number of search agents
29
        self.nFES = nFES  # number of function evaluations
30
        self.Lower = self.benchmark.Lower  # lower bound
31
        self.Upper = self.benchmark.Upper  # upper bound
32
        self.Fun = self.benchmark.function()
33
34
        self.Positions = [[0 for _i in range(self.D)]  # positions of search agents
35
                          for _j in range(self.NP)]
36
37
        self.evaluations = 0  # evaluations counter
38
39
        # TODO: "-inf" is in the case of maximization problems
40
        self.Alpha_pos = [0] * self.D  # init of alpha
41
        self.Alpha_score = float("inf")
42
43
        self.Beta_pos = [0] * self.D  # init of beta
44
        self.Beta_score = float("inf")
45
46
        self.Delta_pos = [0] * self.D  # init of delta
47
        self.Delta_score = float("inf")
48
49
    def initialization(self):
50
        # initialization of positions
51
        for i in range(self.NP):
52
            for j in range(self.D):
53
                self.Positions[i][j] = random.random(
54
                ) * (self.Upper - self.Lower) + self.Lower
55
56
    def bounds(self, position):
57
        for i in range(self.D):
58
            if position[i] < self.Lower:
59
                position[i] = self.Lower
60
            if position[i] > self.Upper:
61
                position[i] = self.Upper
62
        return position
63
64
    # pylint: disable=too-many-locals
65
    def move(self):
66
67
        self.initialization()
68
69
        while True:
70
            if self.evaluations == self.nFES:
71
                break
72
73
            for i in range(self.NP):
74
                self.Positions[i] = self.bounds(self.Positions[i])
75
76
                Fit = self.Fun(self.D, self.Positions[i])
77
                self.evaluations = self.evaluations + 1
78
79
                if Fit < self.Alpha_score:
80
                    self.Alpha_score = Fit
81
                    self.Alpha_pos = self.Positions[i]
82
83
                if ((Fit > self.Alpha_score) and (Fit < self.Beta_score)):
84
                    self.Beta_score = Fit
85
                    self.Beta_pos = self.Positions[i]
86
87
                if ((Fit > self.Alpha_score) and (Fit > self.Beta_score) and
88
                        (Fit < self.Delta_score)):
89
                    self.Delta_score = Fit
90
                    self.Delta_pos = self.Positions[i]
91
92
            a = 2 - self.evaluations * ((2) / self.nFES)
93
94
            for i in range(self.NP):
95
                for j in range(self.D):
96
97
                    r1 = random.random()
98
                    r2 = random.random()
99
100
                    A1 = 2 * a * r1 - a
101
                    C1 = 2 * r2
102
103
                    D_alpha = abs(
104
                        C1 * self.Alpha_pos[j] - self.Positions[i][j])
105
                    X1 = self.Alpha_pos[j] - A1 * D_alpha
106
107
                    r1 = random.random()
108
                    r2 = random.random()
109
110
                    A2 = 2 * a * r1 - a
111
                    C2 = 2 * r2
112
113
                    D_beta = abs(C2 * self.Beta_pos[j] - self.Positions[i][j])
114
                    X2 = self.Beta_pos[j] - A2 * D_beta
115
116
                    r1 = random.random()
117
                    r2 = random.random()
118
119
                    A3 = 2 * a * r1 - a
120
                    C3 = 2 * r2
121
122
                    D_delta = abs(
123
                        C3 * self.Delta_pos[j] - self.Positions[i][j])
124
                    X3 = self.Delta_pos[j] - A3 * D_delta
125
126
                    self.Positions[i][j] = (X1 + X2 + X3) / 3
127
128
        return self.Alpha_score
129
130
    def run(self):
131
        return self.move()
132