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

SimulatedAnnealing.runIteration()   A

Complexity

Conditions 3

Size

Total Lines 7
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nop 8
dl 0
loc 7
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, multiple-statements, attribute-defined-outside-init, logging-not-lazy, unused-argument, arguments-differ, bad-continuation
3
import logging
4
5
from numpy import exp
6
7
from NiaPy.algorithms.algorithm import Algorithm
8
9
logging.basicConfig()
10
logger = logging.getLogger('NiaPy.algorithms.other')
11
logger.setLevel('INFO')
12
13
__all__ = ['SimulatedAnnealing', 'coolDelta', 'coolLinear']
14
15
def coolDelta(currentT, T, deltaT, nFES, **kwargs):
16
	r"""Calculate new temperature by differences.
17
18
	Args:
19
		currentT (float):
20
		T (float):
21
		kwargs (Dict[str, Any]): Additional arguments.
22
23
	Returns:
24
		float: New temperature.
25
	"""
26
	return currentT - deltaT
27
28
def coolLinear(currentT, T, deltaT, nFES, **kwargs):
29
	r"""Calculate temperature with linear function.
30
31
	Args:
32
		currentT (float): Current temperature.
33
		T (float):
34
		deltaT (float):
35
		nFES (int): Number of evaluations done.
36
		kwargs (Dict[str, Any]): Additional arguments.
37
38
	Returns:
39
		float: New temperature.
40
	"""
41
	return currentT - T / nFES
42
43
class SimulatedAnnealing(Algorithm):
44
	r"""Implementation of Simulated Annealing Algorithm.
45
46
	Algorithm:
47
		Simulated Annealing Algorithm
48
49
	Date:
50
		2018
51
52
	Authors:
53
		Jan Popič and Klemen Berkovič
54
55
	License:
56
		MIT
57
58
	Reference URL:
59
60
	Reference paper:
61
62
	Attributes:
63
		Name (List[str]): List of strings representing algorithm name.
64
		delta (float): Movement for neighbour search.
65
		T (float); Starting temperature.
66
		deltaT (float): Change in temperature.
67
		coolingMethod (Callable): Neighbourhood function.
68
		epsilon (float): Error value.
69
70
	See Also:
71
		* :class:`NiaPy.algorithms.Algorithm`
72
	"""
73
	Name = ['SimulatedAnnealing', 'SA']
74
75
	@staticmethod
76
	def algorithmInfo():
77
		r"""Get basic information of algorithm.
78
79
		Returns:
80
			str: Basic information of algorithm.
81
82
		See Also:
83
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
84
		"""
85
		return r"""None"""
86
87 View Code Duplication
	@staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
88
	def typeParameters():
89
		r"""Get dictionary with functions for checking values of parameters.
90
91
		Returns:
92
			Dict[str, Callable]:
93
				* delta (Callable[[Union[float, int], bool]): TODO
94
		"""
95
		return {
96
			'delta': lambda x: isinstance(x, (int, float)) and x > 0,
97
			'T': lambda x: isinstance(x, (int, float)) and x > 0,
98
			'deltaT': lambda x: isinstance(x, (int, float)) and x > 0,
99
			'epsilon': lambda x: isinstance(x, float) and 0 < x < 1
100
		}
101
102
	def setParameters(self, delta=0.5, T=2000, deltaT=0.8, coolingMethod=coolDelta, epsilon=1e-23, **ukwargs):
103
		r"""Set the algorithm parameters/arguments.
104
105
		Arguments:
106
			delta (Optional[float]): Movement for neighbour search.
107
			T (Optional[float]); Starting temperature.
108
			deltaT (Optional[float]): Change in temperature.
109
			coolingMethod (Optional[Callable]): Neighbourhood function.
110
			epsilon (Optional[float]): Error value.
111
112
		See Also
113
			* :func:`NiaPy.algorithms.Algorithm.setParameters`
114
		"""
115
		ukwargs.pop('NP', None)
116
		Algorithm.setParameters(self, NP=1, **ukwargs)
117
		self.delta, self.T, self.deltaT, self.cool, self.epsilon = delta, T, deltaT, coolingMethod, epsilon
118
		if ukwargs: logger.info('Unused arguments: %s' % (ukwargs))
119
120
	def initPopulation(self, task):
121
		x = task.Lower + task.bcRange() * self.rand(task.D)
122
		curT, xfit = self.T, task.eval(x)
123
		return x, xfit, {'curT': curT}
124
125
	def runIteration(self, task, x, xfit, xb, fxb, curT, **dparams):
126
		c = task.repair(x - self.delta / 2 + self.rand(task.D) * self.delta, rnd=self.Rand)
127
		cfit = task.eval(c)
128
		deltaFit, r = cfit - xfit, self.rand()
129
		if deltaFit < 0 or r < exp(deltaFit / curT): x, xfit = c, cfit
130
		curT = self.cool(curT, self.T, deltaT=self.deltaT, nFES=task.nFES)
131
		return x, xfit, {'curT': curT}
132
133
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3
134