Passed
Pull Request — master (#233)
by Grega
01:17
created

MothFlameOptimizer.runIteration()   B

Complexity

Conditions 5

Size

Total Lines 48
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 19
nop 11
dl 0
loc 48
rs 8.9833
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
76
	def initPopulation(self, task):
77
		r"""Initialize starting population.
78
79
		Args:
80
			task (Task): Optimization task
81
82
		Returns:
83
			Tuple[numpy.ndarray, numpy.ndarray[float], Dict[str, Any]]:
84
				1. Initialized population
85
				2. Initialized population function/fitness values
86
				3. Additional arguments:
87
					* best_flames (numpy.ndarray): Best individuals
88
					* best_flame_fitness (numpy.ndarray): Best individuals fitness/function values
89
					* previous_population (numpy.ndarray): Previous population
90
					* previous_fitness (numpy.ndarray[float]): Previous population fitness/function values
91
92
		See Also:
93
			* :func:`NiaPy.algorithms.algorithm.Algorithm.initPopulation`
94
		"""
95
		moth_pos, moth_fitness, d = Algorithm.initPopulation(self, task)
96
		# Create best population
97
		indexes = argsort(moth_fitness)
98
		best_flames, best_flame_fitness = moth_pos[indexes], moth_fitness[indexes]
99
		# Init previous population
100
		previous_population, previous_fitness = zeros((self.NP, task.D)), zeros(self.NP)
101
		d.update({'best_flames': best_flames, 'best_flame_fitness': best_flame_fitness, 'previous_population': previous_population, 'previous_fitness': previous_fitness})
102
		return moth_pos, moth_fitness, d
103
104
	def runIteration(self, task, moth_pos, moth_fitness, xb, fxb, best_flames, best_flame_fitness, previous_population, previous_fitness, **dparams):
105
		r"""Core function of MothFlameOptimizer algorithm.
106
107
		Args:
108
			task (Task): Optimization task.
109
			moth_pos (numpy.ndarray): Current population.
110
			moth_fitness (numpy.ndarray): Current population fitness/function values.
111
			xb (numpy.ndarray): Current population best individual.
112
			fxb (float): Current best individual
113
			best_flames (numpy.ndarray): Best found individuals
114
			best_flame_fitness (numpy.ndarray): Best found individuals fitness/function values
115
			previous_population (numpy.ndarray): Previous population
116
			previous_fitness (numpy.ndarray): Previous population fitness/function values
117
			**dparams (Dict[str, Any]): Additional parameters
118
119
		Returns:
120
			Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, float, Dict[str, Any]]:
121
				1. New population.
122
				2. New population fitness/function values.
123
				3. New global best solution
124
				4. New global best fitness/objective value
125
				5. Additional arguments:
126
					* best_flames (numpy.ndarray): Best individuals.
127
					* best_flame_fitness (numpy.ndarray): Best individuals fitness/function values.
128
					* previous_population (numpy.ndarray): Previous population.
129
					* previous_fitness (numpy.ndarray): Previous population fitness/function values.
130
		"""
131
		# Previous positions
132
		previous_population, previous_fitness = moth_pos, moth_fitness
133
		# Create sorted population
134
		indexes = argsort(moth_fitness)
135
		sorted_population = moth_pos[indexes]
136
		# Some parameters
137
		flame_no, a = round(self.NP - task.Iters * ((self.NP - 1) / task.nGEN)), -1 + task.Iters * ((-1) / task.nGEN)
138
		for i in range(self.NP):
139
			for j in range(task.D):
140
				distance_to_flame, b, t = abs(sorted_population[i, j] - moth_pos[i, j]), 1, (a - 1) * self.rand() + 1
141
				if i <= flame_no: moth_pos[i, j] = distance_to_flame * exp(b * t) * cos(2 * pi * t) + sorted_population[i, j]
142
				else: moth_pos[i, j] = distance_to_flame * exp(b * t) * cos(2 * pi * t) + sorted_population[flame_no, j]
143
		moth_pos = apply_along_axis(task.repair, 1, moth_pos, self.Rand)
144
		moth_fitness = apply_along_axis(task.eval, 1, moth_pos)
145
		xb, fxb = self.getBest(moth_pos, moth_fitness, xb, fxb)
146
		double_population, double_fitness = concatenate((previous_population, best_flames), axis=0), concatenate((previous_fitness, best_flame_fitness), axis=0)
147
		indexes = argsort(double_fitness)
148
		double_sorted_fitness, double_sorted_population = double_fitness[indexes], double_population[indexes]
149
		for newIdx in range(2 * self.NP): double_sorted_population[newIdx] = array(double_population[indexes[newIdx], :])
150
		best_flame_fitness, best_flames = double_sorted_fitness[:self.NP], double_sorted_population[:self.NP]
151
		return moth_pos, moth_fitness, xb, fxb, {'best_flames': best_flames, 'best_flame_fitness': best_flame_fitness, 'previous_population': previous_population, 'previous_fitness': previous_fitness}
152
153
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3
154