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

HybridBatAlgorithm.best_bat()   A

Complexity

Conditions 4

Size

Total Lines 9

Duplication

Lines 8
Ratio 88.89 %

Importance

Changes 0
Metric Value
cc 4
c 0
b 0
f 0
dl 8
loc 9
rs 9.2
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 View Code Duplication
    def __init__(self, D, NP, nFES, A, r, Qmin, Qmax, benchmark):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
23
        self.benchmark = Utility.get_benchmark(benchmark)
24
        self.D = D  # dimension
25
        self.NP = NP  # population size
26
        self.nFES = nFES  # number of function evaluations
27
        self.A = A  # loudness
28
        self.r = r  # pulse rate
29
        self.Qmin = Qmin  # frequency min
30
        self.Qmax = Qmax  # frequency max
31
        self.Lower = self.benchmark.Lower  # lower bound
32
        self.Upper = self.benchmark.Upper  # upper bound
33
        self.Fun = self.benchmark.function()
34
35
        self.f_min = 0.0  # minimum fitness
36
37
        self.Lb = [0] * self.D  # lower bound
38
        self.Ub = [0] * self.D  # upper bound
39
        self.Q = [0] * self.NP  # frequency
40
41
        self.v = [[0 for _i in range(self.D)]
42
                  for _j in range(self.NP)]  # velocity
43
        self.Sol = [[0 for _i in range(self.D)] for _j in range(
44
            self.NP)]  # population of solutions
45
        self.Fitness = [0] * self.NP  # fitness
46
        self.best = [0] * self.D  # best solution
47
        self.evaluations = 0  # evaluations counter
48
49
        self.F = 0.5
50
        self.CR = 0.9
51 View Code Duplication
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
52
    def best_bat(self):
53
        i = 0
54
        j = 0
55
        for i in range(self.NP):
56
            if self.Fitness[i] < self.Fitness[j]:
57
                j = i
58
        for i in range(self.D):
59
            self.best[i] = self.Sol[j][i]
60
        self.f_min = self.Fitness[j]
61 View Code Duplication
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
62
    def init_bat(self):
63
        for i in range(self.D):
64
            self.Lb[i] = self.Lower
65
            self.Ub[i] = self.Upper
66
67
        for i in range(self.NP):
68
            self.Q[i] = 0
69
            for j in range(self.D):
70
                rnd = random.uniform(0, 1)
71
                self.v[i][j] = 0.0
72
                self.Sol[i][j] = self.Lb[j] + (self.Ub[j] - self.Lb[j]) * rnd
73
            self.Fitness[i] = self.Fun(self.D, self.Sol[i])
74
            self.evaluations = self.evaluations + 1
75
        self.best_bat()
76
77
    @classmethod
78
    def simplebounds(cls, val, lower, upper):
79
        if val < lower:
80
            val = lower
81
        if val > upper:
82
            val = upper
83
        return val
84
85
    def move_bat(self):
86
        S = [[0.0 for i in range(self.D)] for j in range(self.NP)]
87
88
        self.init_bat()
89
90
        while True:
91
            if self.evaluations == self.nFES:
92
                break
93
94
            for i in range(self.NP):
95
                rnd = random.uniform(0, 1)
96
                self.Q[i] = self.Qmin + (self.Qmin - self.Qmax) * rnd
97
                j = None
98
                for j in range(self.D):
99
                    self.v[i][j] = self.v[i][j] + (self.Sol[i][j] -
100
                                                   self.best[j]) * self.Q[i]
101
                    S[i][j] = self.Sol[i][j] + self.v[i][j]
102
103
                    S[i][j] = self.simplebounds(S[i][j], self.Lb[j],
104
                                                self.Ub[j])
105
106
                rnd = random.random()
107
108
                if rnd > self.r:
109
                    if random.random() < self.CR:
110
                        naklj = random.sample(range(0, self.NP), 3)
111
                        S[i][j] = S[naklj[0]][j] + self.F * \
112
                            (S[naklj[1]][j] - S[naklj[2]][j])
113
                        S[i][j] = self.simplebounds(S[i][j], self.Lb[j],
114
                                                    self.Ub[j])
115
116
                Fnew = self.Fun(self.D, S[i])
117
                self.evaluations = self.evaluations + 1
118
119
                rnd = random.random()
120
121
                if (Fnew <= self.Fitness[i]) and (rnd < self.A):
122
                    for j in range(self.D):
123
                        self.Sol[i][j] = S[i][j]
124
                    self.Fitness[i] = Fnew
125
126
                if Fnew <= self.f_min:
127
                    for j in range(self.D):
128
                        self.best[j] = S[i][j]
129
                    self.f_min = Fnew
130
131
        return self.f_min
132
133
    def run(self):
134
        return self.move_bat()
135