Completed
Push — master ( ff5cab...a135cc )
by
unknown
17s queued 13s
created

NiaPy.algorithms.basic.cro.BroodingSimple()   A

Complexity

Conditions 3

Size

Total Lines 17
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 3
nop 5
dl 0
loc 17
rs 10
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 algorithmInfo():
109
		r"""Get algorithms information.
110
111
		Returns:
112
			str: Algorithm information.
113
114
		See Also:
115
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
116
		"""
117
		return r"""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."""
118
119
	@staticmethod
120
	def typeParameters():
121
		r"""Get dictionary with functions for checking values of parameters.
122
123
		Returns:
124
			Dict[str, Callable]:
125
				* N (func): TODO
126
				* phi (func): TODO
127
				* Fa (func): TODO
128
				* Fb (func): TODO
129
				* Fd (func): TODO
130
				* k (func): TODO
131
		"""
132
		return {
133
			# TODO funkcije za testiranje
134
			'N': False,
135
			'phi': False,
136
			'Fa': False,
137
			'Fb': False,
138
			'Fd': False,
139
			'k': False
140
		}
141
142
	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):
143
		r"""Set the parameters of the algorithm.
144
145
		Arguments:
146
			N (int): population size for population initialization.
147
			phi (int): TODO.
148
			Fa (float): Value $\in [0, 1]$ for Asexual reproduction size.
149
			Fb (float): Value $\in [0, 1]$ for Brooding size.
150
			Fd (float): Value $\in [0, 1]$ for Depredation size.
151
			k (int): Trys for larvae setting.
152
			SexualCrossover (Callable[[numpy.ndarray, float, Task, mtrand.RandomState, Dict[str, Any]], Tuple[numpy.ndarray, numpy.ndarray]]): Crossover function.
153
			P_Cr (float): Crossover rate $\in [0, 1]$.
154
			Brooding (Callable[[numpy.ndarray, float, Task, mtrand.RandomState, Dict[str, Any]], Tuple[numpy.ndarray, numpy.ndarray]]): Brooding function.
155
			P_F (float): Crossover rate $\in [0, 1]$.
156
			Distance (Callable[[numpy.ndarray, numpy.ndarray], float]): Funciton for calculating distance between corals.
157
158
		See Also:
159
			* :func:`NiaPy.algorithms.Algorithm.setParameters`
160
		"""
161
		ukwargs.pop('NP', None)
162
		Algorithm.setParameters(self, NP=N, **ukwargs)
163
		self.phi, self.k, self.P_Cr, self.P_F = phi, k, P_Cr, P_F
164
		self.Fa, self.Fb, self.Fd = int(self.NP * Fa), int(self.NP * Fb), int(self.NP * Fd)
165
		self.SexualCrossover, self.Brooding, self.Distance = SexualCrossover, Brooding, Distance
166
167
	def getParameters(self):
168
		r"""Get parameters values of the algorithm.
169
170
		Returns:
171
			Dict[str, Any]: TODO.
172
		"""
173
		d = Algorithm.getParameters(self)
174
		d.update({
175
			'phi': self.phi,
176
			'k': self.k,
177
			'P_Cr': self.P_Cr,
178
			'P_F': self.P_F,
179
			'Fa': self.Fa,
180
			'Fd': self.Fd,
181
			'Fb': self.Fb
182
		})
183
		return d
184
185
	def asexualReprodution(self, Reef, Reef_f, xb, fxb, task):
186
		r"""Asexual reproduction of corals.
187
188
		Args:
189
			Reef (numpy.ndarray): Current population of reefs.
190
			Reef_f (numpy.ndarray): Current populations function/fitness values.
191
			task (Task): Optimization task.
192
193
		Returns:
194
			Tuple[numpy.ndarray, numpy.ndarray]:
195
				1. New population.
196
				2. New population fitness/funciton values.
197
198
		See Also:
199
			* :func:`NiaPy.algorithms.basic.CoralReefsOptimization.setting`
200
			* :func:`NiaPy.algorithms.basic.BroodingSimple`
201
		"""
202
		I = argsort(Reef_f)[:self.Fa]
203
		Reefn, Reefn_f = self.Brooding(Reef[I], self.P_F, task, rnd=self.Rand)
204
		xb, fxb = self.getBest(Reefn, Reefn_f, xb, fxb)
