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

BatAlgorithm.runIteration()   B

Complexity

Conditions 6

Size

Total Lines 32
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 10
nop 10
dl 0
loc 32
rs 8.6666
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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