Passed
Pull Request — master (#17)
by Grega
53s
created

BatAlgorithm.init_bat()   A

Complexity

Conditions 4

Size

Total Lines 16

Duplication

Lines 16
Ratio 100 %

Importance

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