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

MothFlameOptimizer.runIteration()   A

Complexity

Conditions 5

Size

Total Lines 45
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 18
nop 11
dl 0
loc 45
rs 9.0333
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, no-self-use, line-too-long, arguments-differ, bad-continuation
3
import logging
4
5
from numpy import apply_along_axis, zeros, argsort, concatenate, array, exp, cos, pi
6
7
from NiaPy.algorithms.algorithm import Algorithm
8
9
logging.basicConfig()
10
logger = logging.getLogger('NiaPy.algorithms.basic')
11
logger.setLevel('INFO')
12
13
__all__ = ['MothFlameOptimizer']
14
15
class MothFlameOptimizer(Algorithm):
16
	r"""MothFlameOptimizer of Moth flame optimizer.
17
18
	Algorithm:
19
		Moth flame optimizer
20
21
	Date:
22
		2018
23
24
	Author:
25
		Kivanc Guckiran and Klemen Berkovič
26
27
	License:
28
		MIT
29
30
	Reference paper:
31
		Mirjalili, Seyedali. "Moth-flame optimization algorithm: A novel nature-inspired heuristic paradigm." Knowledge-Based Systems 89 (2015): 228-249.
32
33
	Attributes:
34
		Name (List[str]): List of strings representing algorithm name.
35
36
	See Also:
37
		* :class:`NiaPy.algorithms.algorithm.Algorithm`
38
	"""
39
	Name = ['MothFlameOptimizer', 'MFO']
40
41
	@staticmethod
42
	def algorithmInfo():
43
		r"""Get basic information of algorithm.
44
45
		Returns:
46
			str: Basic information.
47
48
		See Also:
49
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
50
		"""
51
		return r"""Mirjalili, Seyedali. "Moth-flame optimization algorithm: A novel nature-inspired heuristic paradigm." Knowledge-Based Systems 89 (2015): 228-249."""
52
53
	@staticmethod
54
	def typeParameters():
55
		r"""Get dictionary with functions for checking values of parameters.
56
57
		Returns:
58
			Dict[str, Callable]: TODO
59
60
		See Also:
61
			* :func:`NiaPy.algorithms.algorithm.Algorithm.typeParameters`
62
		"""
63
		return Algorithm.typeParameters()
64
65
	def setParameters(self, NP=25, **ukwargs):
66
		r"""Set the algorithm parameters.
67
68
		Arguments:
69
			NP (int): Number of individuals in population
70
71
		See Also:
72
			* :func:`NiaPy.algorithms.algorithm.Algorithm.setParameters`
73
		"""
74
		Algorithm.setParameters(self, NP=NP, **ukwargs)
75
		if ukwargs: logger.info('Unused arguments: %s' % (ukwargs))
76
77
	def initPopulation(self, task):
78
		r"""Initialize starting population.
79
80
		Args:
81
			task (Task): Optimization task
82
83
		Returns:
84
			Tuple[numpy.ndarray, numpy.ndarray[float], Dict[str, Any]]:
85
				1. Initialized population
86
				2. Initialized population function/fitness values
87
				3. Additional arguments:
88
					* best_flames (numpy.ndarray): Best individuals
89
					* best_flame_fitness (numpy.ndarray): Best individuals fitness/function values
90
					* previous_population (numpy.ndarray): Previous population
91
					* previous_fitness (numpy.ndarray[float]): Previous population fitness/function values
92
93
		See Also:
94
			* :func:`NiaPy.algorithms.algorithm.Algorithm.initPopulation`
95
		"""
96
		moth_pos, moth_fitness, d = Algorithm.initPopulation(self, task)
97
		# Create best population
98
		indexes = argsort(moth_fitness)
99
		best_flames, best_flame_fitness = moth_pos[indexes], moth_fitness[indexes]
100
		# Init previous population
101
		previous_population, previous_fitness = zeros((self.NP, task.D)), zeros(self.NP)
102
		d.update({'best_flames': best_flames, 'best_flame_fitness': best_flame_fitness, 'previous_population': previous_population, 'previous_fitness': previous_fitness})
103
		return moth_pos, moth_fitness, d
104
105
	def runIteration(self, task, moth_pos, moth_fitness, xb, fxb, best_flames, best_flame_fitness, previous_population, previous_fitness, **dparams):
106
		r"""Core function of MothFlameOptimizer algorithm.
107
108
		Args:
109
			task (Task): Optimization task.
110
			moth_pos (numpy.ndarray): Current population.
111
			moth_fitness (numpy.ndarray[float]): Current population fitness/function values.
112
			xb (numpy.ndarray): Current population best individual.
113
			fxb (float): Current best individual
114
			best_flames (numpy.ndarray): Best found individuals
115
			best_flame_fitness (numpy.ndarray[float]): Best found individuals fitness/function values
116
			previous_population (numpy.ndarray): Previous population
117
			previous_fitness (numpy.ndarray[float]): Previous population fitness/function values
118
			**dparams (Dict[str, Any]): Additional parameters
119
120
		Returns:
121
			Tuple[numpy.ndarray, numpy.ndarray[float], Dict[str, Any]]:
122
				1. New population.
123
				2. New population fitness/function values.
124
				3. Additional arguments:
125
					* best_flames (numpy.ndarray): Best individuals.
126
					* best_flame_fitness (numpy.ndarray[float]): Best individuals fitness/function values.
127
					* previous_population (numpy.ndarray): Previous population.
128
					* previous_fitness (numpy.ndarray[float]): Previous population fitness/function values.
129
		"""
130
		# Previous positions
131
		previous_population, previous_fitness = moth_pos, moth_fitness
132
		# Create sorted population
133
		indexes = argsort(moth_fitness)
134
		sorted_population = moth_pos[indexes]
135
		# Some parameters
136
		flame_no, a = round(self.NP - task.Iters * ((self.NP - 1) / task.nGEN)), -1 + task.Iters * ((-1) / task.nGEN)
137
		for i in range(self.NP):
138
			for j in range(task.D):
139
				distance_to_flame, b, t = abs(sorted_population[i, j] - moth_pos[i, j]), 1, (a - 1) * self.rand() + 1
140
				if i <= flame_no: moth_pos[i, j] = distance_to_flame * exp(b * t) * cos(2 * pi * t) + sorted_population[i, j]
141
				else: moth_pos[i, j] = distance_to_flame * exp(b * t) * cos(2 * pi * t) + sorted_population[flame_no, j]
142
		moth_pos = apply_along_axis(task.repair, 1, moth_pos, self.Rand)
143
		moth_fitness = apply_along_axis(task.eval, 1, moth_pos)
144
		double_population, double_fitness = concatenate((previous_population, best_flames), axis=0), concatenate((previous_fitness, best_flame_fitness), axis=0)
145
		indexes = argsort(double_fitness)
146
		double_sorted_fitness, double_sorted_population = double_fitness[indexes], double_population[indexes]
147
		for newIdx in range(2 * self.NP): double_sorted_population[newIdx] = array(double_population[indexes[newIdx], :])
148
		best_flame_fitness, best_flames = double_sorted_fitness[:self.NP], double_sorted_population[:self.NP]
149
		return moth_pos, moth_fitness, {'best_flames': best_flames, 'best_flame_fitness': best_flame_fitness, 'previous_population': previous_population, 'previous_fitness': previous_fitness}
150
151
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3
152