Passed
Pull Request — master (#233)
by
unknown
01:26
created

CoralReefsOptimization.getParameters()   A

Complexity

Conditions 1

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nop 1
dl 0
loc 17
rs 9.85
c 0
b 0
f 0
1
# encoding=utf8
2
import logging
3
from scipy.spatial.distance import euclidean
4
from numpy import apply_along_axis, argsort, where, random as rand, asarray, delete, sqrt, sum, unique, append
5
from NiaPy.algorithms.algorithm import Algorithm
6
7
logging.basicConfig()
8
logger = logging.getLogger('NiaPy.algorithms.basic')
9
logger.setLevel('INFO')
10
11
__all__ = ['CoralReefsOptimization']
12
13
def SexualCrossoverSimple(pop, p, task, rnd=rand, **kwargs):
14
	r"""Sexual reproduction of corals.
15
16
	Args:
17
		pop (numpy.ndarray): Current population.
18
		p (float): Probability in range [0, 1].
19
		task (Task): Optimization task.
20
		rnd (mtrand.RandomState): Random generator.
21
		**kwargs (Dict[str, Any]): Additional arguments.
22
23
	Returns:
24
		Tuple[numpy.ndarray, numpy.ndarray]:
25
			1. New population.
26
			2. New population function/fitness values.
27
	"""
28
	for i in range(len(pop) // 2): pop[i] = asarray([pop[i, d] if rnd.rand() < p else pop[i * 2, d] for d in range(task.D)])
29
	return pop, apply_along_axis(task.eval, 1, pop)
30
31
def BroodingSimple(pop, p, task, rnd=rand, **kwargs):
32
	r"""Brooding or internal sexual reproduction of corals.
33
34
	Args:
35
		pop (numpy.ndarray): Current population.
36
		p (float): Probability in range [0, 1].
37
		task (Task): Optimization task.
38
		rnd (mtrand.RandomState): Random generator.
39
		**kwargs (Dict[str, Any]): Additional arguments.
40
41
	Returns:
42
		Tuple[numpy.ndarray, numpy.ndarray]:
43
			1. New population.
44
			2. New population function/fitness values.
45
	"""
46
	for i in range(len(pop)): pop[i] = task.repair(asarray([pop[i, d] if rnd.rand() < p else task.Lower[d] + task.bRange[d] * rnd.rand() for d in range(task.D)]), rnd=rnd)
47
	return pop, apply_along_axis(task.eval, 1, pop)
48
49
def MoveCorals(pop, p, F, task, rnd=rand, **kwargs):
50
	r"""Move corals.
51
52
	Args:
53
		pop (numpy.ndarray): Current population.
54
		p (float): Probability in range [0, 1].
55
		F (float): Factor.
56
		task (Task): Optimization task.
57
		rnd (mtrand.RandomState): Random generator.
58
		**kwargs (Dict[str, Any]): Additional arguments.
59
60
	Returns:
61
		Tuple[numpy.ndarray, numpy.ndarray]:
62
			1. New population.
63
			2. New population function/fitness values.
64
	"""
65
	for i in range(len(pop)): pop[i] = task.repair(asarray([pop[i, d] if rnd.rand() < p else pop[i, d] + F * rnd.rand() for d in range(task.D)]), rnd=rnd)
66
	return pop, apply_along_axis(task.eval, 1, pop)
67
68
class CoralReefsOptimization(Algorithm):
69
	r"""Implementation of Coral Reefs Optimization Algorithm.
70
71
	Algorithm:
72
		Coral Reefs Optimization Algorithm
73
74
	Date:
75
		2018
76
77
	Authors:
78
		Klemen Berkovič
79
80
	License:
81
		MIT
82
83
	Reference Paper:
84
		S. Salcedo-Sanz, J. Del Ser, I. Landa-Torres, S. Gil-López, and J. A. Portilla-Figueras, “The Coral Reefs Optimization Algorithm: A Novel Metaheuristic for Efficiently Solving Optimization Problems,” The Scientific World Journal, vol. 2014, Article ID 739768, 15 pages, 2014.
85
86
	Reference URL:
87
		https://doi.org/10.1155/2014/739768.
88
89
	Attributes:
90
		Name (List[str]): List of strings representing algorithm name.
91
		phi (float): Range of neighborhood.
92
		Fa (int): Number of corals used in asexsual reproduction.
93
		Fb (int): Number of corals used in brooding.
94
		Fd (int): Number of corals used in depredation.
95
		k (int): Nomber of trys for larva setting.
96
		P_F (float): Mutation variable :math:`\in [0, \infty]`.
97
		P_Cr(float): Crossover rate in [0, 1].
98
		Distance (Callable[[numpy.ndarray, numpy.ndarray], float]): Funciton for calculating distance between corals.
99
		SexualCrossover (Callable[[numpy.ndarray, float, Task, mtrand.RandomState, Dict[str, Any]], Tuple[numpy.ndarray, numpy.ndarray[float]]]): Crossover function.
100
		Brooding (Callable[[numpy.ndarray, float, Task, mtrand.RandomState, Dict[str, Any]], Tuple[numpy.ndarray, numpy.ndarray]]): Brooding function.
101
102
	See Also:
103
		* :class:`NiaPy.algorithms.Algorithm`
104
	"""
105
	Name = ['CoralReefsOptimization', 'CRO']
106
107
	@staticmethod
108
	def typeParameters():
109
		r"""Get dictionary with functions for checking values of parameters.
110
111
		Returns:
112
			Dict[str, Callable]:
113
				* N (func): TODO
114
				* phi (func): TODO
115
				* Fa (func): TODO
116
				* Fb (func): TODO
117
				* Fd (func): TODO
118
				* k (func): TODO
119
		"""
120
		return {
121
			# TODO funkcije za testiranje
122
			'N': False,
123
			'phi': False,
124
			'Fa': False,
125
			'Fb': False,
126
			'Fd': False,
127
			'k': False
128
		}
129
130
	def setParameters(self, N=25, phi=0.4, Fa=0.5, Fb=0.5, Fd=0.3, k=25, P_Cr=0.5, P_F=0.36, SexualCrossover=SexualCrossoverSimple, Brooding=BroodingSimple, Distance=euclidean, **ukwargs):
131
		r"""Set the parameters of the algorithm.
132
133
		Arguments:
134
			N (int): population size for population initialization.
135
			phi (int): TODO.
136
			Fa (float): Value $\in [0, 1]$ for Asexual reproduction size.
137
			Fb (float): Value $\in [0, 1]$ for Brooding size.
138
			Fd (float): Value $\in [0, 1]$ for Depredation size.
139
			k (int): Trys for larvae setting.
140
			SexualCrossover (Callable[[numpy.ndarray, float, Task, mtrand.RandomState, Dict[str, Any]], Tuple[numpy.ndarray, numpy.ndarray]]): Crossover function.
141
			P_Cr (float): Crossover rate $\in [0, 1]$.
142
			Brooding (Callable[[numpy.ndarray, float, Task, mtrand.RandomState, Dict[str, Any]], Tuple[numpy.ndarray, numpy.ndarray]]): Brooding function.
143
			P_F (float): Crossover rate $\in [0, 1]$.
144
			Distance (Callable[[numpy.ndarray, numpy.ndarray], float]): Funciton for calculating distance between corals.
145
146
		See Also:
147
			* :func:`NiaPy.algorithms.Algorithm.setParameters`
148
		"""
149
		ukwargs.pop('NP', None)
150
		Algorithm.setParameters(self, NP=N, **ukwargs)
151
		self.phi, self.k, self.P_Cr, self.P_F = phi, k, P_Cr, P_F
152
		self.Fa, self.Fb, self.Fd = int(self.NP * Fa), int(self.NP * Fb), int(self.NP * Fd)
153
		self.SexualCrossover, self.Brooding, self.Distance = SexualCrossover, Brooding, Distance
154
155
	def getParameters(self):
156
		r"""Get parameters values of the algorithm.
157
158
		Returns:
159
			Dict[str, Any]: TODO.
160
		"""
161
		d = Algorithm.getParameters(self)
162
		d.update({
163
			'phi': self.phi,
164
			'k': self.k,
165
			'P_Cr': self.P_Cr,
166
			'P_F': self.P_F,
167
			'Fa': self.Fa,
168
			'Fd': self.Fd,
169
			'Fb': self.Fb
170
		})
171
		return d
172
173
	def asexualReprodution(self, Reef, Reef_f, xb, fxb, task):
174
		r"""Asexual reproduction of corals.
175
176
		Args:
177
			Reef (numpy.ndarray): Current population of reefs.
178
			Reef_f (numpy.ndarray): Current populations function/fitness values.
179
			task (Task): Optimization task.
180
181
		Returns:
182
			Tuple[numpy.ndarray, numpy.ndarray]:
183
				1. New population.
184
				2. New population fitness/funciton values.
185
186
		See Also:
187
			* :func:`NiaPy.algorithms.basic.CoralReefsOptimization.setting`
188
			* :func:`NiaPy.algorithms.basic.BroodingSimple`
189
		"""
190
		I = argsort(Reef_f)[:self.Fa]
191
		Reefn, Reefn_f = self.Brooding(Reef[I], self.P_F, task, rnd=self.Rand)
192
		xb, fxb = self.getBest(Reefn, Reefn_f, xb, fxb)
193
		Reef, Reef_f, xb, fxb = self.setting(Reef, Reef_f, Reefn, Reefn_f, xb, fxb, task)
194
		return Reef, Reef_f, xb, fxb
195
196
	def depredation(self, Reef, Reef_f):
197
		r"""Depredation operator for reefs.
198
199
		Args:
200
			Reef (numpy.ndarray): Current reefs.
201
			Reef_f (numpy.ndarray): Current reefs function/fitness values.
202
203
		Returns:
204
			Tuple[numpy.ndarray, numpy.ndarray]:
205
				1. Best individual
206
				2. Best individual fitness/function value
207
		"""
208
		I = argsort(Reef_f)[::-1][:self.Fd]
209
		return delete(Reef, I), delete(Reef_f, I)
210
211
	def setting(self, X, X_f, Xn, Xn_f, xb, fxb, task):
212
		r"""Operator for setting reefs.
213
214
		New reefs try to seatle to selected position in search space.
215
		New reefs are successful if theyr fitness values is better or if they have no reef ocupying same search space.
216
217
		Args:
218
			X (numpy.ndarray): Current population of reefs.
219
			X_f (numpy.ndarray): Current populations function/fitness values.
220
			Xn (numpy.ndarray): New population of reefs.
221
			Xn_f (array of float): New populations function/fitness values.
222
			xb (numpy.ndarray): Global best solution.
223
			fxb (float): Global best solutions fitness/objective value.
224
			task (Task): Optimization task.
225
226
		Returns:
227
			Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, float]:
228
				1. New seatled population.
229
				2. New seatled population fitness/function values.
230
		"""
231
		def update(A, phi, xb, fxb):
232
			D = asarray([sqrt(sum((A - e) ** 2, axis=1)) for e in Xn])
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable Xn does not seem to be defined.
Loading history...
233
			I = unique(where(D < phi)[0])
234
			if I.any():
235
				Xn[I], Xn_f[I] = MoveCorals(Xn[I], self.P_F, self.P_F, task, rnd=self.Rand)
236
				xb, fxb = self.getBest(Xn[I], Xn_f[I], xb, fxb)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable Xn_f does not seem to be defined.
Loading history...
237
			return xb, fxb
238
		for i in range(self.k):
239
			xb, fxb = update(X, self.phi, xb, fxb)
240
			xb, fxb = update(Xn, self.phi, xb, fxb)
241
		D = asarray([sqrt(sum((X - e) ** 2, axis=1)) for e in Xn])
242
		I = unique(where(D >= self.phi)[0])
243
		return append(X, Xn[I], 0), append(X_f, Xn_f[I], 0), xb, fxb
244
245
	def runIteration(self, task, Reef, Reef_f, xb, fxb, **dparams):
246
		r"""Core function of Coral Reefs Optimization algorithm.
247
248
		Args:
249
			task (Task): Optimization task.
250
			Reef (numpy.ndarray): Current population.
251
			Reef_f (numpy.ndarray): Current population fitness/function value.
252
			xb (numpy.ndarray): Global best solution.
253
			fxb (float): Global best solution fitness/function value.
254
			**dparams: Additional arguments
255
256
		Returns:
257
			Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, float, Dict[str, Any]]:
258
				1. New population.
259
				2. New population fitness/function values.
260
				3. New global bset solution
261
				4. New global best solutions fitness/objective value
262
				5. Additional arguments:
263
264
		See Also:
265
			* :func:`NiaPy.algorithms.basic.CoralReefsOptimization.SexualCrossover`
266
			* :func:`NiaPy.algorithms.basic.CoralReefsOptimization.Brooding`
267
		"""
268
		I = self.Rand.choice(len(Reef), size=self.Fb, replace=False)
269
		Reefn_s, Reefn_s_f = self.SexualCrossover(Reef[I], self.P_Cr, task, rnd=self.Rand)
270
		xb, fxb = self.getBest(Reefn_s, Reefn_s_f, xb, fxb)
271
		Reefn_b, Reffn_b_f = self.Brooding(delete(Reef, I, 0), self.P_F, task, rnd=self.Rand)
272
		xb, fxb = self.getBest(Reefn_s, Reefn_s_f, xb, fxb)
273
		Reefn, Reefn_f, xb, fxb = self.setting(Reef, Reef_f, append(Reefn_s, Reefn_b, 0), append(Reefn_s_f, Reffn_b_f, 0), xb, fxb, task)
274
		Reef, Reef_f, xb, fxb = self.asexualReprodution(Reefn, Reefn_f, xb, fxb, task)
275
		if task.Iters % self.k == 0: Reef, Reef_f = self.depredation(Reef, Reef_f)
276
		return Reef, Reef_f, xb, fxb, {}
277
278
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3
279