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