Passed
Pull Request — master (#202)
by Grega
01:02
created

BatAlgorithm.generateBest()   A

Complexity

Conditions 1

Size

Total Lines 12
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 4
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
# encoding=utf8
2
# pylint: disable=mixed-indentation, multiple-statements, attribute-defined-outside-init, logging-not-lazy, no-self-use, line-too-long, singleton-comparison, arguments-differ, bad-continuation
3
import logging
4
from numpy import full
5
from NiaPy.algorithms.algorithm import Algorithm
6
7
logging.basicConfig()
8
logger = logging.getLogger('NiaPy.algorithms.basic')
9
logger.setLevel('INFO')
10
11
__all__ = ['BatAlgorithm']
12
13
class BatAlgorithm(Algorithm):
14
	r"""Implementation of Bat algorithm.
15
16
	Algorithm:
17
		Bat algorithm
18
19
	Date:
20
		2015
21
22
	Authors:
23
		Iztok Fister Jr., Marko Burjek and Klemen Berkovič
24
25
	License:
26
		MIT
27
28
	Reference paper:
29
		Yang, Xin-She. "A new metaheuristic bat-inspired algorithm." Nature inspired cooperative strategies for optimization (NICSO 2010). Springer, Berlin, Heidelberg, 2010. 65-74.
30
31
	Attributes:
32
		Name (List[str]): List of strings representing algorithm name.
33
		A (float): Loudness.
34
		r (float): Pulse rate.
35
		Qmin (float): Minimum frequency.
36
		Qmax (float): Maximum frequency.
37
38
	See Also:
39
		* :class:`NiaPy.algorithms.Algorithm`
40
	"""
41
	Name = ['BatAlgorithm', 'BA']
42
43 View Code Duplication
	@staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
44
	def typeParameters():
45
		r"""Return dict with where key of dict represents parameter name and values represent checking functions for selected parameter.
46
47
		Returns:
48
			Dict[str, Callable]:
49
				* A (Callable[[Union[float, int]], bool]): Loudness.
50
				* r (Callable[[Union[float, int]], bool]): Pulse rate.
51
				* Qmin (Callable[[Union[float, int]], bool]): Minimum frequency.
52
				* Qmax (Callable[[Union[float, int]], bool]): Maximum frequency.
53
54
		See Also:
55
			* :func:`NiaPy.algorithms.Algorithm.typeParameters`
56
		"""
57
		d = Algorithm.typeParameters()
58
		d.update({
59
			'A': lambda x: isinstance(x, (float, int)) and x > 0,
60
			'r': lambda x: isinstance(x, (float, int)) and x > 0,
61
			'Qmin': lambda x: isinstance(x, (float, int)),
62
			'Qmax': lambda x: isinstance(x, (float, int))
63
		})
64
		return d
65
66
	def setParameters(self, NP=40, A=0.5, r=0.5, Qmin=0.0, Qmax=2.0, **ukwargs):
67
		r"""Set the parameters of the algorithm.
68
69
		Args:
70
			A (Optional[float]): Loudness.
71
			r (Optional[float]): Pulse rate.
72
			Qmin (Optional[float]): Minimum frequency.
73
			Qmax (Optional[float]): Maximum frequency.
74
75
		See Also:
76
			* :func:`NiaPy.algorithms.Algorithm.setParameters`
77
		"""
78
		Algorithm.setParameters(self, NP=NP, **ukwargs)
79
		self.A, self.r, self.Qmin, self.Qmax = A, r, Qmin, Qmax
80
		if ukwargs: logger.info('Unused arguments: %s' % (ukwargs))
81
82
	def initPopulation(self, task):
83
		r"""Initialize the starting population.
84
85
		Parameters:
86
			task (Task): Optimization task
87
88
		Returns:
89
			Tuple[numpy.ndarray, numpy.ndarray[float], Dict[str, Any]]:
90
				1. New population.
91
				2. New population fitness/function values.
92
				3. Additional arguments:
93
					* S (numpy.ndarray): TODO
94
					* Q (numpy.ndarray[float]): 	TODO
95
					* v (numpy.ndarray[float]): TODO
96
97
		See Also:
98
			* :func:`NiaPy.algorithms.Algorithm.initPopulation`
99
		"""
100
		Sol, Fitness, d = Algorithm.initPopulation(self, task)
101
		S, Q, v = full([self.NP, task.D], 0.0), full(self.NP, 0.0), full([self.NP, task.D], 0.0)
102
		d.update({'S': S, 'Q': Q, 'v': v})
103
		return Sol, Fitness, d
104
105
	def generateBest(self, best, task, **kwargs):
106
		r"""Generate new solution based on global best known solution.
107
108
		Args:
109
			best (numpy.ndarray): Global best individual.
110
			task (Task): Optimization task.
111
			**kwargs (Dict[str, Any]): Additional arguments.
112
113
		Returns:
114
			numpy.ndarray: New solution based on global best individual.
115
		"""
116
		return task.repair(best + 0.001 * self.normal(0, 1, task.D))
117
118
	def runIteration(self, task, Sol, Fitness, best, f_min, S, Q, v, **dparams):
119
		r"""Core function of Bat Algorithm.
120
121
		Parameters:
122
			task (Task): Optimization task.
123
			Sol (numpy.ndarray): Current population
124
			Fitness (numpy.ndarray[float]): Current population fitness/funciton values
125
			best (numpy.ndarray): Current best individual
126
			f_min (float): Current best individual function/fitness value
127
			S (numpy.ndarray): TODO
128
			Q (numpy.ndarray[float]): TODO
129
			v (numpy.ndarray[float]): TODO
130
			dparams (Dict[str, Any]): Additional algorithm arguments
131
132
		Returns:
133
			Tuple[numpy.ndarray, numpy.ndarray[float], Dict[str, Any]]:
134
				1. New population
135
				2. New population fitness/function vlues
136
				3. Additional arguments:
137
					* S (numpy.ndarray): TODO
138
					* Q (numpy.ndarray[float]): TODO
139
					* v (numpy.ndarray[float]): TODO
140
		"""
141
		for i in range(self.NP):
142
			Q[i] = self.Qmin + (self.Qmax - self.Qmin) * self.uniform(0, 1)
143
			v[i] += (Sol[i] - best) * Q[i]
144
			S[i] = task.repair(Sol[i] + v[i])
145
			if self.rand() > self.r: S[i] = self.generateBest(best=best, task=task, i=i, Sol=Sol)
146
			Fnew = task.eval(S[i])
147
			if (Fnew <= Fitness[i]) and (self.rand() < self.A): Sol[i], Fitness[i] = S[i], Fnew
148
			if Fnew <= f_min: best, f_min = S[i], Fnew
149
		return Sol, Fitness, {'S': S, 'Q': Q, 'v': v}
150
151
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3
152