205
		Reef, Reef_f, xb, fxb = self.setting(Reef, Reef_f, Reefn, Reefn_f, xb, fxb, task)
206
		return Reef, Reef_f, xb, fxb
207
208
	def depredation(self, Reef, Reef_f):
209
		r"""Depredation operator for reefs.
210
211
		Args:
212
			Reef (numpy.ndarray): Current reefs.
213
			Reef_f (numpy.ndarray): Current reefs function/fitness values.
214
215
		Returns:
216
			Tuple[numpy.ndarray, numpy.ndarray]:
217
				1. Best individual
218
				2. Best individual fitness/function value
219
		"""
220
		I = argsort(Reef_f)[::-1][:self.Fd]
221
		return delete(Reef, I), delete(Reef_f, I)
222
223
	def setting(self, X, X_f, Xn, Xn_f, xb, fxb, task):
224
		r"""Operator for setting reefs.
225
226
		New reefs try to seatle to selected position in search space.
227
		New reefs are successful if theyr fitness values is better or if they have no reef ocupying same search space.
228
229
		Args:
230
			X (numpy.ndarray): Current population of reefs.
231
			X_f (numpy.ndarray): Current populations function/fitness values.
232
			Xn (numpy.ndarray): New population of reefs.
233
			Xn_f (array of float): New populations function/fitness values.
234
			xb (numpy.ndarray): Global best solution.
235
			fxb (float): Global best solutions fitness/objective value.
236
			task (Task): Optimization task.
237
238
		Returns:
239
			Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, float]:
240
				1. New seatled population.
241
				2. New seatled population fitness/function values.
242
		"""
243
		def update(A, phi, xb, fxb):
244
			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...
245
			I = unique(where(D < phi)[0])
246
			if I.any():
247
				Xn[I], Xn_f[I] = MoveCorals(Xn[I], self.P_F, self.P_F, task, rnd=self.Rand)
248
				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...
249
			return xb, fxb
250
		for i in range(self.k):
251
			xb, fxb = update(X, self.phi, xb, fxb)
252
			xb, fxb = update(Xn, self.phi, xb, fxb)
253
		D = asarray([sqrt(sum((X - e) ** 2, axis=1)) for e in Xn])
254
		I = unique(where(D >= self.phi)[0])
255
		return append(X, Xn[I], 0), append(X_f, Xn_f[I], 0), xb, fxb
256
257
	def runIteration(self, task, Reef, Reef_f, xb, fxb, **dparams):
258
		r"""Core function of Coral Reefs Optimization algorithm.
259
260
		Args:
261
			task (Task): Optimization task.
262
			Reef (numpy.ndarray): Current population.
263
			Reef_f (numpy.ndarray): Current population fitness/function value.
264
			xb (numpy.ndarray): Global best solution.
265
			fxb (float): Global best solution fitness/function value.
266
			**dparams: Additional arguments
267
268
		Returns:
269
			Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, float, Dict[str, Any]]:
270
				1. New population.
271
				2. New population fitness/function values.
272
				3. New global bset solution
273
				4. New global best solutions fitness/objective value
274
				5. Additional arguments:
275
276
		See Also:
277
			* :func:`NiaPy.algorithms.basic.CoralReefsOptimization.SexualCrossover`
278
			* :func:`NiaPy.algorithms.basic.CoralReefsOptimization.Brooding`
279
		"""
280
		I = self.Rand.choice(len(Reef), size=self.Fb, replace=False)
281
		Reefn_s, Reefn_s_f = self.SexualCrossover(Reef[I], self.P_Cr, task, rnd=self.Rand)
282
		xb, fxb = self.getBest(Reefn_s, Reefn_s_f, xb, fxb)
283
		Reefn_b, Reffn_b_f = self.Brooding(delete(Reef, I, 0), self.P_F, task, rnd=self.Rand)
284
		xb, fxb = self.getBest(Reefn_s, Reefn_s_f, xb, fxb)
285
		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)
286
		Reef, Reef_f, xb, fxb = self.asexualReprodution(Reefn, Reefn_f, xb, fxb, task)
287
		if task.Iters % self.k == 0: Reef, Reef_f = self.depredation(Reef, Reef_f)
288
		return Reef, Reef_f, xb, fxb, {}
289
290
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3
291