Passed
Pull Request — master (#202)
by
unknown
02:40 queued 49s
created

SineCosineAlgorithm.nextPos()   A

Complexity

Conditions 2

Size

Total Lines 16
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nop 8
dl 0
loc 16
rs 10
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, trailing-whitespace, line-too-long, multiple-statements, attribute-defined-outside-init, logging-not-lazy, no-self-use, arguments-differ, bad-continuation
3
import logging
4
5
from numpy import apply_along_axis, pi, fabs, sin, cos
6
7
from NiaPy.algorithms.algorithm import Algorithm
8
9
logging.basicConfig()
10
logger = logging.getLogger('NiaPy.algorithms.basic.SineCosineAlgorithm')
11
logger.setLevel('INFO')
12
13
__all__ = ['SineCosineAlgorithm']
14
15
# FIXME test if algorithm realy works OK
16
17
class SineCosineAlgorithm(Algorithm):
18
	r"""Implementation of sine cosine algorithm.
19
20
	Algorithm:
21
		Sine Cosine Algorithm
22
23
	Date:
24
		2018
25
26
	Authors:
27
		Klemen Berkovič
28
29
	License:
30
		MIT
31
32
	Reference URL:
33
		https://www.sciencedirect.com/science/article/pii/S0950705115005043
34
35
	Reference paper:
36
		Seyedali Mirjalili, SCA: A Sine Cosine Algorithm for solving optimization problems, Knowledge-Based Systems, Volume 96, 2016, Pages 120-133, ISSN 0950-7051, https://doi.org/10.1016/j.knosys.2015.12.022.
37
38
	Attributes:
39
		Name (List[str]): List of string representing algorithm names.
40
		a (float): Parameter for control in :math:`r_1` value
41
		Rmin (float): Minimu value for :math:`r_3` value
42
		Rmax (float): Maximum value for :math:`r_3` value
43
44
	See Also:
45
		* :class:`NiaPy.algorithms.Algorithm`
46
	"""
47
	Name = ['SineCosineAlgorithm', 'SCA']
48
49
	@staticmethod
50
	def algorithmInfo():
51
		r"""Get basic information of algorithm.
52
53
		Returns:
54
			str: Basic information of algorithm.
55
56
		See Also:
57
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
58
		"""
59
		return r"""Seyedali Mirjalili, SCA: A Sine Cosine Algorithm for solving optimization problems, Knowledge-Based Systems, Volume 96, 2016, Pages 120-133, ISSN 0950-7051, https://doi.org/10.1016/j.knosys.2015.12.022."""
60
61
	@staticmethod
62
	def typeParameters():
63
		r"""Get dictionary with functions for checking values of parameters.
64
65
		Returns:
66
			Dict[str, Callable]:
67
				* a (Callable[[Union[float, int]], bool]): TODO
68
				* Rmin (Callable[[Union[float, int]], bool]): TODO
69
				* Rmax (Callable[[Union[float, int]], bool]): TODO
70
71
		See Also:
72
			* :func:`NiaPy.algorithms.Algorithm.typeParameters`
73
		"""
74
		d = Algorithm.typeParameters()
75
		d.update({
76
			'a': lambda x: isinstance(x, (float, int)) and x > 0,
77
			'Rmin': lambda x: isinstance(x, (float, int)),
78
			'Rmax': lambda x: isinstance(x, (float, int))
79
		})
80
		return d
81
82
	def setParameters(self, NP=25, a=3, Rmin=0, Rmax=2, **ukwargs):
83
		r"""Set the arguments of an algorithm.
84
85
		Args:
86
			NP (Optional[int]): Number of individual in population
87
			a (Optional[float]): Parameter for control in :math:`r_1` value
88
			Rmin (Optional[float]): Minimu value for :math:`r_3` value
89
			Rmax (Optional[float]): Maximum value for :math:`r_3` value
90
91
		See Also:
92
			* :func:`NiaPy.algorithms.algorithm.Algorithm.setParameters`
93
		"""
94
		Algorithm.setParameters(self, NP=NP, **ukwargs)
95
		self.a, self.Rmin, self.Rmax = a, Rmin, Rmax
96
		if ukwargs: logger.info('Unused arguments: %s' % (ukwargs))
97
98
	def nextPos(self, x, x_b, r1, r2, r3, r4, task):
99
		r"""Move individual to new position in search space.
100
101
		Args:
102
			x (numpy.ndarray): Individual represented with components.
103
			x_b (nmppy.ndarray): Best individual represented with components.
104
			r1 (float): Number dependent on algorithm iteration/generations.
105
			r2 (float): Random number in range of 0 and 2 * PI.
106
			r3 (float): Random number in range [Rmin, Rmax].
107
			r4 (float): Random number in range [0, 1].
108
			task (Task): Optimization task.
109
110
		Returns:
111
			numpy.ndarray: New individual that is moved based on individual ``x``.
112
		"""
113
		return task.repair(x + r1 * (sin(r2) if r4 < 0.5 else cos(r2)) * fabs(r3 * x_b - x), self.Rand)
114
115
	def initPopulation(self, task):
116
		r"""Initialize the individuals.
117
118
		Args:
119
			task (Task): Optimization task
120
121
		Returns:
122
			Tuple[numpy.ndarray, numpy.ndarray[float], Dict[str, Any]]:
123
				1. Initialized population of individuals
124
				2. Function/fitness values for individuals
125
				3. Additional arguments
126
		"""
127
		return Algorithm.initPopulation(self, task)
128
129
	def runIteration(self, task, P, P_f, xb, fxb, **dparams):
130
		r"""Core function of Sine Cosine Algorithm.
131
132
		Args:
133
			task (Task): Optimization task.
134
			P (numpy.ndarray): Current population individuals.
135
			P_f (numpy.ndarray[float]): Current population individulas function/fitness values.
136
			xb (numpy.ndarray): Current best solution to optimization task.
137
			fxb (float): Current best function/fitness value.
138
			dparams (Dict[str, Any]): Additional parameters.
139
140
		Returns:
141
			Tuple[numpy.ndarray, numpy.ndarray[float], Dict[str, Any]]:
142
				1. New population.
143
				2. New populations fitness/function values.
144
				3. Additional arguments.
145
		"""
146
		r1, r2, r3, r4 = self.a - task.Iters * (self.a / task.Iters), self.uniform(0, 2 * pi), self.uniform(self.Rmin, self.Rmax), self.rand()
147
		P = apply_along_axis(self.nextPos, 1, P, xb, r1, r2, r3, r4, task)
148
		P_f = apply_along_axis(task.eval, 1, P)
149
		return P, P_f, {}
150
151
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3
152