Passed
Push — master ( caebb1...14dc00 )
by
unknown
01:01
created

HybridBatAlgorithm.eval_true()   A

Complexity

Conditions 2

Size

Total Lines 5

Duplication

Lines 5
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
c 1
b 0
f 0
dl 5
loc 5
rs 9.4285
1
"""Hybrid bat algorithm.
2
3
Date: 2018
4
5
Authors : Grega Vrbancic
6
7
License: MIT
8
9
Reference paper: Fister Jr., Iztok and Fister, Dusan and Yang, Xin-She.
10
"A Hybrid Bat Algorithm". Elektrotehniski vestnik, 2013. 1-7.
11
"""
12
13
14
import random
15
from NiaPy.benchmarks.utility import Utility
16
17
__all__ = ['HybridBatAlgorithm']
18
19
20
class HybridBatAlgorithm(object):
21
    # pylint: disable=too-many-instance-attributes
22
23 View Code Duplication
    def __init__(self, D, NP, nFES, A, r, F, CR, Qmin, Qmax, benchmark):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
24
        self.benchmark = Utility().get_benchmark(benchmark)
25
        self.D = D  # dimension
26
        self.NP = NP  # population size
27
        self.nFES = nFES  # number of function evaluations
28
        self.A = A  # loudness
29
        self.r = r  # pulse rate
30
        self.F = F  # scaling factor
31
        self.CR = CR  # crossover rate
32
        self.Qmin = Qmin  # frequency min
33
        self.Qmax = Qmax  # frequency max
34
        self.Lower = self.benchmark.Lower  # lower bound
35
        self.Upper = self.benchmark.Upper  # upper bound
36
        self.eval_flag = True  # evaluations flag
37
        self.Fun = self.benchmark.function()
38
39
        self.f_min = 0.0  # minimum fitness
40
41
        self.Lb = [0] * self.D  # lower bound
42
        self.Ub = [0] * self.D  # upper bound
43
        self.Q = [0] * self.NP  # frequency
44
45
        self.v = [[0 for _i in range(self.D)]
46
                  for _j in range(self.NP)]  # velocity
47
        self.Sol = [[0 for _i in range(self.D)] for _j in range(
48
            self.NP)]  # population of solutions
49
        self.Fitness = [0] * self.NP  # fitness
50
        self.best = [0] * self.D  # best solution
51
        self.evaluations = 0  # evaluations counter
52
53
    def best_bat(self):
54
        i = 0
55
        j = 0
56
        for i in range(self.NP):
57
            if self.Fitness[i] < self.Fitness[j]:
58
                j = i
59
        for i in range(self.D):
60
            self.best[i] = self.Sol[j][i]
61 View Code Duplication
        self.f_min = self.Fitness[j]
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
62
63
    def eval_true(self):
64
        """Check evauations."""
65
66
        if self.evaluations == self.nFES:
67
            self.eval_flag = False
68
69
    def init_bat(self):
70
        for i in range(self.D):
71
            self.Lb[i] = self.Lower
72
            self.Ub[i] = self.Upper
73
74
        for i in range(self.NP):
75
            self.Q[i] = 0
76
            for j in range(self.D):
77
                rnd = random.uniform(0, 1)
78
                self.v[i][j] = 0.0
79
                self.Sol[i][j] = self.Lb[j] + (self.Ub[j] - self.Lb[j]) * rnd
80
            self.Fitness[i] = self.Fun(self.D, self.Sol[i])
81
            self.evaluations = self.evaluations + 1
82
        self.best_bat()
83
84
    @classmethod
85
    def simplebounds(cls, val, lower, upper):
86
        if val < lower:
87
            val = lower
88
        if val > upper:
89
            val = upper
90
        return val
91
92
    def move_bat(self):
93
        S = [[0.0 for i in range(self.D)] for j in range(self.NP)]
94
95
        self.init_bat()
96
97
        while self.eval_flag is not False:
98
            for i in range(self.NP):
99
                rnd = random.uniform(0, 1)
100
                self.Q[i] = self.Qmin + (self.Qmin - self.Qmax) * rnd
101
                j = None
102
                for j in range(self.D):
103
                    self.v[i][j] = self.v[i][j] + (self.Sol[i][j] -
104
                                                   self.best[j]) * self.Q[i]
105
                    S[i][j] = self.Sol[i][j] + self.v[i][j]
106
107
                    S[i][j] = self.simplebounds(S[i][j], self.Lb[j],
108
                                                self.Ub[j])
109
110
                rnd = random.random()
111
112
                if rnd > self.r:
113
                    if random.random() < self.CR:
114
                        nums = random.sample(range(0, self.NP), 3)
115
                        S[i][j] = S[nums[0]][j] + self.F * \
116
                            (S[nums[1]][j] - S[nums[2]][j])
117
                        S[i][j] = self.simplebounds(S[i][j], self.Lb[j],
118
                                                    self.Ub[j])
119
120
                self.eval_true()
121
122
                if self.eval_flag is not True:
123
                    break
124
125
                Fnew = self.Fun(self.D, S[i])
126
                self.evaluations = self.evaluations + 1
127
128
                rnd = random.random()
129
130
                if (Fnew <= self.Fitness[i]) and (rnd < self.A):
131
                    for j in range(self.D):
132
                        self.Sol[i][j] = S[i][j]
133
                    self.Fitness[i] = Fnew
134
135
                if Fnew <= self.f_min:
136
                    for j in range(self.D):
137
                        self.best[j] = S[i][j]
138
                    self.f_min = Fnew
139
140
        return self.f_min
141
142
    def run(self):
143
        return self.move_bat()
144