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

NiaPy.algorithms.other.sa   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 132
Duplicated Lines 9.85 %

Importance

Changes 0
Metric Value
eloc 41
dl 13
loc 132
rs 10
c 0
b 0
f 0
wmc 14

5 Methods

Rating   Name   Duplication   Size   Complexity  
A SimulatedAnnealing.typeParameters() 13 13 5
A SimulatedAnnealing.algorithmInfo() 0 11 1
A SimulatedAnnealing.runIteration() 0 7 3
A SimulatedAnnealing.setParameters() 0 17 2
A SimulatedAnnealing.initPopulation() 0 4 1

2 Functions

Rating   Name   Duplication   Size   Complexity  
A coolLinear() 0 14 1
A coolDelta() 0 12 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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